用shBrowseForFolder函数
//uses unit shlobj
procedure TForm1.Button1Click(Sender: TObject);
var
brow : _browseinfoA;
begin
FillChar(Brow, SizeOf(Brow), 0);
Brow.hwndOwner := Form1.Handle ;
brow.ulFlags := BIF_RETURNONLYFSDIRS;
Brow.lpszTitle := 'Select A Directory';
ShBrowseForFolder(Brow);
end;
//uses unit shlobj
procedure TForm1.Button1Click(Sender: TObject);
var
brow : _browseinfoA;
begin
FillChar(Brow, SizeOf(Brow), 0);
Brow.hwndOwner := Form1.Handle ;
brow.ulFlags := BIF_RETURNONLYFSDIRS;
Brow.lpszTitle := 'Select A Directory';
ShBrowseForFolder(Brow);
end;
同意hubdog,注意它有两个原型,打开不同的对话框:一个就是你所说的,另外一个是Windows 3.x风格的,如果你用过的话。在程序中一定加入下面一句:uses ..., FileCtrl;To AcherMagic:
为什么不用现成的呢?
或者你去深度历险去down一些类似的控件
一大堆
unit CXBrowseDlg;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,shlobj,
ActiveX;type
TEnableOperation=(eoNone,eoEnable,eoDisable); TFolderID = (
fiAltStartUp,fiAppData,fiBitBucket,fiCommonAltStartUp,fiCommonDesktopDirectory,
fiCommonFaverites,fiCommonPrograms, fiCommonStartMenu,fiCommonStartUp ,fiControls,
fiCookies,fiDesktop,fiDesktopDirectory,fiDrives,fiFavorites,fiFonts,fiHistory,
fiInternet,fiInternetCache,fiNetHood,fiNetwork,fiPersonal,fiPrinters,fiPrintHood,
fiPrograms,fiRecent,fiSendTo,fiStartMenu,fiStartUp,fiTemplates);
TCXBrowseDlgOption=(fdBrowseForComputer,fdBrowseForPrinter,fdBrowseInclueFiles,
fdDontGoBelowDomain,fdEditBox,fdReturnFSAncestors,fdReturnOnlyFSDirs,fdStatusText,
fdValidate); TCXBrowseDlgOptions=set of TCXBrowseDlgOption; TBrowseChangeProc=procedure (Handle:HWnd;LParam:lparam;DisplayText:Boolean;var StatusText:string;
var EnableOperation:TEnableOperation) of object; TBrowseValidateProc=procedure (Handle:HWnd;ErrorInput:String) of object; TCXBrowseDlg = class(TComponent)
private
{ Private declarations }
FDirectory:String;
FDisplayName:string;
//FOnBrowseInfo:TBrowseProc;
FOnChange:TBrowseChangeProc;
FOnValidateFailed:TBrowseValidateProc;
FOptions:TCXBrowseDlgOptions;
FRoot:TFolderId;
FTitle:String;
procedure SetOptions(Value:TCXBrowseDlgOptions);
{ Protected declarations }
public
{ Public declarations }
//property ItemID:PItemIDList read FItemID write SetItemID;
published
{ Published declarations }
constructor Create(AOwner:TComponent);override;
function Execute:Boolean;
property Title:string read FTitle write FTitle ;//default '浏览文件夹';//运行时只读
property Options:TCXBrowseDlgOptions read FOptions write SetOptions;//FOptions default [];
property Root:TFolderId read FRoot write FRoot default fiDesktop;
property Directory:String read FDirectory;// write FDirectory;// default '';只读
property DisplayName:string read FDisplayName;
property OnChange: TBrowseChangeProc read FOnChange write FOnChange;
property OnValidateFailed: TBrowseValidateProc read FOnValidateFailed write FOnValidateFailed;
end;procedure Register;implementationprocedure 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;end.
//应加上FolderInfo属性,应加上Enable属性(实现的有问题
//应再加上ItemIDList的属性,Caption,Center属性。
SelectDirectory('请选择备份数据库所在目录','桌面',dir)其中dir为一string型,
不过,为了感谢各位的关心,每人有奖!!