是否有办法根据验证规则在SelectDirectory对话框中启用/禁用“确定”按钮,例如:
答案 0 :(得分:7)
如果您使用ShBrowseForFolder
API函数,则可以执行此操作。我认为Delphi附带了一个包含该函数的SelectDirectory
版本,尽管包装器可能无法为您需要的内容提供足够的访问权限。您需要为callback function参数添加lpfn
此签名:
function BrowseCallbackProc(Wnd: HWnd; uMsg: UInt; lParam, lpData: LParam): Integer; stdcall;
当选择更改时,对话框将调用您提供的bffm_SelChanged
功能作为uMsg
参数。第三个参数是表示当前选择的PIDL,因此您可能需要调用ShGetPathFromIDList
来确定字符串名称。您可以通过将消息发送回Wnd
参数中对话框的窗口句柄来控制“确定”按钮。例如:
SendMessage(Wnd, bffm_EnableOK, 0, 0); // disable the button
SendMessage(Wnd, bffm_EnableOK, 0, 1); // enable the button
在您选择无效选项后,请不要忘记重新启用正确选项的按钮。
如果有效选择的标准是目录应包含具有特定名称的文件,请务必包含bif_BrowseIncludeFiles
标记,以便人们可以看到那些文件。
答案 1 :(得分: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);