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);