CBrowseCtrl - 轻松为您的项目添加文件/文件夹浏览功能






4.93/5 (54投票s)
2004年1月9日
5分钟阅读

293698

7864
一个集成了编辑框和带内置图像按钮的文件/文件夹浏览控件
引言
通常,当我们需要为项目添加文件/文件夹浏览功能时,需要做很多琐碎的工作:首先,我们必须创建一个 CEdit
来显示路径名,然后,我们需要创建一个 CButton
并处理其 ON_BN_CLICKED
事件来启动 CFileDialog
并将路径名复制到 CEdit
。此外,如果我们想让它看起来漂亮,还需要包含一些图标或位图资源来装饰 CButton
。如果多个对话框都需要文件/文件夹浏览功能,这可能会让人头疼。
我一直在想,如果 MFC 中有一个控件,它集成了 CEdit
和 CButton
,处理控件事件,弹出 CFileDialog
并自动更新 CEdit
文本,那该多好。如果该控件还有一些内置图像,也就是说,它有自己的绘图能力,不需要我们提供任何图像资源,那就更好了。当然,一些工具提示也没什么坏处……不幸的是,MFC 中没有这样的控件,但幸运的是,我们可以自己做一个。
CBrowseCtrl
就是为了满足我上面段落中描述的精确需求而创建的。它派生自 CButton
,上面有一个编辑框、一个浏览按钮和一个工具提示。它还可以在浏览按钮上绘制一些内置图像,因此您无需为此控件包含任何图标或位图资源。它自己处理按钮事件,因此每当用户单击浏览按钮时,都会弹出文件/文件夹对话框。
如何使用
您需要先将源文件 BrowseCtrl.h 和 BrowseCtrl.cpp 添加到您的工作区,并在需要的地方包含 BrowseCtrl.h。要创建控件,您可以使用 CBrowseCtrl::Create
在运行时创建它,或者在对话框模板上绘制一个 CButton
并将其与 CBrowseCtrl
变量绑定。
代码示例
指定控件样式
您可以随时访问控件样式来更改其外观和行为。可以使用“|
”运算符组合多个样式标志。有效的样式标志是:
标志 | 效果 |
BC_CTL_ALLOWEDIT | 允许用户在编辑框中键入 |
BC_CTL_FOLDERSONLY | 仅浏览文件夹,而非文件 |
BC_BTN_LEFT | 在编辑框的左侧显示浏览按钮 |
BC_BTN_FLAT | 使用平面按钮样式 |
BC_BTN_ICON | 使用图标,不显示文本 |
BC_ICO_ARROWFOLDER | 箭头文件夹图标,必须与 BC_BTN_ICON 结合使用 |
BC_ICO_FOLDER | 文件夹图标,必须与 BC_BTN_ICON 结合使用 |
BC_ICO_EXPLORER | Windows Explorer 图标,必须与 BC_BTN_ICON 结合使用 |
要为浏览按钮设置“Windows Explorer”图标,使按钮呈平面样式,最后,使控件仅“浏览文件夹”。
DWORD dwStyle = m_wndBrowseCtrl.GetButtonStyle();
dwStyle |= BC_BTN_ICON; // Make sure to display icon instead of text
dwStyle |= BC_BTN_FLAT; // Flat button
dwStyle &= ~BC_ICO_ARROWFOLDER; // Remove other icons
dwStyle &= ~BC_ICO_FOLDER;
dwStyle |= BC_ICO_EXPLORER; // Set the explorer icon
dwStyle |= BC_CTL_FOLDERSONLY; // Browse for folders only
m_wndBrowseCtrl.SetButtonStyle(dwStyle); // Apply
我厌倦了图像,希望浏览按钮显示文本,例如“Click Me!”,并显示工具提示“Click to browse your files。”
m_wndBrowseCtrl.SetButtonStyle(m_wndBrowseCtrl.GetButtonStyle() & ~BC_BTN_ICON);
m_wndBrowseCtrl.SetButtonText(_T("Click Me!"));
m_wndBrowseCtrl.SetTooltipText(_T("Click to browse your files."));
浏览文件和文件夹
CBrowseCtrl
会自己处理按钮事件,因此每当用户单击浏览按钮时,都会自动弹出一个文件或文件夹对话框。当然,您也可以在代码中以编程方式处理它,通常您可能希望使用传递给 CFileDialog
构造函数的任何内容来初始化文件对话框。CBrowseCtrl
提供了一组函数来实现相同的初始化,您基本上可以将该控件视为一个对话框。
m_wndBrowseCtrl.SetOpenSave(TRUE); // TRUE-"open", FALSE-"save as"
m_wndBrowseCtrl.SetDefExt(NULL); // Do not use any default extension
m_wndBrowseCtrl.SetFilter(_T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||"));
m_wndBrowseCtrl.SetFileFlags(OFN_FILEMUSTEXIST | OFN_HIDEREADONLY);
m_wndBrowseCtrl.SetPathName(_T("c:\\MyApp\\readme.txt")); // default path
if (m_wndBrowseCtrl.DoModal() == IDOK)
MessageBox(m_wndBrowseCtrl.GetPathName());
浏览文件夹
m_wndBrowseCtrl.SetButtonStyle(m_wndBrowseCtrl.GetButtonStyle()
| BC_CTL_FOLDERSONLY);
// Display an editbox on the dialog
m_wndBrowseCtrl.SetFolderFlags(BIF_EDITBOX);
m_wndBrowseCtrl.SetFolderDialogTitle(_T("Please select a folder"));
if (m_wndBrowseCtrl.DoModal() == IDOK)
MessageBox(m_wndBrowseCtrl.GetPathName());
如果用户从文件对话框中选择了多个文件,您可以通过以下代码迭代所有路径名:
if (m_wndBrowseCtrl.GetSelectedCount() > 1)// Multiple files selected
{
POSITION pos = m_wndBrowseCtrl.GetStartPosition();
while (pos != NULL)
{
CString sPathName = m_wndBrowseCtrl.GetNextPathName(pos);
// Process the path name...
}
}
通知父窗口
用户关闭文件/文件夹对话框后,会向父窗口发送一个通知消息。wParam
要么是 IDOK
,要么是 IDCANCEL
,lParam
是指向此 CBrowseCtrl
对象的指针。
要使控件通知父窗口,您需要为 CBrowseCtrl
提供一个大于 0 的自定义窗口消息。如果您提供的消息是 0,则不会发送消息。如果您不提供任何消息,也不会发送任何消息。
#define WM_BROWSE_NOTIFY WM_APP + 100
m_wndBrowseCtrl.SetNotifyMessageID(WM_BROWSE_NOTIFY);
// Now ready to receive the notification!
结论
就这样。这是一个很棒的小控件,我希望它能在某些情况下帮助到您。欢迎提出任何建议,感谢您的时间。
历史
2004年1月8日
- 首次发布
2004年1月9日
- 改进了绘图函数,以正确处理控件客户区太小无法绘制的情况。在调试模式下,它将提供一个消息框来通知开发者该问题。
- 改进了编辑框,使其在接收和失去输入焦点时表现更好。
- 更新了源代码和演示项目。
2004年1月10日
- 修复了在某些事件发生时编辑框未正确重绘的问题。感谢 JOHN11
- 添加了方法
CBrowseCtrl::GetSelectedCount
,该方法返回用户在最近一次以IDOK
终止的文件/文件夹对话框中选择的项目数量。 - 改进了鼠标/焦点事件监视函数。
- 修复了用户单击编辑框边缘时可能出现的绘图错误。
- 更改了绘图区域计算方法,以提高性能。
- 更新了源代码和演示项目。
2004 年 1 月 14 日
- 更新了
SetPathName
和GetPathName
成员函数。 - 修改了消息发送方法,使
lParam
现在是指向此CBrowseCtrl
对象的指针。 - 更新了源代码和演示项目。
2004年1月22日
- 添加了方法来监视用户是否手动更改了编辑框的内容(当设置了
BC_CTL_ALLOWEDIT
时)。GetPathName
的返回值也将正确受到影响。 - 现在可以通过调用
SetDialogTitle
和GetDialogTitle
来访问文件/文件夹对话框的窗口标题。 - 现在可以通过调用
SetDialogBanner
和GetDialogBanner
来访问文件夹对话框的横幅文本。 - 添加了方法
ModifyButtonStyle
以方便样式更改。
2004年2月7日
- 改进了绘图函数,以便在空间不足时部分绘制浏览按钮上的图像/文本。
2004年5月22日
- 更新了绘图函数。
- 添加了函数:
GetDriveLetter
,GetDirectory
,GetFileName
,GetFileTitle
,GetFileExt
。
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。