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)