' browse folder
'   创建并显示"浏览文件夹"对话框，允许用户选择的文件夹。
'hWnd： （如果有） 的父窗口的句柄
'Caption： 标题将显示为对话框的标题。
'InitialDir： 对话框中将显示初始目录。如果此值为 null，则使用当前目录。
'   Returns:      返回所选文件夹（目录）名称
  
Function FF_BrowseForFolder(ByVal hWnd As HWND, sCaption As CWSTR , InitialDir As CWSTR) As CWSTR 
   
   Dim zBuffer As wString * MAX_PATH
   Dim bi As BROWSEINFOW
   Dim lpIDList As Handle
   
   bi.hWndOwner = hWnd
   bi.lpszTitle = sCaption.vptr
   bi.ulFlags = BIF_RETURNONLYFSDIRS Or BIF_DONTGOBELOWDOMAIN Or BIF_RETURNFSANCESTORS Or BIF_USENEWUI
   bi.lpfn = cast(BFFCALLBACK, @FF_BrowseFolderProc)
   bi.lParam = Cast(LPARAM, InitialDir.vptr )
   lpIDList = SHBrowseForFolderW(@bi)
   
   If (lpIDList <> 0) AndAlso (SHGetPathFromIDListW(Cast(Any Ptr, lpIDList), @zBuffer) <> 0) Then
      CoTaskMemFree lpIDList
      Return zBuffer
   End If
   Return ""
End Function

Function FF_BrowseFolderProc(ByVal hWnd As HWND, ByVal wMsg As UInteger, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
   
   Dim zBuffer As wString * MAX_PATH
   
   Select Case wMsg
      Case BFFM_INITIALIZED
         SendMessageW hWnd, BFFM_SETSELECTION, True, lParam
         
      Case BFFM_SELCHANGED
         SHGetPathFromIDListW Cast(Any Ptr, wParam), @zBuffer
         
         If (wParam = 0) OrElse _                          ' No id number
            (Len(zBuffer)=0) OrElse _                    ' No name
            (Mid(zBuffer,2,1) <> ":") Then           ' Not a local or mapped drive
               SendMessageW hWnd, BFFM_ENABLEOK, False, False
         End If
         
   End Select
   
   Return 0
   
End Function