在开发MFC应用程序时,经常需要在菜单项中添加图标,以便用户可以更直观地识别相关的工具栏命令。然而,传统的方法是使用位图资源,这些资源的大小通常被限制在13x13像素以内。这限制了图标的多样性和清晰度。本文将介绍一种方法,使用C++和MFC框架,将图标资源直接应用到菜单项中,而不需要特殊的资源或句柄。
最近,在项目中需要在菜单项中添加图标,以便用户可以轻松识别与工具栏命令相关的操作。查阅了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);
}
使用上述方法,只需要在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);
...
...
}