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