位图菜单
一种无需位图资源或属主绘制即可拥有位图菜单的简单方法
引言
本文档展示了如何使用 CMenu::SetMenuItemBitmaps()
方法为任何菜单项设置位图,而无需特殊的资源或处理 CMenu::DrawItem
、CMenu::MeasureItem
。此外,您可以使用图标代替位图资源或图像列表。
背景
最近,我需要为菜单项添加一些图标,以便用户可以轻松识别关联的工具栏命令... 我查阅了 MSDN 帮助文档,看到了一个小的示例 此处... 但这些方法只能接受位图资源,并且这些资源必须裁剪为 13X13 像素... 我在 CodeProject 上搜索了所有者绘制菜单,找到了一些不错的示例,但一旦使用了所有者绘制处理程序,我就在操作系统样式上遇到了问题(考虑到我将项目与另一个控件一起放弃了)。
但几乎任何项目都有图标资源(无论尺寸如何),我想知道,如果我可以使用 CMenu::SetMenuItemBitmaps
将图标放在菜单项上会怎么样?为了完成这个目标,我设计了一个图标到位图的转换方法,如下所示
CBitmap* CMainFrame::ConvertIconToBitmap(HICON hIcon)
{
CDC dc;
CBitmap bmp;
CClientDC ClientDC(this);
dc.CreateCompatibleDC(&ClientDC);
bmp.CreateCompatibleBitmap(&ClientDC, 13, 13);
CBitmap* pOldBmp = (CBitmap*)dc.SelectObject(&bmp);
::DrawIconEx(dc.GetSafeHdc(), 0, 0, hIcon, 13, 13, 0, (HBRUSH)RGB(255, 255, 255), DI_NORMAL);
dc.SelectObject(pOldBmp);
dc.DeleteDC();
HBITMAP hBitmap = (HBITMAP)::CopyImage((HANDLE)((HBITMAP)bmp),
IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
return CBitmap::FromHandle(hBitmap);
}
Using the Code
从上面的方法可以看出,您只需要在 OnInitMenuPopup
处理程序中初始化菜单,并使用 CMainFrame::ConvertIconToBitmap
将图标加载到菜单中
void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
CMDIFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
// TODO: Add your message handler code here
HICON hIcon = AfxGetApp()->LoadIcon(IDR_TESTMETYPE);
pPopupMenu->SetMenuItemBitmaps(ID_FILE_NEW,MF_BYCOMMAND,ConvertIconToBitmap(hIcon),NULL);
...
...
}
关注点
这个解决方案可以作为 CMenu
派生控件的一个简单替代方案。希望您喜欢!
历史
- 2012年6月21日:初始版本
- 2015年4月24日:更新了 ConvertIconToBitmap 方法,以提高位图质量。