The following works
'************** *************** *********
' Code Start
Option Explicit
'************** *************** *
'Code Start
'************** *************** *
Private Type BROWSEINFO
hOwner As Long
pidlRoot As Long
pszDisplayName As Long
lpszTitle As Long
' lpszTitle As Byte
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type
'************** *************** *
'Functions in BrowseFolder
'************** *************** *
Private Declare Function SHGetPathFromID List _
Lib "shell32.dl l" Alias "SHGetPathFromI DListA" _
(ByVal pidl As Long, ByVal pszPath As String) _
As Long
Private Declare Function SHBrowseForFold er _
Lib "shell32.dl l" Alias "SHBrowseForFol derA" _
(lpBrowseInfo As BROWSEINFO) _
As Long
Private Declare Sub ZeroMemory _
Lib "kernel32" Alias "RtlZeroMem ory" _
(dest As Long, ByVal numBytes As Long)
Private Declare Function lstrcat _
Lib "kernel32" Alias "lstrcatA" _
(ByVal lpString1 As String, _
ByVal lpString2 As String) _
As Long
'************** *************** *
'/Functions in BrowseFolder
'************** *************** *
Private Declare Function GetFileVersionI nfoSize Lib "version.dl l" _
Alias "GetFileVersion InfoSizeA" _
(ByVal lptstrFilename As String, _
lpdwHandle As Long) As Long
Private Declare Function GetFileVersionI nfo Lib "version.dl l" _
Alias "GetFileVersion InfoA" _
(ByVal lptstrFilename As String, _
ByVal dwHandle As Long, _
ByVal dwLen As Long, _
lpData As Any) As Long
Private Declare Function VerQueryValue Lib "version.dl l" _
Alias "VerQueryValueA " _
(pBlock As Any, _
ByVal lpSubBlock As String, _
lpBuffer As Any, _
nVerSize As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMem ory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)
'************** *************** *
'Functions used in call back
'************** *************** *
Private Declare Function GetCurrentDirec tory _
Lib "kernel32" Alias "GetCurrentDire ctoryA" _
(ByVal nBufferLength As Long, _
ByVal lpBuffer As String) _
As Long
Private Declare Function SendMessage _
Lib "user32" Alias "SendMessag eA" _
(ByVal hWnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) _
As Long
'************** *************** *
'/Functions used in call back
'************** *************** *
'************** *************** *
'Root pidls
'************** *************** *
Private Const CSIDL_DESKTOP = &H0
Private Const CSIDL_PROGRAMS = &H2
Private Const CSIDL_CONTROLS = &H3
Private Const CSIDL_PRINTERS = &H4
Private Const CSIDL_PERSONAL = &H5
Private Const CSIDL_FAVORITES = &H6
Private Const CSIDL_STARTUP = &H7
Private Const CSIDL_RECENT = &H8
Private Const CSIDL_SENDTO = &H9
Private Const CSIDL_BITBUCKET = &HA
Private Const CSIDL_STARTMENU = &HB
Private Const CSIDL_DESKTOPDI RECTORY = &H10
Private Const CSIDL_DRIVES = &H11
Private Const CSIDL_NETWORK = &H12
Private Const CSIDL_NETHOOD = &H13
Private Const CSIDL_FONTS = &H14
Private Const CSIDL_TEMPLATES = &H15
'************** *************** *
'Root pidls
'************** *************** *
'************** *************** *
'uFlag consts
'************** *************** *
Private Const BIF_DONTGOBELOW DOMAIN = &H2
Private Const BIF_STATUSTEXT = &H4
Private Const BIF_RETURNFSANC ESTORS = &H8
Private Const BIF_BROWSEFORCO MPUTER = &H1000
Private Const BIF_BROWSEFORPR INTER = &H2000
Private Const BIF_RETURNONLYF SDIRS = &H1
Private Const BIF_EDITBOX = &H10
Private Const BIF_VALIDATE = &H20
Private Const BIF_NEWDIALOGST YLE As Long = &H40
Private Const BIF_USENEWUI As Long = (BIF_NEWDIALOGS TYLE Or BIF_EDITBOX)
'************** *************** *
'/uFlag consts
'************** *************** *
Private Const WM_USER = &H400
'************** *************** *
'Messages from dialog consts
'************** *************** *
Private Const BFFM_INITIALIZE D = 1
Private Const BFFM_SELCHANGED = 2
Private Const BFFM_VALIDATEFA ILEDA = 3
Private Const BFFM_VALIDATEFA ILED = BFFM_VALIDATEFA ILEDA
'************** *************** *
'/Messages from dialog consts
'************** *************** *
'************** *************** *
'Messages to dialog consts
'************** *************** *
Private Const BFFM_SETSELECTI ONA = WM_USER + 102
Private Const BFFM_SETSELECTI ON = BFFM_SETSELECTI ONA
Private Const BFFM_SETSTATUST EXTA = WM_USER + 100
Private Const BFFM_SETSTATUST EXT = BFFM_SETSTATUST EXTA
'************** *************** *
'/Messages to dialog consts
'************** *************** *
Private Const MAX_PATH = 260
Private strStartDir As String
'
Public Function BrowseFolder(sz DialogTitle As String, _
Optional StartDir As String = vbNullString, Optional hWnd As Long = 0) As
String
'************** *************** **************
'Name: BrowseFolder (Function)
'Purpose: Open API browse for folder dialog
'Author: Terry Kreft
'Date: January 28, 2001, 09:50:20
'Called by: Any
'Calls: AddrOf _
Various API calls defined on this module
'Inputs: szDialogTitle - dialog prompt _
StartDir - Directory to start the _
browse in (Optional)
'Output: Directory selected in browse folder
'************** *************** **************
Dim x As Long
Dim BI As BROWSEINFO
Dim dwIList As Long
Dim szPath As String
Dim wPos As Integer
Dim lngPtr As Long
Dim bytBuffer() As Byte
strStartDir = StartDir
BrowseFolder = ""
Call ZeroMemory(VarP tr(BI), Len(BI))
' This has to be 1 element larger than the length
' of the string so that it contains the terminating
' Null character
ReDim bytBuffer(0 To Len(szDialogTit le))
For lngPtr = 1 To Len(szDialogTit le)
bytBuffer(lngPt r - 1) = Asc(Mid(szDialo gTitle, lngPtr, 1))
Next
With BI
.pidlRoot = CSIDL_DESKTOP
.hOwner = hWnd
.lpszTitle = VarPtr(bytBuffe r(0))
.ulFlags = BIF_RETURNONLYF SDIRS Or BIF_STATUSTEXT _
Or BIF_EDITBOX Or BIF_VALIDATE
If IsShellVersion( 5) Then
.ulFlags = .ulFlags Or BIF_NEWDIALOGST YLE
End If
.lpfn = AddrOf2k(Addres sOf BrowseCallbackP roc)
End With
dwIList = SHBrowseForFold er(BI)
If dwIList Then
szPath = Space$(512)
x = SHGetPathFromID List(dwIList, szPath)
If x Then
wPos = InStr(szPath, Chr(0))
BrowseFolder = Left$(szPath, wPos - 1)
End If
End If
End Function
Function BrowseCallbackP roc(ByVal hWnd As Long, ByVal uMsg As Long, _
ByVal lp As Long, ByVal pData As Long) As Long
'************** *************** **************
'Name: BrowseCallbackP roc (Function)
'Purpose: Call back function for BrowseFolder
'Author: Terry Kreft
'Date: January 28, 2001, 09:52:56
'Called by: API Browse Folder dialog
'Calls: Various API functions
'Inputs: See MSDN for description of inputs
'Output:
'************** *************** **************
Dim lngRet As Long
Dim nBufferLength As Long
Dim lpBuffer As String
Const apiTrue = 1
Const apiFalse = 0
Const BAD_DIR = "The directory selected is invalid." _
& vbCrLf _
& "Do you want to try again"
lngRet = apiFalse
Select Case uMsg
Case BFFM_INITIALIZE D
If Len(strStartDir ) < 1 Then
nBufferLength = MAX_PATH
lpBuffer = String(MAX_PATH , 0)
If GetCurrentDirec tory(nBufferLen gth, lpBuffer) Then
Call SendMessage(hWn d, BFFM_SETSELECTI ON, apiTrue, ByVal lpBuffer)
End If
Else
Call SendMessage(hWn d, BFFM_SETSELECTI ON, apiTrue, ByVal strStartDir)
End If
Case BFFM_SELCHANGED
'Set the status window to the currently selected path.
lpBuffer = String(MAX_PATH , 0)
If SHGetPathFromID List(lp, lpBuffer) Then
lpBuffer = Left(lpBuffer, InStr(lpBuffer, Chr(0)) - 1)
Call SendMessage(hWn d, BFFM_SETSTATUST EXT, apiTrue, ByVal lpBuffer)
End If
Case BFFM_VALIDATEFA ILED
'If the user types an invalid path
If MsgBox(BAD_DIR, vbYesNo) = vbYes Then
lngRet = apiTrue
End If
' Case BFFM_IUNKNOWN
Case Else
' Debug.Print uMsg
End Select
BrowseCallbackP roc = lngRet
End Function
Function AddrOf2k(ByVal lngFnPtr As Long) As Long
AddrOf2k = lngFnPtr
End Function
'************** *************** *
'Code End
'************** *************** *
Private Function IsShellVersion( ByVal Version As Long) As Boolean
'returns True if the Shell version
'(shell32.dll) is equal or later than
'the value passed as 'version'
Dim nBufferSize As Long
Dim nUnused As Long
Dim lpBuffer As Long
Dim nVerMajor As Integer
Dim bBuffer() As Byte
Const sDLLFile As String = "shell32.dl l"
nBufferSize = GetFileVersionI nfoSize(sDLLFil e, nUnused)
If nBufferSize > 0 Then
ReDim bBuffer(nBuffer Size - 1) As Byte
Call GetFileVersionI nfo(sDLLFile, 0&, nBufferSize, bBuffer(0))
If VerQueryValue(b Buffer(0), "\", lpBuffer, nUnused) = 1 Then
CopyMemory nVerMajor, ByVal lpBuffer + 10, 2
IsShellVersion = nVerMajor >= Version
End If 'VerQueryValue
End If 'nBufferSize
End Function
' Code Start
'************** *************** *********
Copy and paste the code above into a module then call the BrowseFolder
function
Sample call:-
Dim strFolder as String
strFolder = BrowseFolder("F ind the Folder", "c:\program files")
--
Terry Kreft
"Salad" <oi*@vinegar.co m> wrote in message
news:UH******** ********@newsre ad1.news.pas.ea rthlink.net...
I designed a small app and I wanted to do a BrowseFolder (see
http://www.mvps.org/access/api/api0002.htm), basically do a file open
diaglog and select a directory/folder. The problem is that you can't
specify the starting folder.
Stephan Leban provided a neat solution that does allow me to browse using
a starting folder.
I am using A97 and it works fine. However, I put it onto a system that
uses AccessXP. And it chokes on references to VBA332.DLL. I searched the
drive on the XP system and there is no VBA332.DLL. That makes Stephan's
utility unworkable.
Is there anything I can use to substitute vba332.dll? Below are the
functions that make refererence to it. Does XP have a "built-in"
browsefolder command where one can specify a starting folder?
Private Declare Function GetCurrentVbaPr oject _
Lib "vba332.dll " Alias "EbGetExecuting Proj" _
(hProject As Long) As Long
Private Declare Function GetFuncID _
Lib "vba332.dll " Alias "TipGetFunction Id" _
(ByVal hProject As Long, ByVal strFunctionName As String, _
ByRef strFunctionId As String) As Long
Private Declare Function GetAddr _
Lib "vba332.dll " Alias "TipGetLpfnOfFu nctionId" _
(ByVal hProject As Long, ByVal strFunctionId As String, _
ByRef lpfn As Long) As Long