procedure Register;
begin
RegisterComponents('CXLib', [TCXBrowseDlg]);
end;
function BrowseCallBack(Wnd: HWND; uMsg: UINT; Param, Data: LPARAM): Integer stdcall;
var
StatusText:String;
PStatusText:PChar;
FolderDialog:TCXBrowseDlg;
EditText:AnsiString;
EnableOperation:TEnableOperation;
begin
FolderDialog:=ptr(Data);
EnableOperation:=eoNone;
GetMem(PStatusText,256);
case uMsg of
BFFM_SELCHANGED:
begin
if assigned(FolderDialog.OnChange) then
begin
if (fdStatusText in FolderDialog.Options) then
FolderDialog.OnChange(Wnd,param,true,StatusText,EnableOperation)
else
FolderDialog.OnChange(Wnd,param,false,StatusText,EnableOperation);
if (fdStatusText in FolderDialog.Options) then
SendMessage(Wnd,BFFM_SETSTATUSTEXT,0,integer(StrPCopy(PStatusText,StatusText)));//注意Pchar的处理不太好
case EnableOperation of
eoEnable:SendMessage(Wnd,BFFM_ENABLEOK,0,1);
eoDisable:SendMessage(Wnd,BFFM_ENABLEOK,0,0);
end;
end;
end;
BFFM_VALIDATEFAILED:
begin
if Assigned(FolderDialog.OnValidateFailed) then
begin
EditText:=Pchar(ptr(param));
FolderDialog.OnValidateFailed(wnd,EditText);//Pchar和String的互换?
end;
end;
end;
FreeMem(PStatusText,256);
result:=1;
end;
constructor TCXBrowseDlg.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FDisplayName:='';
FOptions:=[];
FRoot:=fiDesktop;
FTitle:='浏览文件夹';
end;
procedure TCXBrowseDlg.SetOptions(Value:TCXBrowseDlgOptions);
begin
FOptions:=Value;
if ((fdValidate in FOptions) and (not(fdEditBox in FOptions))) then
FOptions:=FOptions + [fdEditBox];
end;
function TCXBrowseDlg.Execute:Boolean;
const
DialogOptions: array[TCXBrowseDlgOption] of DWORD = (
BIF_BROWSEFORCOMPUTER,BIF_BROWSEFORPRINTER,BIF_BROWSEINCLUDEFILES,BIF_DONTGOBELOWDOMAIN,
BIF_EDITBOX,BIF_RETURNFSANCESTORS,BIF_RETURNONLYFSDIRS,BIF_STATUSTEXT,BIF_VALIDATE);
const
FolderIDs: array[TFolderID] of integer = (
CSIDL_ALTSTARTUP,CSIDL_APPDATA,CSIDL_BITBUCKET,CSIDL_COMMON_ALTSTARTUP,CSIDL_COMMON_DESKTOPDIRECTORY,
CSIDL_COMMON_FAVORITES,CSIDL_COMMON_PROGRAMS,CSIDL_COMMON_STARTMENU,CSIDL_COMMON_STARTUP,
CSIDL_CONTROLS,CSIDL_COOKIES,CSIDL_DESKTOP,CSIDL_DESKTOPDIRECTORY,CSIDL_DRIVES,CSIDL_FAVORITES,
CSIDL_FONTS,CSIDL_HISTORY,CSIDL_INTERNET,CSIDL_INTERNET_CACHE,CSIDL_NETHOOD,CSIDL_NETWORK,
CSIDL_PERSONAL,CSIDL_PRINTERS,CSIDL_PRINTHOOD,CSIDL_PROGRAMS,CSIDL_RECENT,CSIDL_SENDTO,CSIDL_STARTMENU,
CSIDL_STARTUP,CSIDL_TEMPLATES);
var
BrowseInfo: TBrowseInfo;
Option:TCXBrowseDlgOption;
RootIDList,ItemIDList: PItemIDList;
DisplayBuffer,SelectBuffer:array [0..Max_Path] of char;//PChar;
ShellMalloc: IMalloc;
begin
result:=false;
FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);
if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then
SHGetSpecialFolderLocation(Application.Handle, FolderIDs[FRoot], RootIDList);
with BrowseInfo do
begin
hwndOwner := Application.Handle;
pidlRoot := RootIDList;//nil;//RootItemIDList;
pszDisplayName := DisplayBuffer;
lpszTitle := PChar(FTitle);
for Option := Low(Option) to High(Option) do
if Option in FOptions then
ulFlags := ulFlags or DialogOptions[Option];
lpfn:=@BrowseCallBack;//如何实现CallBack函数
lparam:=integer(self);
end;
ItemIDList := ShBrowseForFolder(BrowseInfo);
Result := ItemIDList <> nil;
if Result then
begin
ShGetPathFromIDList(ItemIDList, SelectBuffer);
ShellMalloc.Free(ItemIDList);
FDirectory := SelectBuffer;
FDisplayName:=BrowseInfo.pszDisplayName;
end;
ShellMalloc.Free(RootIDList);
end;