XBreadCrumbBar - 使用超链接和 HTML 绘制面包屑导航





5.00/5 (21投票s)
XBreadCrumbBar 是一个无窗口、非 MFC 的类,它允许您以 HTML 文本格式显示面包屑导航,并支持 Web 链接和 APP: 链接。
引言
根据维基百科,
这是面包屑在网络上常用的方式
当然,谷歌也使用面包屑
面包屑的使用在网络上越来越普遍,并且也开始出现在 PC 应用程序中。Vista Windows Explorer 使用面包屑来显示您在文件系统中的位置。
面包屑导航似乎特别适合任何类型的分层系统,并且有两个目的:首先,显示您在分层结构中的位置;其次,允许您以随机访问的方式导航到分层结构中的前一个点——换句话说,您不必一直按“后退”按钮,只需单击第二个链接即可立即转到面包屑导航中的第二个位置。
虽然对面包屑导航的大多数研究都集中在网站上(请参阅参考文献),但在导航网站和导航非琐碎 PC 应用程序之间存在许多相似之处,特别是那些处理分层数据的应用程序——例如,人力资源系统、汽车零件订购系统以及用于呈现和选择课程表的软件。用户界面专家 Jakob Nielsen 有一篇关于面包屑的有趣博客。如果您将他博客中的“网站”一词替换为“PC 应用程序”,它仍然完全有意义。
面包屑导航似乎适合我最近参与的一个大型库存系统,并且在向客户展示时,他很喜欢这个想法。这导致了 XBreadCrumbBar 的创建,它基于XHtmlDraw。这在面包屑导航的视觉显示方面提供了额外的灵活性,并且还内置了对 Web 链接和APP: 链接的支持(有关更多详细信息,请参阅我的XHtmlDraw文章)。
XBreadCrumbBar 功能
首先,让我向您展示演示应用程序
以下是主要功能
- 无链接的面包屑显示静态面包屑导航,没有链接。文本使用粗体字体显示,分隔符也是如此。
- Web 链接的面包屑显示了链接的颜色,这些颜色是从我喜欢的图书网站复制过来的。最后一个面包屑颜色不同,且不是链接。请注意,面包屑是粗体的,而分隔符不是。
- APP: 链接的面包屑显示每个链接不同的颜色,鼠标悬停在第一个链接上。点击链接时,您会看到
XBreadCrumbBar 实现
CXBreadCrumbBar
类派生自 CXHtmlDraw
(可在本文中找到描述),并嵌入了链接处理类 CXHtmlDrawLink
(也在CXHtmlDraw 文章中进行了描述)。
以下是 CXBreadCrumbBar
类的一些函数
函数 | 描述 |
---|---|
int Draw(HWND hWnd, BOOL bUnderlineUrl, int index = -1) | 将 XBreadCrumbBar 绘制到 hWnd。如果 index = -1,则绘制所有面包屑,否则仅绘制指定索引的面包屑。 |
int Draw(HDC hdc, BOOL bUnderlineUrl, int index = -1) | 将 XBreadCrumbBar 绘制到 hdc。如果 index = -1,则绘制所有面包屑,否则仅绘制指定索引的面包屑。 |
BOOL GetBoldSeparator() | 获取分隔符的粗体标志状态 |
int GetCount() | 检索面包屑的数量 |
XHTMLDRAWSTRUCT * GetDrawStruct(int index) | 检索由索引指定面包屑的绘制结构 |
size_t GetCrumb(int index, BOOL bStripHtml, LPTSTR pszCrumb, size_t size) | 检索由索引指定面包屑的字符串。如果 pszCrumb 为 NULL,则仅返回面包屑的长度(以 TCHAR 为单位)。 |
int GetCrumb(LPCTSTR lpszCrumb, BOOL bStripHtml) | 检索字符串与 lpszCrumb 匹配的面包屑的索引 |
CXHtmlDrawLink * GetLinks() | 检索指向 CXHtmlDrawLink 对象的指针,该对象用于 Web 和 APP: 链接 |
int GetCrumbs(TCHAR *** crumbs) | 检索指向面包屑字符串指针数组的指针 |
TCHAR * GetSeparator() | 检索指向分隔符字符串的指针 |
CXBreadCrumbBar& InitDrawStruct(XHTMLDRAWSTRUCT * pXHDS, BOOL bBoldSeparator = TRUE) | 初始化绘制结构 |
int IsAnchorUnderlined() | 返回被下划线标记的面包屑的索引号,否则返回 -1 |
int IsOverAnchor(HWND hWnd) | 返回鼠标悬停其上的面包屑的索引号,否则返回 -1 |
BOOL RelayClick(HWND hWnd) | 将单击事件转发给 CXBreadCrumbBar |
void RelayMouseMove(HWND hWnd) | 将鼠标移动转发给 CXBreadCrumbBar |
CXBreadCrumbBar& SetAppCommands(XHTMLDRAW_APP_COMMAND * paAppCommands, int nAppCommands) | 设置 APP: 命令的表 |
CXBreadCrumbBar& SetBoldSeparator(BOOL bBold) | 设置分隔符粗体标志:如果为 TRUE,则分隔符在面包屑为粗体时也为粗体;如果为 FALSE,则即使面包屑为粗体,分隔符也不会为粗体。 |
CXBreadCrumbBar& SetCrumbs(const TCHAR * crumbs[], int count) | 从字符串数组设置面包屑字符串 |
CXBreadCrumbBar& SetCrumbs(LPCTSTR crumbs, TCHAR sepchar) | 从字符分隔的字符串设置面包屑字符串,其中字符由 sepchar 指定 |
CXBreadCrumbBar& SetSeparator(LPCTSTR lpszSep) | 设置分隔符字符串 |
如何使用
请按照以下步骤将 XBreadCrumbBar 集成到您的应用程序中
步骤 1:添加 XBreadCrumbBar 文件
将以下文件添加到您的项目中
- XBreadCrumbBar.cpp
- XBreadCrumbBar.h
- XHtmlDraw.cpp
- XHtmlDraw.h
- XHtmlDrawLink.cpp
- XHtmlDrawLink.h
- XNamedColors.cpp
- XNamedColors.h
- XString.cpp
- XString.h
步骤 2:定义持久的 CXBreadCrumbBar 对象
在演示应用程序中,在 XBreadCrumbBarTestDlg.h 中定义了三个 CXBreadCrumbBarM
对象
CXBreadCrumbBar m_ccb[3];
步骤 3:初始化 XHTMLDRAWSTRUCT 结构
XHTMLDRAWSTRUCT 结构
包含 XBreadCrumbBar 的格式化信息和屏幕位置。这是演示应用程序中的初始化函数
//================================================================= void CXBreadCrumbBarTestDlg::InitDrawStruct(int index) //================================================================= { ASSERT((index >=0) && (index < 3)); LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); CFont *pFont = GetFont(); // get font for the dialog if (pFont) pFont->GetLogFont(&lf); CWnd *pWnd = GetDlgItem(g_uStatic[index]); ASSERT(pWnd); CRect rect; pWnd->GetWindowRect(&rect); ScreenToClient(&rect); rect.DeflateRect(5, 5); rect.top += 10; CXBreadCrumbBar::XHTMLDRAWSTRUCT ds; ds.crText = m_rgbText; ds.nID = index; if (index == 0) ds.crText = RGB(119,121,118); if (index == 1) ds.crBackground = GetSysColor(COLOR_BTNFACE); else ds.crBackground = m_rgbBackground; ds.rect = rect; if (index != 2) ds.bBold = TRUE; else ds.bBold = FALSE; ds.bLogFont = TRUE; if (index == 0) _tcscpy(lf.lfFaceName, _T("Arial")); memcpy(&ds.lf, &lf, sizeof(LOGFONT)); if (index == 0) m_ccb[index].SetSeparator(_T(" > ")); // must set crumbs before calling CXBreadCrumbBar::InitDrawStruct switch (index) { default: case 0: // all crumbs in one string, separated by '~' m_ccb[index].SetCrumbs(SAMPLE_1, _T('~')); break; case 1: // array of 4 strings m_ccb[index].SetCrumbs(SAMPLE_2, 4); break; case 2: // array of 5 strings m_ccb[index].SetCrumbs(SAMPLE_3, 5); break; } // don't use bold separators in second bread crumb bar m_ccb[index].InitDrawStruct(&ds, (index == 1) ? FALSE : TRUE); }
步骤 4:初始化 APP: 命令
APP:
超链接允许您显示超链接文本,当用户单击它时,该文本会将 Windows 消息发送到指定的窗口。要使用 APP:
超链接,您必须设置APP: 命令表——这是演示应用程序中使用的表
CXHtmlDraw::XHTMLDRAW_APP_COMMAND AppCommands[] = { { m_hWnd, WM_APP_COMMAND_1, 1, _T("WM_APP_COMMAND1") }, { m_hWnd, WM_APP_COMMAND_2, 2, _T("WM_APP_COMMAND2") }, { m_hWnd, WM_APP_COMMAND_3, 3, _T("WM_APP_COMMAND3") }, { m_hWnd, WM_APP_COMMAND_4, 4, _T("WM_APP_COMMAND4") }, { m_hWnd, WM_APP_COMMAND_5, 5, _T("WM_APP_COMMAND5") }, };该表有五项,但您可以根据需要添加任意数量的条目。每项有四个元素:第一个是要接收消息的窗口的
HWND
;第二个是通过 SendMessage()
发送给窗口的数字消息编号;第三个是用户定义的数据,该数据将返回在 wParam 成员中;第四个是用于将表条目与 HTML 代码关联的字符串。设置此表后,通过调用 SetAppCommands()
将其传递给 CXBreadCrumbBarM
对象。
m_ccb[2].SetAppCommands(AppCommands, sizeof(AppCommands)/sizeof(AppCommands[0]));
如果面包屑是动态变化的,您可以根据需要多次调用 SetAppCommands()
。
步骤 5:跟踪鼠标移动
由于 CXBreadCrumbBar
是无窗口的,您必须添加代码将鼠标移动转发给 CXBreadCrumbBar
。这是演示应用程序中的 OnMouseMove()
函数
//============================================================================= void CXBreadCrumbBarTestDlg::OnMouseMove(UINT nFlags, CPoint point) //============================================================================= { for (int i = 0; i < 3; i++) m_ccb[i].RelayMouseMove(m_hWnd); CDialog::OnMouseMove(nFlags, point); }
步骤 6:处理鼠标单击
同样,由于 CXBreadCrumbBar
是无窗口的,您必须添加代码将单击转发给 CXBreadCrumbBar
。这是演示应用程序中的 OnLButtonUp()
函数
//============================================================================= void CXBreadCrumbBarTestDlg::OnLButtonUp(UINT nFlags, CPoint point) //============================================================================= { for (int i = 0; i < 3; i++) { if (m_ccb[i].RelayClick(m_hWnd)) break; } CDialog::OnLButtonUp(nFlags, point); }
参考文献
有关面包屑导航的信息链接
- 维基百科:面包屑导航
- 面包屑导航:使用情况的进一步研究
- 培训和接触对使用面包屑导航的影响
- Jakob Nielsen:面包屑导航越来越有用
- Keith Instone:位置、路径和属性面包屑
- 面包屑导航
- 汉赛尔和格蕾太尔
我用于演示应用程序的文章链接
- XHtmlDraw - 使用 HTML 标签和锚链接绘制文本
- XHyperLink - 又一个超链接控件
- XMessageBox - 反向工程的 MessageBox()
- XString - 非 MFC 非 STL 的字符串函数
修订历史
版本 1.0 - 2007 年 8 月 7 日
- 首次公开发布
用法
本软件已发布至公共领域。您可以随意使用它,但不得出售此源代码。如果您修改或扩展它,请考虑将新代码发布到此处供大家共享。本软件按“原样”提供,不附带任何明示或暗示的保证。对于本软件可能造成的任何损害或业务损失,本人概不负责。