65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (54投票s)

2004年1月9日

5分钟阅读

viewsIcon

293698

downloadIcon

7864

一个集成了编辑框和带内置图像按钮的文件/文件夹浏览控件

Sample Image - CBrowseCtrl.gif

引言

通常,当我们需要为项目添加文件/文件夹浏览功能时,需要做很多琐碎的工作:首先,我们必须创建一个 CEdit 来显示路径名,然后,我们需要创建一个 CButton 并处理其 ON_BN_CLICKED 事件来启动 CFileDialog 并将路径名复制到 CEdit。此外,如果我们想让它看起来漂亮,还需要包含一些图标或位图资源来装饰 CButton。如果多个对话框都需要文件/文件夹浏览功能,这可能会让人头疼。

我一直在想,如果 MFC 中有一个控件,它集成了 CEditCButton,处理控件事件,弹出 CFileDialog 并自动更新 CEdit 文本,那该多好。如果该控件还有一些内置图像,也就是说,它有自己的绘图能力,不需要我们提供任何图像资源,那就更好了。当然,一些工具提示也没什么坏处……不幸的是,MFC 中没有这样的控件,但幸运的是,我们可以自己做一个。

CBrowseCtrl 就是为了满足我上面段落中描述的精确需求而创建的。它派生自 CButton,上面有一个编辑框、一个浏览按钮和一个工具提示。它还可以在浏览按钮上绘制一些内置图像,因此您无需为此控件包含任何图标或位图资源。它自己处理按钮事件,因此每当用户单击浏览按钮时,都会弹出文件/文件夹对话框。

如何使用

您需要先将源文件 BrowseCtrl.hBrowseCtrl.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,要么是 IDCANCELlParam 是指向此 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 日

  • 更新了 SetPathNameGetPathName 成员函数。
  • 修改了消息发送方法,使 lParam 现在是指向此 CBrowseCtrl 对象的指针。
  • 更新了源代码和演示项目。

2004年1月22日

  • 添加了方法来监视用户是否手动更改了编辑框的内容(当设置了 BC_CTL_ALLOWEDIT 时)。GetPathName 的返回值也将正确受到影响。
  • 现在可以通过调用 SetDialogTitleGetDialogTitle 来访问文件/文件夹对话框的窗口标题。
  • 现在可以通过调用 SetDialogBannerGetDialogBanner 来访问文件夹对话框的横幅文本。
  • 添加了方法 ModifyButtonStyle 以方便样式更改。

2004年2月7日

  • 改进了绘图函数,以便在空间不足时部分绘制浏览按钮上的图像/文本。

2004年5月22日

  • 更新了绘图函数。
  • 添加了函数:GetDriveLetter, GetDirectory, GetFileName, GetFileTitle, GetFileExt

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.