Is there a way to enable / disable the Ok button in the SelectDirectory Dialog based on a validation rule, for example:
?
You can do it if you use the ShBrowseForFolder
API function. I think Delphi comes with a SelectDirectory
version that wraps that function, although the wrapper might not provide enough access for what you'd need to do with it. You need to include a callback function for the lpfn
parameter with this signature:
function BrowseCallbackProc(Wnd: HWnd; uMsg: UInt; lParam, lpData: LParam): Integer; stdcall;
When the selection changes, the dialog box will call the function you provided with bffm_SelChanged
as the uMsg
parameter. The third parameter will be a PIDL representing the current selection, so you may need to call ShGetPathFromIDList
to determine the string name. You can control the OK button by sending messages back to the dialog box's window handle in the Wnd
parameter. For example:
SendMessage(Wnd, bffm_EnableOK, 0, 0); // disable the button
SendMessage(Wnd, bffm_EnableOK, 0, 1); // enable the button
Don't forget to re-enable the button for good selections after you've disabled it for invalid selections.
If the criterion for a valid selection is that the directory should contain a file with a certain name, be sure to include the bif_BrowseIncludeFiles
flag so people can see what files are there.
Just for complement the excellent answer of @Rob.
See this code.
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;
to execute
if SelectFolderDialogExt(Handle, SelectedDir) then
ShowMessage(SelectedDir);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With