强大的拥有绘制菜单






4.92/5 (31投票s)
2001年10月24日
2分钟阅读

746312

9061
具有背景图片和图标阴影支持的 XP 风格拥有绘制菜单
 
  
 
一个功能齐全的自定义绘制菜单类
CMenuXP 是一个从 CMenu 派生的类,使用了自定义绘制技术。我将其命名为 MenuXP,因为我希望它看起来像 Office XP 和 Windows XP 中找到的菜单,但我未能实现这一点。我遇到的主要困难是将菜单的 3D 边框转换为平面边框,但我希望它仍然对您有用。
我从 Scribble 示例应用程序构建了这个类,并且部分绘制代码是从 CCoolMenuManager 类复制而来。此外,我还使用了 BCGControlBar 中的一个名为 CBCGKeyHelper 的类来显示加速键文本。
特点
- 带有图标的菜单,如 Office 97 中所示
- 弹出菜单的任何级别上的侧边栏
- 支持按钮式菜单项,例如在 Microsoft Office 套件的一些绘图工具栏中找到的
- 所有颜色、字体和大小都可以自定义
引言
菜单中的一个项目由 CMenuXPItem 类表示。一些进一步的类从它派生,提供方便的使用
- CMenuXPText表示带有文本和可选图标的普通菜单项
- CMenuXPSeparator表示分隔符
- CMenuXPSideBar表示弹出菜单左侧的侧边栏
- CMenuXPButton表示仅包含图标的按钮菜单项
了解这些将有助于您理解代码。
如何用作弹出菜单
- 构造一个 CMenuXP实例
- 调用 CreatePopupMenu
- 如果需要,使用 AddSideBar添加一个侧边栏
- 使用 AppendODMenu添加一些菜单项
- 如果有第二级弹出菜单,使用步骤 1 到 4 构建它,并使用 AppendODPopup将其添加到当前菜单
- 像往常一样调用 TrackPopupMenu
示例代码如下所示
void CMenuXPAppView::OnContextMenu(CWnd* pWnd, CPoint point)
{
	CMenuXP	*pMenu = new CMenuXP;
	pMenu->CreatePopupMenu();
	pMenu->AddSideBar(new CMenuXPSideBar(24, "MenuXP"));
	pMenu->AppendODMenu(0, new CMenuXPText(10, "First Item",
                               AfxGetApp()->LoadIcon(IDI_ICON1)));
	pMenu->AppendODMenu(0, new CMenuXPText(11, "Second Item",
                               AfxGetApp()->LoadIcon(IDI_ICON2)));
	pMenu->AppendODMenu(0, new CMenuXPText(12, "Another Item",
                               AfxGetApp()->LoadIcon(IDI_ICON3)));
	pMenu->AppendODMenu(0, new CMenuXPText(13, "No Icon"));
	CMenuXP *pPopup = new CMenuXP;
	pPopup->CreatePopupMenu();
	pPopup->AppendODMenu(0, new CMenuXPButton(21,
                                AfxGetApp()->LoadIcon(IDI_ICON4)));
	pPopup->AppendODMenu(0, new CMenuXPButton(22,
                                AfxGetApp()->LoadIcon(IDI_ICON5)));
	pPopup->AppendODMenu(0, new CMenuXPButton(23,
                                AfxGetApp()->LoadIcon(IDI_ICON6)));
	pPopup->Break();
	pPopup->AppendODMenu(0, new CMenuXPButton(24,
                                AfxGetApp()->LoadIcon(IDI_ICON7)));
	pPopup->AppendODMenu(0, new CMenuXPButton(25,
                                AfxGetApp()->LoadIcon(IDI_ICON8)));
	pPopup->AppendODMenu(0, new CMenuXPButton(26,
                                AfxGetApp()->LoadIcon(IDI_ICON9)));
	pPopup->Break();
	pPopup->AppendODMenu(0, new CMenuXPButton(27,
                                AfxGetApp()->LoadIcon(IDI_ICON10)));
	pPopup->AppendODMenu(0, new CMenuXPButton(28,
                                AfxGetApp()->LoadIcon(IDI_ICON11)));
	pPopup->AppendODMenu(0, new CMenuXPButton(29,
                                AfxGetApp()->LoadIcon(IDI_ICON12)));
	pMenu->AppendODPopup(0, pPopup, new CMenuXPText(0, "Popup",
                                AfxGetApp()->LoadIcon(IDI_ICON1)));
	pMenu->TrackPopupMenu(TPM_LEFTBUTTON, point.x, point.y, this);
	delete pMenu;
}
在堆上构造的对象将自动销毁,除了需要手动销毁的顶级弹出菜单。
请记住在您的父窗口的 WM_MEASUREITEM 处理程序中添加以下代码
void CMenuXPAppView::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
	// TODO: Add your message handler code here and/or call default
	HMENU hMenu = AfxGetThreadState()->m_hTrackingMenu;
	CMenu	*pMenu = CMenu::FromHandle(hMenu);
	pMenu->MeasureItem(lpMeasureItemStruct);
	CView::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}
就这样了,希望这对您有用。欢迎提交错误报告和改进建议。
许可证
本文没有明确的许可证附加到它,但可能包含在文章文本或下载文件本身中的使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。
