孙鑫视频---菜单

菜单的工作原理及编写应用,菜单命令消息在MFC框架程序的几个类中的传递顺序和处理过程

标记菜单、缺省菜单的实现原理、图形菜单的实现及常犯错误的分析,GetSystemMetrics的应用,快捷弹出菜单的实现方式及其命令响应函数有效范围(与弹出菜单时所指定的父窗口有密切的关系,最底层的子窗口具有最优先的处理机会)

动态菜单的编写,如何让程序在运行时产生新的菜单项及如何手工为这些新产生的菜单命令安排处理函数,如何在顶层窗口中截获对菜单命令的处理,更进一步掌握CString类的应用

在菜单上增加自己的菜单

在资源文件中打开相应文件夹

在帮助后新增加一个Test菜单

弹出菜单不能够用来做命令响应的,即popup属性为True

所以将Test菜单编辑器中Popup的属性改为false,就可以定义ID了,M代表是menu,菜单的意思

然后进行命令响应

在CMainFrame中增加类向导,为ID为IDM_TEST增加COMMAND处理

接在在View类、APP类、文档类当中分别添加相同的处理函数

结果在点击菜单Test时,最先弹出的是View类中的响应函数,其余都没有弹出

接着删除View类中的响应函数,点击菜单Test时,弹出的是文档类中的响应函数

然后删除文档中的响应函数,点击菜单时,弹出的MainFrame类中的响应函数

最后响应的是应用程序类

View--->文档类--->MainFrame--->app

消息的分类

标准消息

               除WM_COMMAND之外,所有以WM_开头的消息。 从CWnd派生的类,都可以接收到这类消息。

命令消息

               来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。 从CCmdTarget派生的类,都可以接收到这类消息。

通告消息

              由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现。 从CCmdTarget派生的类,都可以接收到这类消息。

    //给选项前画√
    //GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED);
    //GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND | MF_CHECKED);

    //缺省菜单项,以粗体显示,一个子菜单只能有一个缺省菜单
    //GetMenu()->GetSubMenu(0)->SetDefaultItem(1,TRUE);
    GetMenu()->GetSubMenu(0)->SetDefaultItem(ID_FILE_OPEN);
    GetMenu()->GetSubMenu(0)->SetDefaultItem(5,TRUE);

    //创建图形菜单
    CString str;
    str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),GetSystemMetrics(SM_CYMENUCHECK));
    //MessageBox(str);
    m_bitmap.LoadBitmap(IDB_BITMAP1);
    GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION,&m_bitmap,&m_bitmap);

    //屏蔽功能操作
    GetMenu()->GetSubMenu(0)->EnableMenuItem(1,MF_BYPOSITION | MF_DISABLED | MF_GRAYED);


    //移除菜单
    SetMenu(NULL);

    CMenu menu;
    menu.LoadMenu(IDR_MAINFRAME);
    SetMenu(&menu);
    menu.Detach();

命令更新

菜单项状态的维护是依赖于CN_UPDATE_COMMAND_UI消息,谁捕获CN_UPDATE_COMMAND_UI消息,MFC就在其中创建一个CCmdUI对象。

我们可以通过手工或利用ClassWizard在消息映射中添加ON_UPDATE_COMMAND_UI宏来捕获CN_UPDATE_COMMAND_UI消息。

在后台所做的工作是:操作系统发出WM_INITMENUPOPUP消息,然后由MFC的基类如CFrameWnd接管。它创建一个CCmdUI对象,并与第一个菜单项相关联,调用对象的一个成员函数DoUpdate()。

这个函数发出CN_UPDATE_COMMAND_UI消息,这条消息带有指向CCmdUI对象的指针。同一个CCmdUI对象就设置为与第二个菜单项相关联,这样顺序进行,直到完成所有菜单项。

更新命令UI处理程序仅应用于弹出式菜单项上的项目,不能应用于永久显示的顶级菜单项目。

注意:VS2010中GetMenu()引发异常解决方法

原文地址:https://www.cnblogs.com/yangyuqing/p/10251563.html