function
AdvBrowseDirectory(sCaption:
String
; wsRoot:
WideString
;
var
sDirectory:
String
; bEditBox:
Boolean
=
False
; bShowFiles:
Boolean
=
False
; bAllowCreateDirs:
Boolean
=
True
; bRootIsMyComp:
Boolean
=
False
):
Boolean
;
function
SelectDirCB(Wnd: HWND; uMsg: UINT; lParam, lpData: lParam):
Integer
; stdcall;
begin
case
uMsg
of
BFFM_INITIALIZED: SendMessage(Wnd, BFFM_SETSELECTION, Ord(
True
),
Integer
(lpData));
end
;
Result :=
0
;
end
;
var
WindowList:
Pointer
;
BrowseInfo: TBrowseInfo;
Buffer:
PChar
;
RootItemIDList, ItemIDList: PItemIDList;
ShellMalloc: IMalloc;
IDesktopFolder: IShellFolder;
Eaten, Flags:
LongWord
;
const
BIF_USENEWUI =
$0040
;
BIF_NOCREATEDIRS =
$0200
;
begin
Result :=
False
;
if
not
DirectoryExists(sDirectory)
then
sDirectory :=
''
;
FillChar(BrowseInfo, SizeOf(BrowseInfo),
0
);
if
(ShGetMalloc(ShellMalloc) = S_OK)
and
(ShellMalloc <>
nil
)
then
begin
Buffer := ShellMalloc
.
Alloc(MAX_PATH);
try
RootItemIDList :=
nil
;
if
wsRoot <>
''
then
begin
SHGetDesktopFolder(IDesktopFolder);
IDesktopFolder
.
ParseDisplayName(Application
.
Handle,
nil
,
POleStr(wsRoot), Eaten, RootItemIDList, Flags);
end
else
begin
if
bRootIsMyComp
then
SHGetSpecialFolderLocation(
0
, CSIDL_DRIVES, RootItemIDList);
end
;
OleInitialize(
nil
);
with
BrowseInfo
do
begin
hwndOwner := Application
.
Handle;
pidlRoot := RootItemIDList;
pszDisplayName := Buffer;
lpszTitle :=
PChar
(sCaption);
ulFlags :=
BIF_RETURNONLYFSDIRS
or
BIF_USENEWUI
or
BIF_EDITBOX * Ord(bEditBox)
or
BIF_BROWSEINCLUDEFILES * Ord(bShowFiles)
or
BIF_NOCREATEDIRS * Ord(
not
bAllowCreateDirs);
lpfn := @SelectDirCB;
if
sDirectory <>
''
then
lParam :=
Integer
(
PChar
(sDirectory));
end
;
WindowList := DisableTaskWindows(
0
);
try
ItemIDList := ShBrowseForFolder(BrowseInfo);
finally
EnableTaskWindows(WindowList);
end
;
Result := ItemIDList <>
nil
;
if
Result
then
begin
ShGetPathFromIDList(ItemIDList, Buffer);
ShellMalloc
.
Free(ItemIDList);
sDirectory := Buffer;
end
;
finally
ShellMalloc
.
Free(Buffer);
end
;
end
;
end
;