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

MZCrumbBar - 通用面包屑控制器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (46投票s)

2010年3月17日

CPOL

3分钟阅读

viewsIcon

70800

downloadIcon

1816

一个通用的 MFC 面包屑导航控件,显示可点击的面包屑列表。

MZCrumbBarDemo

引言

我需要一个类似 Windows Vista 中的面包屑导航条,以便显示路径并且可以点击路径。但是我也需要在另一个项目中使用面包屑导航条,它与文件路径无关。所以我构建了这个通用的 CrumbBar 控件。它可以显示任何带有分隔符的字符串作为面包屑导航条。

特点

  • 任何带有分隔符的字符串都可以显示为面包屑导航条
  • CrumbBar showing a none file path

  • 如果被点击,可以进入编辑模式(可配置哪些点击会使其变为可编辑的)。
  • Go into edit mode if clicked on

  • 发送关于哪个项目被点击的通知。可以为所有三个鼠标按钮的单次和双击发送通知。
  • 如果不是所有的面包屑项目都适合在控件中显示,则支持“返回”项目。
  • Go into edit mode if clicked on

  • 支持左边距和项目间距。
  • 支持渐变背景。
  • 可以很容易地进行自定义绘制,以实现您自己绘制面包屑项目。
  • Custom draw of crumbbar items

创建控件

MZCrumbBar 添加到对话框

Custom Control Properties

  1. 在您想要放置它的布局中添加一个自定义控件。
  2. 将属性的 ID 设置为类似 IDC_CRUMBBAR 的值。
  3. 属性中的类名必须是 "MZCrumbBarCtrl"。
  4. 然后设置你想要的样式标志,比如 0x50810001。如果你不想要任何边框 (WS_BORDER),从这个值中移除 0x00800000。
  5. 然后向您的对话框类添加一个 MZCrumbBar 变量。
  6. 为了将对话框布局中的自定义控件与 m_CrumbBar 变量连接起来,您需要在 DoDataExchange 中添加一些代码
  7. void CCrumbBarDemoDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
        DDX_Control(pDX, IDC_CRUMBBAR, m_CrumbBar);
    }
  8. 然后在 OnInitDialog() 中配置您想要的控件。

配置

以下是控件何时应进入编辑模式的选项。 将它们设置为 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;

    ...
}

自定义绘制面包屑导航条项目

Custom draw of crumbbar items

Custom draw of crumbbar items

要将 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,当它看到分隔符时,它不应该中断路径。
    • 例如:“Main-Sub-Sub--Menu” -> 最后一个项目通常显示为“Sub-Menu”,但使用此标志,它显示为“Sub--Menu”。 由于双分隔符未被剥离,例如“\\Server\Share\Folder” -> 第一个项目现在将显示为“\\Server”而不是“\Server”。

  • 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 - 第一个版本。
© . All rights reserved.