uses
... ShlObj, Forms, ActiveX;
function SelectDir(Owner: THandle; const Caption, InitialDir: string; const Root:
WideString; ShowStatus: Boolean; out Directory: string): Boolean;
function BrowseCallbackProc(hwnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): Integer; stdcall;
var
Path: array[0..MAX_PATH] of Char;
begin
case uMsg of
BFFM_INITIALIZED:
begin
SendMessage(hwnd, BFFM_SETSELECTION, 1, lpData);
SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, lpData);
end;
BFFM_SELCHANGED:
begin
if SHGetPathFromIDList(Pointer(lParam), Path) then
begin
SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, Integer(@Path));
end;
end;
end;
Result := 0;
end;
function SelectDir(Owner: THandle; const Caption, InitialDir: string; const Root:
WideString; ShowStatus: Boolean; out Directory: string): Boolean;
var
BrowseInfo: TBrowseInfo;
Buffer: PChar;
RootItemIDList,
ItemIDList: PItemIDList;
ShellMalloc: IMalloc;
IDesktopFolder: IShellFolder;
Eaten, Flags: LongWord;
Windows: Pointer;
Path: string;
begin
Result := False;
Directory := '';
Path := InitialDir;
if (Length(Path) > 0) and (Path[Length(Path)] = '\') then
begin
Delete(Path, Length(Path), 1);
end;
FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);
if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then
begin
Buffer := ShellMalloc.Alloc(MAX_PATH);
try
SHGetDesktopFolder(IDesktopFolder);
IDesktopFolder.ParseDisplayName(Owner, nil, PWideChar(Root), Eaten, RootItemIDList, Flags);
with BrowseInfo do
begin
hwndOwner := Owner;
pidlRoot := RootItemIDList;
pszDisplayName := Buffer;
lpszTitle := PChar(Caption);
ulFlags := BIF_RETURNONLYFSDIRS;
if ShowStatus then
begin
ulFlags := ulFlags or BIF_STATUSTEXT;
end;
lParam := Integer(PChar(Path));
lpfn := BrowseCallbackProc;
iImage := 0;
end;
Windows := DisableTaskWindows(Owner);
try
ItemIDList := ShBrowseForFolder(BrowseInfo);
finally
EnableTaskWindows(Windows);
end;
Result := ItemIDList <> nil;
if Result then
begin
ShGetPathFromIDList(ItemIDList, Buffer);
ShellMalloc.Free(ItemIDList);
Directory := Buffer;
end;
finally
ShellMalloc.Free(Buffer);
end;
end;
end;