📄 faq62.htm
字号:
LPSTR pszDisplayName<b>;</b>
LPCSTR lpszTitle<b>;</b>
UINT ulFlags<b>;</b>
BFFCALLBACK lpfn<b>;</b>
LPARAM lParam<b>;</b>
<b>int</b> iImage<b>;</b>
<b>}</b> BROWSEINFO<b>;</b>
</pre>
<P>
<B><TT>hwndOwner:</TT></B> Specifies the handle of the owner window of the browsing dialog. If you
supply an owner, the browse dialog will behave modally with respect to the owner window.
The user will not be able to interact with your program while the browse dialog is displayed.
This is usually the effect that you want. Also, when you specify an owner, the taskbar will
not display a separate icon for the browsing dialog. If you set <TT>hwndOwner</TT> to
<TT>NULL</TT>, then the browsing dialog behaves like a separate window that is not part
of your program. Users will still be able to interact with your program and the browsing
dialog will have its own taskbar icon.
</P>
<P>
<B><TT>pidlRoot:</TT></B> Specifies the root <TT>PIDL</TT>, or directory, of the browsing dialog. The root
<TT>PIDL</TT> acts like the base folder for the dialog. The user cannot backup past the root folder.
For example, let's say that you want your users to select a folder on the <TT>C:</TT> drive. You
could obtain a <TT>PIDL</TT> for the C:\ drive (how you obtain that is complicated enough to
warrant its own FAQ), and then assign this <TT>PIDL</TT> to the <TT>pidlRoot</TT> member of
<TT>BROWSEINFO</TT>. The browsing dialog would not allow the user to backup past the root
directory of the <TT>C:</TT> drive.
</P>
<P>
<B><TT>pszDisplayName:</TT></B> The browse dialog writes the title of the selected folder into
the <TT>pszDisplayName</TT> member of <TT>BROWSEINFO</TT>. You should point this member to a buffer that can
hold at least <TT>MAX_PATH</TT> characters. Note that the display name is not the same
thing as the directory path to the folder.
</P>
<P>
<B><TT>lpszTitle:</TT></B> This parameter allows you to specify text that the browse info dialog
will display just above the directory treeview (see Figure 1).
</P>
<P>
<B><TT>ulFlags:</TT></B> Controls the type of folders that the user can browse for. The
possible values are:
</P>
<PRE>
BIF_BROWSEFORCOMPUTER Browses only for computers (network neighborhood).
BIF_BROWSEFORPRINTER Browses for network printers (somewhat useless).
BIF_DONTGOBELOWDOMAIN Prevents display of network folders below domain level.
BIF_RETURNFSANCESTORS Returns file system items (drives and directories).
BIF_RETURNONLYFSDIRS Returns file system ancestors (so what are those??).
BIF_STATUSTEXT Displays a label on the browse dialog.
</PRE>
<P>
Be careful when trying to control <TT>SHBrowseFolder</TT> by altering the <TT>ulFlags</TT> structure member.
You might not get the results that you expect. For example, if you specify the <TT>BIF_BROWSEFORPRINTER</TT> flag, you
might expect that the user will be able to select a local printer that is connected directly to their PC. This turns out
to be false. The <TT>BIF_BROWSEFORPRINTER</TT> only allows the user to browse for network printers. Also, it doesn't
seem to prevent them form selecting a file directory (at least, not when I tried it).
</P>
<P>
<B><TT>lpfn:</TT></B> Pointer to a callback routine. An example is shown below.
</P>
<P>
<B><TT>lParam:</TT></B> Value that is used in the callback routine.
</P>
<P>
<B><TT>iImage:</TT></B> The folder that is selected by <TT>SHBrowseForFolder</TT> will have an associated icon of some
kind. When <TT>SHBrowseForFolder</TT> closes, <TT>iImage</TT> contains an integer value. This value is the selected
folder's index into the system imagelist. If you don't know what the system imagelist is, see my FAQ on
<A HREF="faq21.htm">displaying the same icons that Windows displays</A>.
</P>
<H4>Using a <TT>SHBrowseForFolder</TT> callback routine</H4>
<P>
Two of the <TT>BROWSEINFO</TT> members pertain to some mystical callback hocus pocus. So what is this callback jazz
all about? The callback routine exists so you can customize the behavior of the <TT>SHBrowseForFolder</TT> dialog. For
example, if you don't like (or don't understand, like my) why the <TT>ulFlags</TT> parameter doesn't seem to behave correctly,
you can take control of the browse dialog yourself by using a callback. The callback allows you to enable and disable
the browse dialog's OK button. You can also navigate the dialog to a specific folder or set the status text.
</P>
<P>
Here is a code example that demonstrates how to utilize the browse dialog's callback function.
This code sets the status text of the dialog, and it initialize the browse dialog to a specific directory. The code
also tracks the current selection in the browse dialog and displays the folder path in a label.
</P>
<pre>
<b>int</b> <b>__stdcall</b> BrowseProc<b>(</b>HWND hwnd<b>,</b>UINT uMsg<b>,</b> LPARAM lParam<b>,</b> LPARAM lpData <b>)</b>
<b>{</b>
<b>char</b> szDir<b>[</b>MAX_PATH<b>]</b><b>;</b>
<b>switch</b><b>(</b>uMsg<b>)</b>
<b>{</b>
<b>case</b> BFFM_INITIALIZED<b>:</b>
SendMessage<b>(</b>hwnd<b>,</b> BFFM_SETSTATUSTEXT<b>,</b><font color="blue">0</font><b>,</b> <b>(</b>LPARAM<b>)</b><font color="blue">"Greetings"</font><b>)</b><b>;</b>
<font color="navy">// Set the initial directory. If WPARAM is TRUE, then LPARAM is a</font>
<font color="navy">// string that contains the path. If WPARAM is FALSE, then LPARAM</font>
<font color="navy">// should be a lovely PIDL</font>
SendMessage<b>(</b>hwnd<b>,</b> BFFM_SETSELECTION<b>,</b> TRUE<b>,</b> <b>(</b>LPARAM<b>)</b><font color="blue">"C:\\Delphi4"</font><b>)</b><b>;</b>
<b>break</b><b>;</b>
<b>case</b> BFFM_SELCHANGED<b>:</b>
<b>if</b><b>(</b>SHGetPathFromIDList<b>(</b><b>(</b>LPITEMIDLIST<b>)</b>lParam<b>,</b> szDir<b>)</b><b>)</b>
Form1<b>-></b>Label3<b>-></b>Caption <b>=</b> szDir<b>;</b>
<b>break</b><b>;</b>
<b>}</b>
<b>return</b> <font color="blue">0</font><b>;</b>
<b>}</b>
<b>void</b> <b>__fastcall</b> TForm1<b>:</b><b>:</b>Button1Click<b>(</b>TObject <b>*</b>Sender<b>)</b>
<b>{</b>
BROWSEINFO info<b>;</b>
<b>char</b> szDir<b>[</b>MAX_PATH<b>]</b><b>;</b>
<b>char</b> szDisplayName<b>[</b>MAX_PATH<b>]</b><b>;</b>
LPITEMIDLIST pidl<b>;</b>
LPMALLOC pShellMalloc<b>;</b>
<b>if</b><b>(</b>SHGetMalloc<b>(</b><b>&</b>pShellMalloc<b>)</b> <b>==</b> NO_ERROR<b>)</b>
<b>{</b>
memset<b>(</b><b>&</b>info<b>,</b> <font color="blue">0x00</font><b>,</b> <b>sizeof</b><b>(</b>info<b>)</b><b>)</b><b>;</b>
info<b>.</b>hwndOwner <b>=</b> <font color="blue">0</font><b>;</b>
info<b>.</b>pidlRoot <b>=</b> NULL<b>;</b>
info<b>.</b>pszDisplayName <b>=</b> szDisplayName<b>;</b>
info<b>.</b>lpszTitle <b>=</b> <font color="blue">"Browse Title"</font><b>;</b>
info<b>.</b>ulFlags <b>=</b> BIF_RETURNONLYFSDIRS<b>|</b>BIF_STATUSTEXT<b>;</b>
info<b>.</b>lpfn <b>=</b> BrowseProc<b>;</b> <font color="navy">// callback function</font>
pidl <b>=</b> SHBrowseForFolder<b>(</b><b>&</b>info<b>)</b><b>;</b>
<b>if</b><b>(</b>pidl<b>)</b>
<b>{</b>
<b>if</b><b>(</b>SHGetPathFromIDList<b>(</b>pidl<b>,</b> szDir<b>)</b><b>)</b>
<b>{</b>
Label1<b>-></b>Caption <b>=</b> szDir<b>;</b>
<b>}</b>
Label2<b>-></b>Caption <b>=</b> info<b>.</b>pszDisplayName<b>;</b>
pShellMalloc<b>-></b>Free<b>(</b>pidl<b>)</b><b>;</b>
pShellMalloc<b>-></b>Release<b>(</b><b>)</b><b>;</b>
<b>}</b>
<b>}</b>
<b>}</b>
</pre>
</TD> </TR>
</TABLE>
</CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -