by jingzhongrong
原文地址:http://blog.youkuaiyun.com/jingzhongrong/archive/2007/01/02/1472452.aspx
由于使用到了UnicodeString,因此,本篇文章只适用于BCB2009。
使用方法,见文章后。
效果:
theFolderDialog.h如下:
- //---------------------------------------------------------------------------
- #define NO_WIN32_LEAN_AND_MEAN
- #ifndef theFolderDialogH
- #define theFolderDialogH
- //---------------------------------------------------------------------------
- #include <shlobj.h>
- #include <vcl.h>
- class FolderDialog
- {
- private:
- BROWSEINFO FInfo;
- wchar_t* FTitle;
- protected:
- wchar_t FFolderName[260]; /**保存返回的目录名称*/
- UnicodeString FFolderPath; /**保存路径名*/
- UnicodeString __fastcall GetDialogTitle() { return FTitle; }
- void __fastcall SetDialogTitle(const UnicodeString& title);
- UnicodeString __fastcall GetFolderPath() { return FFolderPath; }
- UnicodeString __fastcall GetFolderName() { return UnicodeString(FFolderName); }
- public:
- /**初始化调用句柄
- @HwndOwner 调用者句柄
- */
- FolderDialog(HWND HwndOwner);
- FolderDialog(); //如果没有指定句柄,则需使用带参数的Execute函数
- void __fastcall SetBrowseInfoFlags(UINT ulFlags); /**提供对FInfo的自定义*/
- bool __fastcall Execute(void); //打开对话框
- bool __fastcall Execute(HWND HwndOwner);
- __property UnicodeString Title={read=GetDialogTitle, write=SetDialogTitle};
- __property UnicodeString FolderName={read=GetFolderName};
- __property UnicodeString FolderPath={read=GetFolderPath};
- };
- #endif
theFolderDialog.cpp如下:
- //---------------------------------------------------------------------------
- #pragma hdrstop
- #include "theFolderDialog.h"
- //ver 1.3
- //* 修正可能的内存泄露问题
- //* 修正SetBrowseInfoFlags函数
- //+ 使用CoInitialize以及BIF_USENEWUI可以支持有新建文件夹按钮的对话框
- //ver 2.0
- //* Unicode版本
- //---------------------------------------------------------------------------
- #pragma package(smart_init)
- #define INFO_BUFFER_SIZE 32767
- FolderDialog::FolderDialog(HWND HwndOwner)
- {
- memset(&FInfo,0,sizeof(BROWSEINFO));
- memset(FFolderName,0,260);
- FInfo.hwndOwner = HwndOwner;
- FInfo.pszDisplayName = FFolderName;
- FInfo.lpszTitle = L"请选择目录";
- FInfo.ulFlags = BIF_RETURNONLYFSDIRS;
- FTitle = new wchar_t[wcslen(FInfo.lpszTitle)+1];
- wcscpy(FTitle,FInfo.lpszTitle);
- FTitle[wcslen(FInfo.lpszTitle)] = 0;
- }
- FolderDialog::FolderDialog()
- {
- memset(&FInfo,0,sizeof(BROWSEINFO));
- memset(FFolderName,0,260);
- FInfo.pszDisplayName = FFolderName;
- FInfo.lpszTitle = L"请选择目录";
- FInfo.ulFlags = BIF_RETURNONLYFSDIRS;
- FTitle = new wchar_t[wcslen(FInfo.lpszTitle)+1];
- wcscpy(FTitle,FInfo.lpszTitle);
- FTitle[wcslen(FInfo.lpszTitle)] = 0;
- }
- void __fastcall FolderDialog::SetBrowseInfoFlags(UINT ulFlags)
- {
- FInfo.ulFlags |= ulFlags;
- }
- bool __fastcall FolderDialog::Execute()
- {
- LPITEMIDLIST ItemID;
- wchar_t SelectDir[INFO_BUFFER_SIZE] = { 0 };
- ItemID = SHBrowseForFolder(&FInfo);
- if(ItemID)
- {
- SHGetPathFromIDList(ItemID,SelectDir);
- GlobalFree(ItemID);
- FFolderPath = UnicodeString(SelectDir);
- return true;
- }
- else
- {
- return false;
- }
- }
- bool __fastcall FolderDialog::Execute(HWND HwndOwner)
- {
- FInfo.hwndOwner = HwndOwner;
- if(Execute())
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- void __fastcall FolderDialog::SetDialogTitle(const UnicodeString& title)
- {
- if(FTitle != NULL)
- delete FTitle;
- FTitle = new wchar_t[title.Length()+1];
- wcscpy(FTitle,title.w_str());
- FTitle[title.Length()] = 0;
- FInfo.lpszTitle = FTitle;
- }
使用方法:
1、将上述文件添加到工程中。
2、在使用处添加下面代码:
- // set the folder selection dialog box to the centre of the form
- // use CoInitialize to initialize COM library on a thread
- // we can use BIF_USENEWUI flags , see MSDN for more information
- CoInitialize(NULL);
- FolderDialog fd;
- fd.Title = L"请选择工程根目录目录:";
- fd.SetBrowseInfoFlags(BIF_BROWSEFORCOMPUTER|BIF_NEWDIALOGSTYLE|BIF_NONEWFOLDERBUTTON);
- fd.Execute(Application->Handle);
- if(fd.FolderPath != "")
- {
- this->LabeledEdit1->Text = fd.FolderPath;
- }
- CoUninitialize();
如果需要“新建文件夹”按钮请根据MSDN:BROWSEINFO结构的ulFlags所描述的进行修改。