MFC菜单命令更新机制---用该机制实现 Enable or Disable  MenuItem

方法:
1)用资源中的菜单项"剪切"的ClassWizard添加一个UPDATE_COMMAND_UI消息响应函数 
   void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI) 
   同时发现MFC在MainFrm.cpp的消息映射代码处添加了一个宏:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut) //关联CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI) 的宏 
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

MFC就是由消息映射表中的宏来调用关联的消息响应函数,对消息做出响应.
  
2) 在消息响应函数OnUpdateEditCut(CCmdUI* pCmdUI)中:
     pCmdUI->Enable(true); //就可以Enable "剪切",由灰色变成激活了.

//

//---

因为工具栏上的剪刀图标的index并不等于2,工具栏这个横条是一个整体,剪刀的index=4

------> 0,1,2(保存),3(分隔条),4(剪刀)

//---

//---

//---

菜单和工具栏图标都激活: 最简单就是不要用if()判断,直接Enable
  pCmdUI->Enable(true);

//--- 代码都是在CMainFrame的MainFrm.cpp中干活,为什么不在CMenuVie类,CMenuDoc类中干活? 其实都可以.

OnTest中实验COMMAND的响应顺序是CMenuView--->CMenuDoc--->CMainFrame--->CMenuApp..

在这里做了个实验:

(1)如果CMenuDoc中添加了void CMenuDoc::OnUpdateEditCut(CCmdUI* pCmdUI) ,虽然CMainFrame也有void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)

但是后者不会被调用了.

(2)  CMenuDoc::OnUpdateEditCut是被调用的消息处理函数,但是它没有 pCmdUI->Enable(true),因此"剪切"子菜单项还是个灰色的.

void CMenuDoc::OnUpdateEditCut(CCmdUI* pCmdUI) 
{
// TODO: Add your command update UI handler code here    
}

