If
you read my last two API tips, you noticed that the dialogs which
functions loaded, could be loaded using comctl32.ocx control. However not all
common dialog windows can be loaded this way. "Browse For
Folder" is one of them. In this tip, I'll show how to load this
dialog using two API functions: SHBrowseForFolder and
SHGetPathFromIDList

.

You need two functions because
loading this dialog is a two step process. First, you call
SHBrowseForFolder function to obtain a so called 'pointer to ID List'.
Second, you call SHGetPathFromIDList to extract a folder path from this
'ID List'. First comes the declaration of SHBrowseForFolder (remember,
this function is not present in API Viewer!!!)::

Public Declare Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long

All this code above has to be
declared in one line. As you can see, the function uses BROWSEINFO
structure which looks like this:

Public Type BROWSEINFO
hOwner As Long
'handle to the window calling this
pidlRoot As Long
'ID List point to the top most folder, set this to 0
pszDisplayName As Long 'Buffer used to hold the display
'name of the folder selected by the user
lpszTitle As String
'the caption of the browse dialog
uFlags As Long
'the flags to determine what to browse for
lpfn As Long
'the address of the callback function, set to Null
lParam As Long
'a value passed to the callback function
iImage As Long
'a buffer to hold the index to the image of
'selected folder
End Type

Copy BROWSEINFO to
the module together with the functions. The only members of BROWSEINFO
we are going to use are hOwner, pidlRoot, lpszTitle, and uFlags. Other
stuff is not needed.

Next
function, SHGetPathFromIDList, will extract the folder path together
with the name from the 'ID list' returned by the SHBrowseForFolder
function. The declaration (not present in API Viewer) looks like this
(has to be in one line):