在 MFC CMenu 中绘制图标而不是位图?

Posted

技术标签:

【中文标题】在 MFC CMenu 中绘制图标而不是位图?【英文标题】:Drawing icons instead of bitmaps in a MFC CMenu? 【发布时间】:2008-11-06 12:29:20 【问题描述】:

我可以在菜单中使用位图

CMenu men;
CBitmap b;
b.LoadBitmap(IDB_0); 
men.AppendMenu( MF_ENABLED,1,&b);

我可以在 DC 中绘制图标

  CImageList IL;
  IL.Create(70, 14, ILC_COLOR16 | ILC_MASK, 1, 0);
  IL.Add(AfxGetApp()->LoadIcon(IDI_0));
  IL.Draw ( pDC,  0,  rcIcon.TopLeft(),  ILD_BLEND50 );

但我找不到在菜单中显示图标的简单方法。我想做这个

CMenu men;
CBitmap b;
// here the miracle happens, load the icon into the bitmap
men.AppendMenu( MF_ENABLED,1,&b);

这应该是可能的。


这与this 是同一个问题。但是这个问题涉及到 MFC 功能包,没有得到回答,并且一个月没有活动,所以我认为值得参考基本 MFC 再次询问。

【问题讨论】:

【参考方案1】:

我问了你提到的问题。

向菜单添加(普通,16 位颜色)图标的方法是制作一个工具栏,该工具栏的资源 ID 与您想要在其中包含图标的菜单相同。然后您将 ID 分配给每个工具栏按钮,即与菜单条目相同的 ID。制作一个由向导生成的新 MFC 应用程序,您将看到它是如何工作的。

我发布的问题的答案表明,对于功能包工具栏具有透明度的 32 位图像,它应该同样适用;不过我还没来得及测试它。

如果您的具体问题是如何制作动态生成的菜单,我认为您应该在工具栏中传递现有条目的 id,然后使用该图像。

不是对您问题的真正答案,但也许它会为您指明正确的方向。

【讨论】:

谢谢。这听起来可能会奏效。但是,它似乎相当复杂,尤其是因为我以前没有使用过工具栏。现在,我将坚持我目前的解决方法——为每个图像存储一个位图和一个图标。叹息!【参考方案2】:

好代码。请注意,这会显示位图图像,但如果您正在显示图像,最好删除字符串(用于检查/取消检查)留下的空格。 我确实喜欢这个。

        MENUINFO mi;
        mi.cbSize = sizeof(mi);
        mi.fMask = MIM_STYLE;
        mi.dwStyle = MNS_NOCHECK;
        pcSubMenu->SetMenuInfo(&mi);

        MENUITEMINFO mii;
        mii.cbSize = sizeof mii;
        mii.fMask = MIIM_BITMAP;

        mii.hbmpItem = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_16_HELP),IMAGE_BITMAP,0,0,LR_SHARED |LR_VGACOLOR |LR_LOADTRANSPARENT);
        pcSubMenu->SetMenuItemInfo(ID_CONTENTS,&mii,FALSE);

【讨论】:

【参考方案3】:

我认为您正在寻找的内容与此处描述的内容非常相似... www.codeguru.com/cpp/controls/menu/bitmappedmenus/article.php/c165/

与 www.codeproject.com/KB/shell/DynIcon.aspx 中的描述混合

还得看看能不能用。

驯服者

【讨论】:

【参考方案4】:

在 Windows Vista/Windows7 上你不能这样做,它要么是 32 BGRA 图像,要么是菜单不是以新的 UI 样式绘制的。没有解决方法,也许是 ownerdrawing,但我读到 style API 无法与菜单一起正常工作,所以我从未尝试过深入了解它。

无论如何你都应该使用 32 位 BGRA 图标。

【讨论】:

【参考方案5】:

为了为菜单设置位图,您需要为每个项目调用 CMenu::SetMenuItemInfo(),如下所示:

MENUITEMINFO mii;
mii.cbSize = sizeof mii;
mii.fMask = MIIM_BITMAP;
mii.hbmpItem = bitmapHandle;
menu.SetMenuItemInfo(menuItem,&mii,TRUE);

这样做的另一个复杂之处在于,这适用于 256 色位图,但不适用于全色 32 位 RGBA 位图 - 这些将起作用,但仅适用于 Vista,并且仅当您将位图呈现为预先计算的 RGBA 时。

在实践中,在我的代码中,我通过使用菜单图标的另一个功能来解决这个问题,即将 hbmpItem 设置为 HBMMENU_CALLBACK,它允许回调来绘制位图:我在 Windows XP 和之前的版本中这样做。代码有点太复杂,无法在此处发布。例如,您可以查看我的代码

http://www.ifarchive.org/if-archive/infocom/interpreters/frotz/WindowsFrotzSrc.zip

查看“MenuBar.h”和“MenuBar.cpp”,尤其是 MenuBar::SetBitmaps() 周围的代码。

【讨论】:

您似乎误读了这个问题。我知道如何在菜单中使用位图(使用更简单的方法,发布在我的问题中)。我希望通过同样简单的方法了解如何使用图标。

以上是关于在 MFC CMenu 中绘制图标而不是位图?的主要内容,如果未能解决你的问题,请参考以下文章

.ico文件看起来错误用DrawIcon绘制

MFC绘制一个心形

将 OpenGL 绘制到离屏位图

在 SDI MFC 中绘制方网

在 iOS 和 iPhone 上,如何绘制位图并在 drawRect 中显示?

在 MFC 中重绘时闪烁