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

位图菜单

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.96/5 (13投票s)

2012年6月21日

CPOL

1分钟阅读

viewsIcon

46155

downloadIcon

2211

一种无需位图资源或属主绘制即可拥有位图菜单的简单方法

引言

本文档展示了如何使用 CMenu::SetMenuItemBitmaps() 方法为任何菜单项设置位图,而无需特殊的资源或处理 CMenu::DrawItemCMenu::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 方法,以提高位图质量。
© . All rights reserved.