2010-03-15 37 views

回答

7

如果您使用ShBrowseForFolder API函數,則可以這樣做。我認爲Delphi帶有封裝該函數的SelectDirectory版本,儘管封裝器可能無法爲您提供足夠的訪問權限來處理它。您需要包括爲lpfn參數與此簽名callback function

function BrowseCallbackProc(Wnd: HWnd; uMsg: UInt; lParam, lpData: LParam): Integer; stdcall; 

當選擇發生變化時,對話框將調用該函數你提供bffm_SelChangeduMsg參數。第三個參數將是表示當前選擇的PIDL,因此您可能需要致電ShGetPathFromIDList以確定字符串名稱。您可以通過將消息發送回Wnd參數中對話框的窗口句柄來控制OK按鈕。例如:

SendMessage(Wnd, bffm_EnableOK, 0, 0); // disable the button 
SendMessage(Wnd, bffm_EnableOK, 0, 1); // enable the button 

不要忘了您禁用它無效的選擇後重新啓用按鈕選擇。

如果有效選擇的標準是該目錄應包含具有某個名稱的文件,請確保包含bif_BrowseIncludeFiles標誌,以便人們可以看到有哪些文件。

+1

很不錯的。我希望VCL和JVCL中的目錄選擇控件爲此提供了一個事件處理程序。 – 2010-03-15 20:17:08

5

只是爲了補充@Rob的優秀答案。

請參閱此代碼。

uses ShlObj; 

function BrowseCallbackProc(hwnd: HWND; MessageID: UINT; lParam: LPARAM; lpData: LPARAM): Integer; stdcall; 
var 
    DirName: array[0..MAX_PATH] of Char; 
    pIDL : pItemIDList; 
begin 
    case MessageID of 
    BFFM_INITIALIZED:SendMessage(hwnd, BFFM_SETSELECTION, 1, lpData); 
    BFFM_SELCHANGED :begin 
         pIDL := Pointer(lParam); 
         if Assigned(PIDL) then 
         begin 
          SHGetPathFromIDList(pIDL, DirName); 
          if DirectoryExists(DirName) then 
          if (ExtractFileName(DirName)='config') then //you can add more validations here 
          SendMessage(hwnd, BFFM_ENABLEOK, 0, 1) //enable the ok button 
          else 
          SendMessage(hwnd, BFFM_ENABLEOK, 0, 0) //disable the ok button 
          else 
          SendMessage(hwnd, BFFM_ENABLEOK, 0, 0); 
         end 
         else 
          SendMessage(hwnd, BFFM_ENABLEOK, 0, 0); 
        end; 
    end; 

    Result := 0; 
end; 

function SelectFolderDialogExt(Handle: Integer; var SelectedFolder: string): Boolean; 
var 
    ItemIDList: PItemIDList; 
    JtemIDList: PItemIDList; 
    DialogInfo: TBrowseInfo; 
    Path: PAnsiChar; 
begin 
    Result := False; 
    Path := StrAlloc(MAX_PATH); 
    SHGetSpecialFolderLocation(Handle, CSIDL_DRIVES, JtemIDList); 
    with DialogInfo do 
    begin 
    pidlRoot  := JtemIDList; 
    //ulFlags  := BIF_RETURNONLYFSDIRS;  //only select directories 
    hwndOwner  := GetActiveWindow; 
    SHGetSpecialFolderLocation(hwndOwner, CSIDL_DRIVES, JtemIDList); 
    pszDisplayName := StrAlloc(MAX_PATH); 
    lpszTitle  := PChar('Select a folder'); 
    lpfn   := @BrowseCallbackProc; 
    lParam   := LongInt(PChar(SelectedFolder)); 
    end; 

    ItemIDList := SHBrowseForFolder(DialogInfo); 

    if (ItemIDList <> nil) then 
    if SHGetPathFromIDList(ItemIDList, Path) then 
    begin 
     SelectedFolder := Path; 
     Result   := True; 
    end; 
end; 

執行

if SelectFolderDialogExt(Handle, SelectedDir) then 
    ShowMessage(SelectedDir); 
相關問題