// MainFrm.cpp : implementation of the CMainFrame class
//#include "stdafx.h"
#include "Menu.h"#include "MainFrm.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/
// CMainFrameIMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)//{{AFX_MSG_MAP(CMainFrame)ON_WM_CREATE()ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut) //关联CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI) 的宏 //}}AFX_MSG_MAP
END_MESSAGE_MAP()static UINT indicators[] =
{ID_SEPARATOR,           // status line indicatorID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,
};/
// CMainFrame construction/destructionCMainFrame::CMainFrame()
{// TODO: add member initialization code here// m_bAutoMenuEnable =false; //改回false. 下面用MFC菜单命令更新机制来处理菜单.}CMainFrame::~CMainFrame()
{
}int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{if (CFrameWnd::OnCreate(lpCreateStruct) == -1)return -1;if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)){TRACE0("Failed to create toolbar\n");return -1;      // fail to create}if (!m_wndStatusBar.Create(this) ||!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT))){TRACE0("Failed to create status bar\n");return -1;      // fail to create}// TODO: Delete these three lines if you don't want the toolbar to//  be dockablem_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);//------ 子菜单项勾选函数CheckMenuItem//MenuItem:菜单项就是子菜单下面的各个选项,如"新建","打开","保存"等等.
//  GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION|MF_CHECKED);通过索引0访问"新建"菜单项MenuItem
//  GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND|MF_CHECKED);//通过命令ID访问"新建"菜单项MenuItem//------ 子菜单项设置为默认函数SetDefaultItem
//  GetMenu()->GetSubMenu(0)->SetDefaultItem(0,true);//第二个参数是true,则第一个参数用索引
//  GetMenu()->GetSubMenu(0)->SetDefaultItem(ID_FILE_NEW);//第二个参数默认是false,则第一个参数ID
//  GetMenu()->GetSubMenu(0)->SetDefaultItem(5,true); //"打印"是5不是4,因为分隔栏是要占索引的, 另外只能有一个缺省菜单项//------ 子菜单项上添加位图(文字左边) SetMenuItemBitmapsCString str;str.Format("x=%d, y=%d",GetSystemMetrics(SM_CXMENUCHECK),GetSystemMetrics(SM_CYMENUCHECK));//MessageBox(str);//x=13,y=13 系统子菜单项位图大小必须是13*13m_bitmap.LoadBitmap(IDB_BITMAP1);GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION,&m_bitmap,NULL); //要注意修改位图的底色,白色就看不见了.//------ 禁用子菜单项// m_bAutoMenuEnable 在CMainFrame()构造函数中设置其为m_bAutoMenuEnable =false 关闭MFC自动更新菜单的机制GetMenu()->GetSubMenu(0)->EnableMenuItem(ID_FILE_OPEN,MF_DISABLED|MF_GRAYED);//禁用"打开"子菜单项//GetMenu()->GetSubMenu(0)->EnableMenuItem(0,MF_BYPOSITION|MF_DISABLED|MF_GRAYED);//或者这样用子菜单项索引//------ 删除整个菜单,和加载菜单
//  SetMenu(NULL); // 填参数NULL 就删除了整个菜单//------加载菜单,可以加载自定义菜单资源/*    CMenu menu; // 这里有个隐藏的问题 就是menu是个局部变量,解决办法是(1)把他放到CMainFrame中作为成员变量//(2) 就是下面的加上:menu.Detach();menu.LoadMenu(IDR_MAINFRAME); //菜单资源IDSetMenu(&menu);menu.Detach();//将菜单句柄与CMenud对象menu脱离,这样局部变量menu析构是就不会这个菜单资源(因菜单资源已经不属于它了,析构不到)*/return 0;
}BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{if( !CFrameWnd::PreCreateWindow(cs) )return FALSE;// TODO: Modify the Window class or styles here by modifying//  the CREATESTRUCT csreturn TRUE;
}/
// CMainFrame diagnostics#ifdef _DEBUG
void CMainFrame::AssertValid() const
{CFrameWnd::AssertValid();
}void CMainFrame::Dump(CDumpContext& dc) const
{CFrameWnd::Dump(dc);
}#endif //_DEBUG/
// CMainFrame message handlers//DEL void CMainFrame::OnTest()
//DEL {
//DEL   // TODO: Add your command handler code here
//DEL   MessageBox("MainFrame clicked");
//DEL
//DEL }void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)
{// TODO: Add your command update UI handler code here//    if(pCmdUI->m_nID == ID_EDIT_CUT)这个判断是多余的,因为pCmdUI的成员m_nID传入进来是必定是ID_EDIT_CUT//因为这个消息响应函数是与菜单项关联了的.//------通过菜单项的ID "ID_EDIT_CUT",这样能保证菜单项"剪切"和工具栏那个剪刀都Enable/*if(pCmdUI->m_nID == ID_EDIT_CUT) //多余的pCmdUI->Enable(true);*///------通过索引m_nIndex: 这样的缺点工具栏中的剪刀图标没有激活,仅激活了子菜单项"剪切"//因为工具栏上的剪刀图标的index并不等于2,工具栏这个横条是一个整体,剪刀的index=4/*if(pCmdUI->m_nIndex == 2) pCmdUI->Enable();*///------菜单和工具栏图标都激活: 最简单就是不要用if()判断,直接EnablepCmdUI->Enable(true);}

孙鑫VC++深入详解:Lesson6 Part2 -- MFC菜单更新机制 用该机制实现 Enable or Disable MenuItem相关推荐

  1. 孙鑫VC++深入详解:Lesson6 Part3 ---创建右键弹出菜单 TrackPopupMenu

    1 -----增加右键弹出菜单方法一:      Project-->Add to Project-->Components and Controls -->Visual C++ C ...

  2. 孙鑫VC++深入详解第三章学习笔记

    第三章 3.1创建MFC AppWizard 如何利用vs2019创建MFC应用见参考文献[1] 需要注意的地方有 [1] 创建MFC单文档应用程序 [2]开启类视图窗口 3.2基于MFC的程序框架剖 ...

  3. 孙鑫VC++深入详解第二章学习笔记

    第二章 掌握C++ 2.1 从结构到类 2.1.1 结构体的定义 C++相比于C的特性:封装性.继承性.多态性: 对象具有状态和行为,状态保存在成员变量中,行为通过函数实现: 标准输入输出流对象:ci ...

  4. 孙鑫VC++深入详解第一章学习笔记

    第一章 Windows程序内部运行机制 1.1 API和SDK API:Windows操作系统提供给应用程序编程的接口. SDK(软件开发包):用于开发的所有资源的集合. 1.2 窗口和句柄 窗口 句 ...

  5. 孙鑫VC++深入详解笔记

    前言:最近感觉技术提升提来很吃力,主要还是因为以前的基础没有打牢,特别是多线程和数据库方面,所有准备重新学习一下基础. 如下文章转载自:http://www.cnblogs.com/gaojun/ar ...

  6. VC++深入详解 孙鑫 高清PDF + 配套视频下载

    VC++深入详解 孙鑫 高清PDF版下载 孙鑫C++视频教程 rmvb格式 全20CD完整版 精品分享 转载于:https://www.cnblogs.com/gavinhughhu/archive/ ...

  7. 孙鑫《VC++深入详解》完整版PDF 下载

    非常不错的书,结合孙鑫视频看,效果很好. 下载地址: http://pan.baidu.com/s/1sjBT1hV (链接更新时间:2015-08-28 00:59:03  一两年内应该有效) 此书 ...

  8. Lesson16基于消息的异步套接字聊天室程序 VS2013 VC++深入详解 孙鑫

    Table of Contents 新建项目 UI设置 项目Project设置 代码 Chat.cpp ChatDlg.h : header file ChatDlg.cpp TODO: 新建项目 M ...

  9. VC++深入详解学习笔记

    VC++深入详解学习笔记 Lesson1: Windows程序运行原理及程序编写流程 Lesson2: 掌握C++基本语法 Lesson3: MFC框架程序剖析 Lesson4: 简单绘图 Lesso ...

最新文章

  1. 来自顶尖JAVA程序猿的焦虑,拒绝中年危机,唯有一生力学笃行
  2. 一台计算机有64,在同一台计算机上使用带有32位和64位Altium设计软件的数据库元件库...
  3. [原]执行存储过程后返回影响的行数
  4. C指针原理(26)-gtk
  5. HDU 6175 算术
  6. css3小球坠落,CSS3 圆球体内的小球碰撞运动
  7. MapReduce操作HBase
  8. jsx中的注释的写法
  9. Flowable 数据库表结构 ACT_GE_PROPERTY
  10. OJ1041: 数列求和2(高阶递推)
  11. 【API进阶之路】太秃然了,老板要我一周内检测并导入一万个小时的视频
  12. 一个多文件编程里.h文件定义static变量产生的问题
  13. 毕业设计管理系统(JAVA毕业设计)
  14. SwiftUI教程第1章第13节:Divider
  15. Guass Rank(深度学习数值特征归一化方法)
  16. 网课答题查询助手(免费)
  17. thinkphp5+php微信公众号二维码扫码关注推广二维码事件实现
  18. html可编辑的表格
  19. TCP/IP可能有你不知道的事
  20. 学生如何免费激活JetBrain所有产品(PyCharm,IDEA......)

热门文章

  1. 1237-简单计算器【浙大计算机研究生复试上机考试-2006年】
  2. 全球与中国先进航空航天复合材料市场现状及未来发展趋势2022-2028
  3. css实现“五筒”结构
  4. 韩国GENICOM紫外线探测器 探头GUVV-T11GC-TLW10 原厂渠道
  5. 机器学习笔记入门 (三)
  6. Java8新特性----Stream
  7. 店宝宝谈天猫苏宁合作升级:面对家电劲敌仍需努力
  8. 14.关于字符串连接运算符
  9. DevStream 成为 CNCF Sandbox 项目啦!- 锣鼓喧天、鞭炮齐鸣、红旗招展、忘词了。
  10. 隐藏HTML 文字链接,让超链接文字隐藏掉css代码