建立显示“浏览”文件夹窗口(50分)

  • 主题发起人 主题发起人 alading
  • 开始时间 开始时间
A

alading

Unregistered / Unconfirmed
GUEST, unregistred user!
我想在程序中实现点击“浏览”按钮,类似于WINDOWS中“查找文件或文件夹”中的“浏览(B)”按钮,但用DIRECTORYLISTBOX却只能看到一个驱动器中的文件夹。我想在WINDOWS中肯定有这样的API函数,但不知道如何实现,请多多指教!
 
ShBrowseForFolder(BrowseInfo)
 
我写的控件<br>unit CXBrowseDlg;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,shlobj,<br>&nbsp; ActiveX;<br><br>type<br>&nbsp; TEnableOperation=(eoNone,eoEnable,eoDisable);<br><br>&nbsp; TFolderID = (<br>&nbsp; &nbsp; fiAltStartUp,fiAppData,fiBitBucket,fiCommonAltStartUp,fiCommonDesktopDirectory,<br>&nbsp; &nbsp; fiCommonFaverites,fiCommonPrograms, fiCommonStartMenu,fiCommonStartUp ,fiControls,<br>&nbsp; &nbsp; fiCookies,fiDesktop,fiDesktopDirectory,fiDrives,fiFavorites,fiFonts,fiHistory,<br>&nbsp; &nbsp; fiInternet,fiInternetCache,fiNetHood,fiNetwork,fiPersonal,fiPrinters,fiPrintHood,<br>&nbsp; &nbsp; fiPrograms,fiRecent,fiSendTo,fiStartMenu,fiStartUp,fiTemplates);<br>&nbsp; &nbsp; <br>&nbsp; TCXBrowseDlgOption=(fdBrowseForComputer,fdBrowseForPrinter,fdBrowseInclueFiles,<br>&nbsp; &nbsp; fdDontGoBelowDomain,fdEditBox,fdReturnFSAncestors,fdReturnOnlyFSDirs,fdStatusText,<br>&nbsp; &nbsp; fdValidate);<br><br>&nbsp; TCXBrowseDlgOptions=set of TCXBrowseDlgOption;<br><br>&nbsp; TBrowseChangeProc=procedure (Handle:HWnd;LParam:lparam;DisplayText:Boolean;var StatusText:string;<br>&nbsp; &nbsp; var EnableOperation:TEnableOperation) of object;<br><br>&nbsp; TBrowseValidateProc=procedure (Handle:HWnd;ErrorInput:String) of object;<br><br>&nbsp; TCXBrowseDlg = class(TComponent)<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; &nbsp; FDirectory:String;<br>&nbsp; &nbsp; FDisplayName:string;<br>&nbsp; &nbsp; //FOnBrowseInfo:TBrowseProc;<br>&nbsp; &nbsp; FOnChange:TBrowseChangeProc;<br>&nbsp; &nbsp; FOnValidateFailed:TBrowseValidateProc;<br>&nbsp; &nbsp; FOptions:TCXBrowseDlgOptions;<br>&nbsp; &nbsp; FRoot:TFolderId;<br>&nbsp; &nbsp; FTitle:String;<br>&nbsp; &nbsp; procedure SetOptions(Value:TCXBrowseDlgOptions);<br>&nbsp; &nbsp; { Protected declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; &nbsp; //property ItemID:PItemIDList read FItemID write SetItemID;<br>&nbsp; published<br>&nbsp; &nbsp; { Published declarations }<br>&nbsp; &nbsp; constructor Create(AOwner:TComponent);override;<br>&nbsp; &nbsp; function Execute:Boolean;<br>&nbsp; &nbsp; property Title:string read FTitle write FTitle ;//default '浏览文件夹';//运行时只读<br>&nbsp; &nbsp; property Options:TCXBrowseDlgOptions read FOptions write SetOptions;//FOptions default [];<br>&nbsp; &nbsp; property Root:TFolderId read FRoot write FRoot default fiDesktop;<br>&nbsp; &nbsp; property Directory:String read FDirectory;// write FDirectory;// default '';只读<br>&nbsp; &nbsp; property DisplayName:string read FDisplayName;<br>&nbsp; &nbsp; property OnChange: TBrowseChangeProc read FOnChange write FOnChange;<br>&nbsp; &nbsp; property OnValidateFailed: TBrowseValidateProc read FOnValidateFailed write FOnValidateFailed;<br>&nbsp; end;<br><br>procedure Register;<br><br>implementation<br><br>procedure Register;<br>begin<br>&nbsp; RegisterComponents('CXLib', [TCXBrowseDlg]);<br>end;<br><br>function BrowseCallBack(Wnd: HWND; uMsg: UINT; Param, Data: LPARAM): Integer stdcall;<br>var<br>&nbsp; StatusText:String;<br>&nbsp; PStatusText:PChar;<br>&nbsp; FolderDialog:TCXBrowseDlg;<br>&nbsp; EditText:AnsiString;<br>&nbsp; EnableOperation:TEnableOperation;<br>begin<br>&nbsp; FolderDialog:=ptr(Data);<br>&nbsp; EnableOperation:=eoNone;<br>&nbsp; GetMem(PStatusText,256);<br>&nbsp; case uMsg of<br>&nbsp; &nbsp; BFFM_SELCHANGED:<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; if assigned(FolderDialog.OnChange) then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (fdStatusText in FolderDialog.Options) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FolderDialog.OnChange(Wnd,param,true,StatusText,EnableOperation)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FolderDialog.OnChange(Wnd,param,false,StatusText,EnableOperation);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (fdStatusText in FolderDialog.Options) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SendMessage(Wnd,BFFM_SETSTATUSTEXT,0,integer(StrPCopy(PStatusText,StatusText)));//注意Pchar的处理不太好<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case EnableOperation of<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; eoEnable:SendMessage(Wnd,BFFM_ENABLEOK,0,1);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; eoDisable:SendMessage(Wnd,BFFM_ENABLEOK,0,0);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; BFFM_VALIDATEFAILED:<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; if Assigned(FolderDialog.OnValidateFailed) then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EditText:=Pchar(ptr(param));<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FolderDialog.OnValidateFailed(wnd,EditText);//Pchar和String的互换?<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; end;<br>&nbsp; FreeMem(PStatusText,256);<br>&nbsp; result:=1;<br>end;<br><br>constructor TCXBrowseDlg.Create(AOwner:TComponent);<br>begin<br>&nbsp; inherited Create(AOwner);<br>&nbsp; FDisplayName:='';<br>&nbsp; FOptions:=[];<br>&nbsp; FRoot:=fiDesktop;<br>&nbsp; FTitle:='浏览文件夹';<br>end;<br><br>procedure TCXBrowseDlg.SetOptions(Value:TCXBrowseDlgOptions);<br>begin<br>&nbsp; FOptions:=Value;<br>&nbsp; if ((fdValidate in FOptions) and (not(fdEditBox in FOptions))) then<br>&nbsp; &nbsp; FOptions:=FOptions + [fdEditBox];<br>end;<br><br>function TCXBrowseDlg.Execute:Boolean;<br>const<br>&nbsp; DialogOptions: array[TCXBrowseDlgOption] of DWORD = (<br>&nbsp; &nbsp; BIF_BROWSEFORCOMPUTER,BIF_BROWSEFORPRINTER,BIF_BROWSEINCLUDEFILES,BIF_DONTGOBELOWDOMAIN,<br>&nbsp; &nbsp; BIF_EDITBOX,BIF_RETURNFSANCESTORS,BIF_RETURNONLYFSDIRS,BIF_STATUSTEXT,BIF_VALIDATE);<br>const<br>&nbsp; FolderIDs: array[TFolderID] of integer = (<br>&nbsp; &nbsp; CSIDL_ALTSTARTUP,CSIDL_APPDATA,CSIDL_BITBUCKET,CSIDL_COMMON_ALTSTARTUP,CSIDL_COMMON_DESKTOPDIRECTORY,<br>&nbsp; &nbsp; CSIDL_COMMON_FAVORITES,CSIDL_COMMON_PROGRAMS,CSIDL_COMMON_STARTMENU,CSIDL_COMMON_STARTUP,<br>&nbsp; &nbsp; CSIDL_CONTROLS,CSIDL_COOKIES,CSIDL_DESKTOP,CSIDL_DESKTOPDIRECTORY,CSIDL_DRIVES,CSIDL_FAVORITES,<br>&nbsp; &nbsp; CSIDL_FONTS,CSIDL_HISTORY,CSIDL_INTERNET,CSIDL_INTERNET_CACHE,CSIDL_NETHOOD,CSIDL_NETWORK,<br>&nbsp; &nbsp; CSIDL_PERSONAL,CSIDL_PRINTERS,CSIDL_PRINTHOOD,CSIDL_PROGRAMS,CSIDL_RECENT,CSIDL_SENDTO,CSIDL_STARTMENU,<br>&nbsp; &nbsp; CSIDL_STARTUP,CSIDL_TEMPLATES);<br>var<br>&nbsp; BrowseInfo: TBrowseInfo;<br>&nbsp; Option:TCXBrowseDlgOption;<br>&nbsp; RootIDList,ItemIDList: PItemIDList;<br>&nbsp; DisplayBuffer,SelectBuffer:array [0..Max_Path] of char;//PChar;<br>&nbsp; ShellMalloc: IMalloc;<br>begin<br>&nbsp; result:=false;<br>&nbsp; FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);<br>&nbsp; if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc &lt;&gt; nil) then<br>&nbsp; &nbsp; SHGetSpecialFolderLocation(Application.Handle, FolderIDs[FRoot], RootIDList);<br>&nbsp; with BrowseInfo do<br>&nbsp; begin<br>&nbsp; &nbsp; hwndOwner := Application.Handle;<br>&nbsp; &nbsp; pidlRoot := RootIDList;//nil;//RootItemIDList;<br>&nbsp; &nbsp; pszDisplayName := DisplayBuffer;<br>&nbsp; &nbsp; lpszTitle := PChar(FTitle);<br>&nbsp; &nbsp; for Option := Low(Option) to High(Option) do<br>&nbsp; &nbsp; &nbsp; if Option in FOptions then<br>&nbsp; &nbsp; &nbsp; &nbsp; ulFlags := ulFlags or DialogOptions[Option];<br>&nbsp; &nbsp; lpfn:=@BrowseCallBack;//如何实现CallBack函数<br>&nbsp; &nbsp; lparam:=integer(self);<br>&nbsp; end;<br>&nbsp; ItemIDList := ShBrowseForFolder(BrowseInfo);<br>&nbsp; Result := &nbsp;ItemIDList &lt;&gt; nil;<br>&nbsp; if Result then<br>&nbsp; begin<br>&nbsp; &nbsp; ShGetPathFromIDList(ItemIDList, SelectBuffer);<br>&nbsp; &nbsp; ShellMalloc.Free(ItemIDList);<br>&nbsp; &nbsp; FDirectory := SelectBuffer;<br>&nbsp; &nbsp; FDisplayName:=BrowseInfo.pszDisplayName;<br>&nbsp; end;<br>&nbsp; ShellMalloc.Free(RootIDList);<br>end;<br><br>end.<br>//应加上FolderInfo属性,应加上Enable属性(实现的有问题<br>//应再加上ItemIDList的属性,Caption,Center属性。
 
天! 至于吗?!!!!<br>用D4里面的SelectDirectory函数就可以完全达到你要的效果!
 
ok the question should be solved:)
 
多人接受答案了。
 
后退
顶部