MFC中菜单项的动态添加、删除与响应

原创 2004年10月28日 22:40:00
    在编写游戏地图编辑器时涉及到菜单项的动态添加和动态响应,本文记录了碰到的一些问题和解决方法。
    因为游戏地图是分层次存储和显示的,所以在编辑器主菜单中有个Layer菜单,这个菜单中的菜单项除了一个"Show Only"菜单项和一个Sperator,其它的菜单项是根据地图中的层数和层的名字动态添加的,所以在编译期无法知道菜单项的个数,也无法用ON_COMMAND宏将这些菜单项与命令处理函数相关联。本来还有一个ON_COMMAND_RANGE宏,可以将某个范围内的ID与一个Command Handler相关联,但是这样的话,我必须在这个宏中指定最大的ID号。因为我不知道实际的地图到底会有多少层,所以我不想让动态添加的菜单项在ID上有个上限。
    Layer菜单的第一个菜单项是"Show Only",它响应了UPDATE_COMMAND_UI消息,我在这个响应函数里先删除"Show Only"之后的所有菜单项,然后检查地图实际有多少层,取得地图各层的名字,再根据实际的层数添加菜单项。
    删除菜单项的代码如下:
nItemCount = pLayerMenu->GetMenuItemCount();
for (i = 2;i < nItemCount;i++)
{
    pLayerMenu->DeleteMenu(i,MF_BYPOSITION);
}
    这样删除的话就有问题。因为我是根据菜单项的位置来删除的,而每执行一次
pLayerMenu->DeleteMenu(i,MF_BYPOSITION)就少一个菜单项,其后的菜单项的位置偏移就会减一,最后删除的结果就非我所预期的了。
    解决办法是用MF_BYCOMMAND根据ID来删除,或者
nItemCount = pLayerMenu->GetMenuItemCount();
for (i = 2;i < nItemCount;i++)
{
    pLayerMenu->DeleteMenu(2,MF_BYPOSITION);
}
这样我就能保证删除所有上一次动态添加上去的菜单项了。
    动态添加菜单项我是这样做的:
nLayerCount = pMaterialDoc->GetLayerCount();
for (i = 0;i < nLayerCount;i++)
{
    pLayerMenu->AppendMenu(
                MF_STRING | MF_ENABLED | MF_CHECKED,
                ID_LAYER_SHOW_ONLY + i + 1,
                pMaterialDoc->GetLayerName(i));
}
但是这样添加上去的菜单项全是灰色的,即使我用了MF_ENABLED选项。因为MFC
中会自动地让没有Command Handler与之对应的菜单项变灰。这是由CFrameWnd中的
m_bAutoMenuEnable变量控制的,它为true时,MFC做确定菜单项是否应该变灰的工作,为false时,由我们自己做。我只希望我动态添加的菜单项全部是Enabled的,其它菜单的Enable问题还是由MFC来处理。那我应该怎么办呢?
    通过跟踪MFC源码我得知,MFC确定一个Command ID是否有Handler与之对应是通过调用OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) 然后根据返回值来确定的。返回值为true, 表示有对应的处理函数,返回值为false,表示没有。那MFC如何保证在检测一个Command ID是否有Handler时,不会无谓地调用这个Handler呢?注意第四个参数pHandlerInfo,当pHandlerInfo不为NULL时,表示是在检测,当其为NULL时,表示是真的在路由这个命令消息,希望能得到处理。
    我重载了GMapView(继承自CView,用来显示游戏地图)的OnCmdMsg(...)函数,因为我想在GMapView中处理这些动态添加的菜单项。
nMaxPos = pLayerMenu->GetMenuItemCount() - 1;
if (0 == nCode)
{
    if (pLayerMenu->GetMenuItemID(2) <= nID
       && nID <= pLayerMenu->GetMenuItemID(nMaxPos))
    {
        if (NULL == pHandlerInfo)
        {
            handler();
        }
        return true;
    }
}
return CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

    nCode为0表示是命令消息,为-1就表示是UPDATE_COMMAND_UI消息。我在动态添加菜单项时让它们的ID顺序递增,这样方便处理。

VC中菜单项命令的响应顺序

VC的菜单项命令响应顺序为:视类、文档类、框架类,最后是程序类。可以给同一个菜单项在MFC ClassWizard中Class Name中选择不同的类,分别添加响应函数(如显示一个对话框)进行测试。...
  • guoqingchun
  • guoqingchun
  • 2013年03月22日 16:09
  • 732

Android上去掉系统菜单栏,删除SystemUI.apk

项目需求:启动平板后,启动我的应用程序后,去掉系统自带的菜单栏,如:返回,主页,等等。 空气净化器的UI控制端,屏蔽系统自带的可见的home,返回键等菜单。 硬件设备:使用aigo M60 平板。...
  • keezhong
  • keezhong
  • 2013年12月24日 14:12
  • 2210

MFC中菜单项状态的切换

MFC中的菜单项中左边可以有一个是否选中的状态,注意不是让菜单项变灰,而是在菜单项左边出现一个钩,要实现这个效果,需要进行下面这几步操作。 1.首先在菜单项的资源文件中将属性Checked置为true...
  • u012501459
  • u012501459
  • 2014年01月06日 14:53
  • 1548

动态修改smartphone中菜单项

定义菜单IDR_MAINFRAME,两个子菜单IDM_ACTION,IDM_MENUIDR_MAINMENU RCDATABEGIN   IDR_POPUP,   2,   I_IMAGENONE, ...
  • procedurecode
  • procedurecode
  • 2007年11月05日 14:36
  • 1028

关于MFC中菜单项的使用一点解决方法

在使用MFC结合OpenGL进行图形绘制的时候,按照教程上面的一步一步的进行编写程序,可是在编写完成后,总是出现以下问题: --------------------Configuration: CY...
  • hand9162012
  • hand9162012
  • 2013年03月04日 11:10
  • 369

MFC中动态创建控件以及事件响应实现方法

本文实例讲述了MFC中动态创建控件以及事件响应实现方法,分享给大家供大家参考。具体实现方法如下: 动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的。 一、创建...
  • Qsir
  • Qsir
  • 2017年06月07日 12:17
  • 869

【MFC】基于对话框的键盘响应

VC中键盘事件处理主要是通过对相应的消息的响应,这些事件有如:WM_CHAR、   WM_KEYDOWN、WM_KEYUP等他们分别对应OnChar、OnKeyDown、OnKeyUp消息处  ...
  • zdhlwt2008
  • zdhlwt2008
  • 2015年06月30日 13:12
  • 2478

MFC中消息响应机制

由于视类窗口始终覆盖在框架类窗口之上,因此所有操作,包括鼠标单击、鼠标移动等操作都只能由视类窗口捕获。一个MFC消息响应函数在程序中有三处相关信息:函数原型、函数实现和以及用来关联消息和消息响应函数的...
  • silenough
  • silenough
  • 2011年11月07日 11:11
  • 4433

MFC-菜单的动态(增加 插入 删除 响应)

增加菜单 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { CMenu menu; menu.CreateMenu();//新...
  • nvcgkk
  • nvcgkk
  • 2016年12月17日 17:27
  • 863

VC动态创建工具栏及工具栏上的按钮及为按钮添加消息响应函数

// OnInitDialog函数中 //向列表中添加图标 m_imagelist.Create(32,32,ILC_COLOR24|ILC_MASK,1,1); m_imagelist.Add(Af...
  • nanhaizhixin
  • nanhaizhixin
  • 2010年10月01日 22:44
  • 6317
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MFC中菜单项的动态添加、删除与响应
举报原因:
原因补充:

(最多只允许输入30个字)