Specify a Path with Standard Folder Browsing

This article first appeared in Visual Developer Magazine
(Note: This is my unedited original and may differ slightly from the published version.)
By Matt Hart

Visual Basic does not directly support the Windows standard folder browsing dialog, but it’s easy to add by using the SHBrowseForFolder API function. The API declarations file included with VB doesn’t have the shell operations APIs listed, but they can be easily translated from the C versions. The Platform SDK contains all the C versions of every constant and structure. You can download it a few clicks from this page: msdn.microsoft.com/developer/sdk.

When you use the SendMessage API call in the BrowseCallbackProc procedure, make sure aStr has something in it. VB will crash without a startup path, so don’t make the call if there’s nothing to do.

Note that I use the lParam element of the BROWSEINFO structure to hold the object pointer of the TextBox containing the default path. That makes it easy to retrieve the default path from any number of source text boxes.

The GetAddress function is necessary because B.lpCallBack = AddressOf BrowseCallbackProc isn’t a valid statement.

‘ Form code

Private Sub cmdBrowse_Click() Dim B As BROWSEINFO, lItems As Long, aStr As String B.hWndOwner = hwnd B.pszTitle = "Browse sample" B.lpCallback = GetAddress(AddressOf BrowseCallbackProc) B.lParam = ObjPtr(Text1) lItems = SHBrowseForFolder(B) If lItems Then aStr = Space$(MAX_PATH) SHGetPathFromIDList lItems, aStr Text1.Text = Left$(aStr, InStr(aStr, Chr$(0))) LocalFree lItems End If End Sub ‘ Module code Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long) Declare Function LocalFree Lib "kernel32" (ByVal hMem As Long) _ As Long Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _ lParam As Any) As Long Declare Function SHBrowseForFolder Lib "shell32.dll" Alias _ "SHBrowseForFolderA" (lpBrowseInfo As Any) As Long Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias _ "SHGetPathFromIDListA" (ByVal pidl As Long, _ ByVal pszPath As String) As Long Type BROWSEINFO hWndOwner As Long pdilRoot As Long pszDisplayName As String pszTitle As String ulFlags As Long lpCallback As Long lParam As Long iImage As Long End Type Public Const WM_USER = &H400 Public Const BFFM_INITIALIZED = 1 Public Const BFFM_SETSELECTIONA = (WM_USER + 102) Public Const MAX_PATH = 260 Public Function BrowseCallbackProc(ByVal hwnd As Long, ByVal Msg _ As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Select Case Msg Case BFFM_INITIALIZED Dim aStr As String, oText As Object CopyMemory oText, lParam, 4 aStr = oText.Text If Len(aStr) Then If Len(aStr) > 3 Then If Right$(aStr, 1) = "\" Then aStr = _ Left$(aStr, Len(aStr) - 1) End If SendMessage hwnd, BFFM_SETSELECTIONA, True, _ ByVal aStr End If End Select End Function Public Function GetAddress(ByVal lParam As Long) As Long GetAddress = lParam End Function

Back to Articles
Copyright © 2000 by Matt E. Hart, All Rights Reserved Worldwide.
Nothing on this web site may be reproduced, in any form, without express written consent.