Windows目錄對話框是一個標准的WindowsUI控件,其可以列出一個目錄列表,並且可以顯示新增按鈕。由於Delphi中並沒有提供對於該控件的封裝,所以打開它是個問題。網上有多種方法,試舉幾例:
1、使用Win31目錄下的DriverList、DirectoryList、FileList和FileFilterList四個控件進行組合來獲取當前目錄,操作復雜,也不美觀,對程序EXE體積影響明顯
2、使用Samples下的ShellTreeView,效果很好,但對程序EXE體積也是增加明顯
3、讓用戶直接定位文件,通過對話框OpenDialog來實現,但無法限制用戶定位文件的權限,而且可能在程序中使用相對目錄時沖突報錯
4、利用FileCtrl單元中的SelectDirectory函數定位到文件夾,且可以用Root參數限定根目錄上限,但總是彈出在右下角
5、我個人是使用以下方法直接調用Windows目錄對話框,向原作者表示衷心感謝!
unit BrowseForFolderU;
interface
function BrowseForFolder(const browseTitle:string;
const initialFolder:string=''):string;
implementation
uses Windows,shlobj;
var
lg_StartFolder:string;
function BrowseForFolderCallBack(Wnd:HWND;uMsg:UINT;
lParam,lpData:LPARAM):Integer stdcall;
begin
if uMsg=BFFM_INITIALIZED then
SendMessage(Wnd,BFFM_SETSELECTION,1,Integer(@lg_StartFolder[1]));
result:=0;
end;
function BrowseForFolder(const browseTitle:string;
const initialFolder:string=''):string;
const
BIF_NEWDIALOGSTYLE=$40;
var
browse_info:TBrowseInfo;
folder:array[0..MAX_PATH] of char;
find_context:PItemIDList;
begin
FillChar(browse_info,SizeOf(browse_info),#0);
lg_StartFolder:=initialFolder;
browse_info.pszDisplayName:=@folder[0];
browse_info.lpszTitle:=PChar(browseTitle);
browse_info.ulFlags:=BIF_RETURNONLYFSDIRS or BIF_NEWDIALOGSTYLE;
if initialFolder<>'' then
browse_info.lpfn:=BrowseForFolderCallBack;
find_context:=SHBrowseForFolder(browse_info);
if Assigned(find_context) then
begin
if SHGetPathFromIDList(find_context,folder) then
result:=folder
else
result:='';
GlobalFreePtr(find_context);
end
else
result:='';
end;
end.
調用代碼:
uses
BrowseForFolderU;
procedure TForm1.Button1Click(Sender: TObject);
var opath,dpath,omsg:String;
begin
dpath:='c:';
omsg:='請選擇路徑:';
opath:=BrowseForFolder(omsg,dpath);
if opath<>'' then Edit1.Text:=opath
else
Application.MessageBox('沒有選擇路徑','系統提示',MB_OK+MB_ICONERROR);
end;
參考:
http://blog.sina.com.cn/s/blog_7d8514840101d1is.html