MFC中CMenu类的问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC中CMenu类的问题相关的知识,希望对你有一定的参考价值。
Create a CMenu object on the stack frame as a local, then call CMenu’s member functions to manipulate the new menu as needed. Next, call CWnd::SetMenu to set the menu to a window, followed immediately by a call to the CMenu object’s Detach member function. The CWnd::SetMenu member function sets the window’s menu to the new menu, causes the window to be redrawn to reflect the menu change, and also passes ownership of the menu to the window. The call to Detach detaches the HMENU from the CMenu object, so that when the local CMenu variable passes out of scope, the CMenu object destructor does not attempt to destroy a menu it no longer owns. The menu itself is automatically destroyed when the window is destroyed.
这段话表达的含义是什么?英文我倒是看得懂,就是不知道表达的什么意思?比如句柄和CMenu对象为什么要断开呢?析构和窗口销毁不是一个意思吗?里面的关系我捋不顺。谢谢各位大大回答!
最主要的是成员函数Detach,如果你定义了一个局部的CMenu对象,建立了一个菜单,当这个对象的生命周期结束时析构函数就会销毁这个菜单(我们当然不希望这样),而Detach则能将菜单的句柄和CMenu对象断开,这样对象的生命周期结束时菜单也不会销毁,而是当这个窗口销毁时菜单才销毁、、
在 MFC CMenu 中绘制图标而不是位图?
【中文标题】在 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类的问题的主要内容,如果未能解决你的问题,请参考以下文章
在MFC中,CMenu如何使用,比如点击开始,下面有新建,打开,保存等……