RSS
StartseiteKnowledge LibraryTop 10Impressum

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