How does the Delphi SelectDirectory dialog box dynamically check the selected folder?

Is there a way to enable / disable the Ok button in the SelectDirectory dialog box based on a validation rule, for example:

  • enable the OK button if the name of the selected folder is "config"
  • enable the OK button if the selected folder contains a file named ".project" and a folder named ".settings"

?

+4
source share
2 answers

You can do this if you use the ShBrowseForFolder API ShBrowseForFolder . I think Delphi comes with a version of SelectDirectory that wraps this function, although the shell may not provide sufficient access for what you need to do with it. For lpfn you must enable the ShGetPathFromIDList function to determine the string name. You can control the OK button by sending messages back to the window handle of the dialog box in the Wnd parameter. For instance:

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

Remember to re-enable the button for the correct selection after you disable it for invalid selections.

If the criterion for the actual choice is that the directory should contain a file with a specific name, be sure to enable the bif_BrowseIncludeFiles flag bif_BrowseIncludeFiles that people can see which files are.

+7
source

Just to complement, @Rob's great answer.

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; 

execute

 if SelectFolderDialogExt(Handle, SelectedDir) then ShowMessage(SelectedDir); 
+5
source

Source: https://habr.com/ru/post/1304185/


All Articles