Ordner auswählen mit BrowseForFolder
Für die Auswahl eines Verzeichnisses hat Windows einen eigenen Dialog parat.
Für die Auswahl von Dateien steht Ihnen das CommonDialog Control zur Verfügung. Doch in manchen Anwendungsfällen ist nur ein Laufwerk bzw. ein Verzeichnis gefragt, hierfür ist das CommonDialog Control nicht geeignet, da nur Dateien eine gültige Auswahl darstellen.
Windows hat aber für diese Zwecke einen eigenen netten Dialog vorgesehen, den "Ordner auswählen" - Dialog. Sie haben dabei zwei Möglichkeiten diesen Dialog zu nutzen, entweder über die API- Funktion
SHBrowseForFolder oder vorgefertigt in Form der "Shell Controls and Automation" - Bibliothek, die
ab IE4 zur Verfügung steht. Betrachtet man die Option über eine BrowseCallBack Funktion erweiterten Einfluss
auf den Dialog zu nehmen, als eigenständige Möglichkeit, sind es sogar drei.
SHBrowseForFolder – schnörkellos
Den "Ordner auswählen" Dialog in seiner einfachsten Ausführung, können Sie mit nur drei API Aufrufen anzeigen: SHBrowseForFolder für die eigentliche Anzeige des Dialogs, SHGetPathFromIDList, um den ausgewählten Pfad aus dem zurückgegeben PIDL (Pointer to Item ID List) zu ermitteln und zum Abschluss noch CoTaskMemFree, um den PIDL wieder freizugeben:
Private Type BROWSEINFO
hwndOwner As Long
pIDLRoot As Long
pszDisplayName As Long
lpszTitle As String
ulFlags As Long
lpfnCallback As Long
lParam As Long
iImage As Long
End Type
Private Declare Function SHBrowseForFolder Lib "Shell32" (
ByRef lpbi As BROWSEINFO _
) As Long
Private Declare Function SHGetPathFromIDList Lib "Shell32" ( _
ByVal pidList As Long, _
ByVal lpBuffer As String _
) As Long
Private Declare Sub CoTaskMemFree Lib "ole32" ( _
ByVal hMem As Long)
Private Const MAX_PATH = 260
Private Const BIF_RETURNONLYFSDIRS = &H1& 'Nur Verzeichnisse
Public Function BrowseForFolder(Optional Parent As Variant, _
Optional Title As Variant) As String
Dim tBI As BROWSEINFO
Dim lhWndParent As Long
Dim lngPIDL As Long
Dim strPath As String
If IsMissing(Title) Then Title = "Wählen Sie einen Ordner aus."
If IsMissing(Parent) = False Then lhWndParent = Parent.hWnd
With tBI
.hwndOwner = lhWndParent
.lpszTitle = Title
.ulFlags = BIF_RETURNONLYFSDIRS
End With
lngPIDL = SHBrowseForFolder(tBI)
If (lngPIDL <> 0) Then
' Pfad aus Item ID List ermitteln:
strPath = Space$(MAX_PATH)
SHGetPathFromIDList lngPIDL, strPath
strPath = Left$(strPath, InStr(strPath, Chr$(0)) - 1)
' PIDL freigeben:
CoTaskMemFree lngPIDL
End If
BrowseForFolder = strPath
End Function
Ein möglicher Aufruf der Funktion:
Debug.Print BrowseForFolder(Me)
Den Download des Moduls, finden Sie am Ende des Artikel.
SHBrowseForFolder - BrowseCallback
Der "Ordner auswählen" Dialog kann natürlich auch weiter angepasst werden. So kann man ab IE4/Win98 ein zusätzliches Eingabefeld anzeigen lassen oder neben Ordnern, auch nach Dateien suchen lassen. Windows 2000 bietet darüber hinaus auch ein gänzlich neues Layout und erweiterte Funktionen an. Der Dialog kann in seiner Größe verändert werden, Drag & Drop Operationen sind möglich, das Kontextmenü steht zur Verfügung und es können neue Ordner angelegt werden. Diese Optionen können noch über den ulFlags - Parameter der BROWSEINFO - Struktur festgelegt werden.
Will man aber selber festlegen, welcher Pfad angezeigt werden soll, wann der OK - Button freigegeben ist oder wie der Dialog positioniert werden soll, muss man eine eigene BrowseCallback Prozedur einrichten und auf die entsprechenden Nachrichten reagieren. Die Adresse dieser Prozedur, kann über den Parameter lpfnCallback übergeben werden.
Ein Klassenmodul, das erweiterte Optionen des "Ordner auswählen" Dialogs bereitstellt, kann am Endes des Artikels heruntergeladen werden.
BrowseForFolder - Funktion der "Microsoft Shell Controls and Automation" Bibliothek
Zu guter letzt sei noch die vorgefertigte BrowseForFolder - Funktion erwähnt, die über "Microsoft Shell Controls and Automation" Bibliothek seit IE4 bzw. Win98 zur Verfügung steht (Projekt => Verweise). Auch ihre Anwendung ist denkbar einfach:
Dim objShell As Shell32.Shell
Dim objFolder As Shell32.Folder
Const BIF_RETURNONLYFSDIRS = &H1&
Set objShell = New Shell32.Shell
Set objFolder = objShell.BrowseForFolder(Me.hWnd, _
"Wählen Sie einen Ordner aus.", _
BIF_RETURNONLYFSDIRS, mlng_RootFolder)
If Not objFolder Is Nothing Then
Debug.Print objFolder.Items.Item.Path
Else
' "Abbrechen" gewählt
End If
- BrowseFolders Modul und Beispielprojekt (browsefolder1.zip - ca. 4 KB)
- BrowseFolder Klassenmodul und Beispielprojekt (browsefolder2.zip - ca. 20 KB)
- Shell32 Automation - BrowseForFolder Beispielprojekt (browsefolder3.zip - ca. 3 KB)