有沒有一種方法來啓用/禁用基於驗證規則在SelectDirectory對話框的確定按鈕,例如:Delphi中的SelectDirectory對話框如何動態驗證突出顯示的文件夾?
- 啓用OK按鈕,如果高亮顯示的文件夾的名稱是「配置」
- 如果突出顯示的文件夾包含名稱爲「.project」和名稱爲「.settings」的文件夾,則啓用「確定」按鈕。
?
有沒有一種方法來啓用/禁用基於驗證規則在SelectDirectory對話框的確定按鈕,例如:Delphi中的SelectDirectory對話框如何動態驗證突出顯示的文件夾?
?
如果您使用ShBrowseForFolder
API函數,則可以這樣做。我認爲Delphi帶有封裝該函數的SelectDirectory
版本,儘管封裝器可能無法爲您提供足夠的訪問權限來處理它。您需要包括爲lpfn
參數與此簽名callback function:
function BrowseCallbackProc(Wnd: HWnd; uMsg: UInt; lParam, lpData: LParam): Integer; stdcall;
當選擇發生變化時,對話框將調用該函數你提供bffm_SelChanged
爲uMsg
參數。第三個參數將是表示當前選擇的PIDL,因此您可能需要致電ShGetPathFromIDList
以確定字符串名稱。您可以通過將消息發送回Wnd
參數中對話框的窗口句柄來控制OK按鈕。例如:
SendMessage(Wnd, bffm_EnableOK, 0, 0); // disable the button
SendMessage(Wnd, bffm_EnableOK, 0, 1); // enable the button
不要忘了您禁用它無效的選擇後重新啓用按鈕好選擇。
如果有效選擇的標準是該目錄應包含具有某個名稱的文件,請確保包含bif_BrowseIncludeFiles
標誌,以便人們可以看到有哪些文件。
只是爲了補充@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);
很不錯的。我希望VCL和JVCL中的目錄選擇控件爲此提供了一個事件處理程序。 – 2010-03-15 20:17:08