Re: Set Path for Folder Picker

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Whew!! For once I'm innocent! I didn't write that code I got it here:

http://www.xtremevbtalk.com/printthread.php?t=213821

"Karl E. Peterson" wrote:

Charlie wrote:
Thanks. I had to do a little extra searching to complete some of your
references that I didn't already have (e.g. CSIDL_DRIVES and LPTR)

While searching I came upon code similar to yours with an aditional option
that includes the "Make New Folder" button, nice.

Private Const BIF_NEWDIALOGSTYLE = &H40
.ulFlags = BIF_RETURNONLYFSDIRS + BIF_NEWDIALOGSTYLE

This was something I'd thought about adding to my own routine, but never gotten "a
roundtuit". First, though, I need to admonish you for adding those flags, rather
than Or'ing them -- /bad programmer!/ <g>

For sake of the thread, here's what my code ended up doing:

Public Function BrowseForFolderByPath(ByVal SelPath As String, Optional ByVal
hWnd As Long, Optional Title As String, Optional JustDrives As Boolean, Optional
NewFolderButton As Boolean) As String
Dim BI As BROWSEINFO
Dim pRoot As Long
Dim pItem As Long
Dim lpSelPath As Long
Dim Path As String

With BI
' Owner of the dialog. Pass 0 for the desktop.
.hOwner = hWnd

' The desktop folder will be the dialog's root folder.
' SHSimpleIDListFromPath can also be used to set this value.
If JustDrives Then
If SHGetSpecialFolderLocation(hWnd, CSIDL_DRIVES, pRoot) = NOERROR Then
.pidlRoot = pRoot
End If
End If

' Just show folders, no files, using new dialog style.
' New style requires Shell 5.0, but will be ignored?
.ulFlags = BIF_RETURNONLYFSDIRS Or BIF_NEWDIALOGSTYLE

' Optionally, allow user to create new folder.
If NewFolderButton = False Then
.ulFlags = .ulFlags Or BIF_NONEWFOLDERBUTTON
End If

' Set the dialog's prompt string
.lpszTitle = Title

' Obtain and set the address of the callback function
.lpfn = FuncPtr(AddressOf BrowseCallbackProcStr)

' Now the fun part. Allocate some memory for the dialog's
' selected folder path (sSelPath), blast the string into
' the allocated memory, and set the value of the returned
' pointer to lParam (checking LocalAlloc's success is
' omitted for brevity). Note: VB's StrPtr function won't
' work here because a variable's memory address goes out
' of scope when passed to SHBrowseForFolder.
'
' Note: Win2000 requires that the memory block
' include extra space for the string's terminating null.
lpSelPath = LocalAlloc(LPTR, Len(SelPath) + 1)
CopyMemory ByVal lpSelPath, ByVal SelPath, Len(SelPath) + 1
.lParam = lpSelPath
End With

' Shows the browse dialog and doesn't return until the
' dialog is closed. The BrowseCallbackProcStr will
' receive all browse dialog specific messages while
' the dialog is open. pItem will contain the pidl of the
' selected folder if the dialog is not cancelled.
pItem = SHBrowseForFolder(BI)

If pItem Then
' Get the path from the selected folder's pidl returned
' from the SHBrowseForFolder call (rtns True on success,
' sPath must be pre-allocated!)
Path = Space$(MAX_PATH)
If SHGetPathFromIDList(pItem, Path) Then
' Return the path
BrowseForFolderByPath = Left$(Path, InStr(Path, vbNullChar) - 1)
End If

' Free the memory allocated for the Item pidl.
Call CoTaskMemFree(pItem)
End If

' Free the memory allocated for the Root pidl.
If pRoot Then Call CoTaskMemFree(pRoot)

' Free the allocated pointer
Call LocalFree(lpSelPath)
End Function

Note it wasn't quite as simple as you suggested! I was (mistakenly) passing
CSIDL_DRIVES directly, as the pidlRoot, when I should've been obtaining a pidl for
that using SHGetSpecialFolderLocation.

One thing I'm still unsure of is, what happens in pre-Shell 5.0 systems? I'm
assuming the BIF_NEWDIALOGSTYLE flag will just be ignored?

Thanks All for the help!

P.S. Nice comments in your code Karl, (now that I have egg on my face I'm
reading them more closely.)

Thanks! Always nice to hear. :-)
--
..NET: It's About Trust!
http://vfred.mvps.org



.



Relevant Pages

  • Re: Set Path for Folder Picker
    ... that includes the "Make New Folder" button, ... Public Function BrowseForFolderByPath(SelPath As String, ... Dim pidl As Long ... Allocate some memory for the dialog's ...
    (microsoft.public.vb.general.discussion)
  • Re: Set Path for Folder Picker
    ... Public Function BrowseForFolderByPath(ByVal SelPath As String, ... ' The desktop folder will be the dialog's root folder. ... Allocate some memory for the dialog's ... ' Get the path from the selected folder's pidl returned ...
    (microsoft.public.vb.general.discussion)
  • Re: Set Path for Folder Picker
    ... has the sFolder property for setting the default folder to display. ... Public Function BrowseForFolderByPath(ByVal SelPath As String, ... Allocate some memory for the dialog's ... ' Get the path from the selected folder's pidl returned ...
    (microsoft.public.vb.general.discussion)
  • Re: Set Path for Folder Picker
    ... Public Function BrowseForFolderByPath(SelPath As String, ... Dim pidl As Long ... ' The desktop folder will be the dialog's root folder. ... Allocate some memory for the dialog's ...
    (microsoft.public.vb.general.discussion)
  • Re: Which registry key to use?
    ... Public Declare Function SHGetPathFromIDListA Lib "shell32" (ByVal pidl As ... Public Function GetFolPathAs String ... Ditto for accessing the Program Files folder. ...
    (microsoft.public.vb.general.discussion)