MZCrumbBar - 通用面包屑控制器






4.95/5 (46投票s)
一个通用的 MFC 面包屑导航控件,显示可点击的面包屑列表。
引言
我需要一个类似 Windows Vista 中的面包屑导航条,以便显示路径并且可以点击路径。但是我也需要在另一个项目中使用面包屑导航条,它与文件路径无关。所以我构建了这个通用的 CrumbBar
控件。它可以显示任何带有分隔符的字符串作为面包屑导航条。
特点
- 任何带有分隔符的字符串都可以显示为面包屑导航条
- 如果被点击,可以进入编辑模式(可配置哪些点击会使其变为可编辑的)。
- 发送关于哪个项目被点击的通知。可以为所有三个鼠标按钮的单次和双击发送通知。
- 如果不是所有的面包屑项目都适合在控件中显示,则支持“返回”项目。
- 支持左边距和项目间距。
- 支持渐变背景。
- 可以很容易地进行自定义绘制,以实现您自己绘制面包屑项目。
创建控件
将 MZCrumbBar
添加到对话框
- 在您想要放置它的布局中添加一个自定义控件。
- 将属性的 ID 设置为类似
IDC_CRUMBBAR
的值。 - 属性中的类名必须是 "
MZCrumbBarCtrl
"。 - 然后设置你想要的样式标志,比如 0x50810001。如果你不想要任何边框 (
WS_BORDER
),从这个值中移除 0x00800000。 - 然后向您的对话框类添加一个
MZCrumbBar
变量。 - 为了将对话框布局中的自定义控件与
m_CrumbBar
变量连接起来,您需要在DoDataExchange
中添加一些代码 - 然后在
OnInitDialog()
中配置您想要的控件。
void CCrumbBarDemoDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_CRUMBBAR, m_CrumbBar);
}
配置
以下是控件何时应进入编辑模式的选项。 将它们设置为 Create
中的 StyleEx
标志,或使用 MZCrumbBar::Style(...)
。
#define CRU_EDITOUTSIDE 0x00000010 // Click must be outside of crumb items.
#define CRU_EDITONCLK_L 0x00000100 // Enter Edit mode on Left Click
#define CRU_EDITONDBL_L 0x00000200 // Enter edit mode on Left DblClick
#define CRU_EDITONCLK_R 0x00000400 // Enter Edit mode on Right Click
#define CRU_EDITONDBL_R 0x00000800 // Enter edit mode on Right DblClick
#define CRU_EDITONCLK_M 0x00001000 // Enter Edit mode on Middle Click
#define CRU_EDITONDBL_M 0x00002000 // Enter edit mode on Middle DblClick
#define CRU_LASTITEMCOLD 0x00010000 // Show no hover action for the last item
#define CRU_LASTITEMNOCLK 0x00020000 // Do not generate click action for the last item
#define CRU_LASTITEMNODELIMITER 0x00040000 // Do not draw a delimiter for the last item
#define CRU_DONOTSTRIPDELIMITER 0x00080000 // Do not strip double delimiter
用于配置分隔符应如何显示的标志(通过 DelimiterMode(...)
函数设置选项)
#define DM_STRIP 0 // Strip the delimiter char
#define DM_LEFT 1 // Show Delimiter in the Left part
#define DM_RIGHT 2 // Show Delimiter in the right part
设置颜色和边距
m_CrumbBar.ColorDefault( RGB(255, 0, 0));
m_CrumbBar.ColorHot( RGB(255, 0, 0));
m_CrumbBar.BackgroundColor( RGB(255, 0, 0), RGB(0,0,0), true);
m_CrumbBar.Margin(10);
m_CrumbBar.ItemSpacing(6);
使用面包屑导航条
// Initializing the CrumbBar.
m_CrumbBar.Path(_T("C:\\MyFolder\\SubFiles1\\SubFolder2\\"));
m_CrumbBar.Delimiter(_T("\\"));
m_CrumbBar.DelimiterMode(DM_RIGHT);
// Create a PreItem and set the preitem to "..\\"
MZCrumbBar::CrumbBarItem PreItem(_T(""), _T("..\\"));
m_CrumbBar.PreItem(PreItem);
// Rebuild/Update the CrumbBar.
m_CrumbBar.BuildCrumbbar();
// Get The Complete path.
CString path = m_crumbBar.Path();
// Get the path up to and including a specific CrumbBar item.
CString path = m_crumbBar.GetPath( pCrumbBarItem );
Notifications
有一些通知消息用于在发生事情时通知所有者窗口
#define NMCB_LBCLICK 1000 // User clicked with Left Mouse Button
#define NMCB_RBCLICK 1001 // User clicked with Right Mouse Button
#define NMCB_MBCLICK 1002 // User clicked with Middle Mouse Button
#define NMCB_LBDBLCLICK 1003 // User double clicked with Left Mouse Button
#define NMCB_RBDBLCLICK 1004 // User double clicked with Right Mouse Button
#define NMCB_MBDBLCLICK 1005 // User double clicked with Middle Mouse Button
#define NMCB_EDITCHANGE 1010 // User changed path by editing it
要捕获通知消息,您可以在对话框中执行此操作
// in .h file
afx_msg void OnCrumbBarItemClicked(NMHDR *pNotifyStruct, LRESULT* pResult) ;
// in .cpp file
BEGIN_MESSAGE_MAP(CCrumbBarDemoDlg, CDialog)
ON_NOTIFY( NMCB_LBCLICK, IDC_CRUMBBAR , OnCrumbBarItemClicked)
END_MESSAGE_MAP()
void CCrumbBarDemoDlg::OnCrumbBarItemClicked(NMHDR* pNotifyStruct, LRESULT* pResult)
{
NM_CRUMBBARITEM* pnmCrumbBarItem = (NM_CRUMBBARITEM*)pNotifyStruct;
// CrumbBar Item that was clicked
pnmCrumbBarItem->pCrumbBarItem;
// CrumbBar Path for clicked item
pnmCrumbBarItem->strCrumbPath;
// Mouse position when click happen.
// used for example to show a context menu with sub folder,
// like Explorer in Windows Vista
pnmCrumbBarItem->pt;
...
}
自定义绘制面包屑导航条项目
要将 CrumbBar
更改为自定义外观,您需要重写几个函数。
// Return the width of the crumbbar item.
virtual int OnMeasureItem(CDC* pDC, CrumbBarItem* pItem);
// Return width if the PreItem (item that is shown at the beginning,
// if not all crumbbar items can be drawn)
virtual int OnMeasurePreItem(CDC* pDC);
// Draw CrumbBar Item
virtual void DrawCrumbItem(CrumbBarItem* pItem, CDC* pDC, CRect rc);
// Draw PreItem
virtual void DrawPreItem(CrumbBarItem* pItem, CDC* pDC, CRect rc);
查看演示应用程序源中的 *CBlockCrumbBar.h*/*.cpp*,看看它是如何完成的。
致谢
- 从 CLabel by Norm.net 借用了渐变代码
历史
有关完整历史记录,请查看 *MZCrumbBar.cpp* 中的标头。
- v1.3: 2010-11-13
- 添加了新标志
CRU_DONOTSTRIPDELIMITER
,它将保留双分隔符。 - 双分隔符用于告诉
MZCrumbarCtrl
,当它看到分隔符时,它不应该中断路径。 - v1.2: 2010-04-15
- 添加了 Iain Clarke 提供的改进/修复
- 针对特殊情况的另外三个
BuildCrumbbar(...)
函数。 - 重构了路径的解析方式。
- 添加了
CRU_LASTITEMNODELIMITER
。 如果设置了样式,则不会为最后一个面包屑导航条项目显示分隔符。 - 现在可以使用
styleEx
设置样式。 - 将默认热颜色更改为
COLOR_HOTLIGHT
。 - 添加了在面包屑导航条项目中存储自定义数据的可能性。
- 添加了自定义数据的
SetItemData
/GetItemData
到面包屑导航条项目。 - 修复了双分隔符现在可以再次工作的问题。 双分隔符应该是面包屑路径名称的一部分,而不是拆分路径。
- 更改为通过虚函数
AddCrumbItem(...)
将项目添加到m_vCrumbItems
。 - 修复了不将空路径部分添加到路径的问题。
- v1.1 - 2010-03-17 - 第一个公共版本。修复了小的绘图问题。
- v1.0 - 2009-10-10 - 第一个版本。
例如:“Main-Sub-Sub--Menu” -> 最后一个项目通常显示为“Sub-Menu”,但使用此标志,它显示为“Sub--Menu”。 由于双分隔符未被剥离,例如“\\Server\Share\Folder” -> 第一个项目现在将显示为“\\Server”而不是“\Server”。