MFC 菜单路由事件,按钮可用不可用

点击b会切换a可用状态:

添加 Menu 选项

a 对应 ID ID_DEMO_A,b 对应 ID ID_DEMO_B。
弹式菜单无法编辑 ID。

▲ 右键添加事件处理程序

▲ 路由传递路径
frame 给到 view 如果 view 处理好了,就返回给 frame;如果没处理的话, view 会给这个路由消息给 doc,如果doc没有处理,再返回给 view, view 在给 frame,frame 给 app(应用程序)。消息处理后就不会传递下去了。
消息分为三类
1)菜单的命令响应函数
a)弹式菜单,ID不可编辑,按下去,弹出一个菜单项
b)非弹式菜单,ID可编辑
c)菜单响应命令消息的路由(顺序)
d)消息类型
非标准消息 WM_COMMAND,命令消息、通告消息,CCmdTarget、CWnd子类子类能接收到非标准消息 // 只有菜单有
标准消息 WM_XXXX CWnd子类才能接收到标准消息
命令消息WM_COMMAND:菜单处理函数选中
标准消息: 属性 -> 消息
通告消息:点击按钮,处理函数 // 点击按钮等控件的时候有
CWnd 可以接受任何消息
CCmdTarget 不能接受标准消息
头文件
// 生成的消息映射函数
protected:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnTestDemo();
    afx_msg void OnUpdateFileOpen(CCmdUI* pCmdUI);
private:
    bool m_isEnable;
public:
    afx_msg void OnFileSave();
    afx_msg void OnDemoB();
    afx_msg void OnUpdateDemoA(CCmdUI* pCmdUI);
在 Frame 静态处理

▲ IDR_MENU1 Menu     IDR_MAINFRAME这个是默认的
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("未能创建工具栏\n");
		return -1;      // 未能创建
	}
	if (!m_wndStatusBar.Create(this))
	{
		TRACE0("未能创建状态栏\n");
		return -1;      // 未能创建
	}
	m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
	// TODO: 如果不需要可停靠工具栏,则删除这三行
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);
    // 获取主菜单
    CMenu* menu = GetMenu();
    CMenu* fileMenu = menu->GetSubMenu(0); // 第 0 个,也可以通过 ID
    // 标志 "新建"
    fileMenu->CheckMenuItem(0, MF_BYPOSITION | MF_CHECKED); // 前面会有个 勾
    // 打开
    fileMenu->CheckMenuItem(ID_FILE_OPEN, MF_BYCOMMAND | MF_CHECKED); // 通过 ID的方式
    // 设置默认项, 加粗,一个菜单只能一个默认菜单
    // FASLE: 用ID
    // TRUE: 用位置
    fileMenu->SetDefaultItem(ID_FILE_SAVE, FALSE);   // 这个效果是,加粗变黑。
    fileMenu->SetDefaultItem(3, TRUE);
    // 变灰
    //需要把 CFrameWnd::m_bAutoMenuEnable 设置 false  才能真正变灰,可在构造函数置 false
    fileMenu->EnableMenuItem(5, MF_BYPOSITION | MF_DISABLED);   // 这个效果禁用变灰 分割线也算一个索引位置
    SetMenu(NULL);   // 移除菜单
    CMenu menu2;
    // 加载菜单  菜单的加载
    menu2.LoadMenuW(IDR_MENU1);
    SetMenu(&menu2);
    menu2.Detach();  // 分离,不会局部变量回收的效果
	return 0;
}
菜单更新机制
// b 的处理函数
void CMainFrame::OnDemoB()
{
    m_isEnable = !m_isEnable;
}
// a 的更新  这个会自动更新
void CMainFrame::OnUpdateDemoA(CCmdUI* pCmdUI)
{
    pCmdUI->Enable(m_isEnable);
}
参考:
笔记定位:
- MFC 菜单响应路由 // 这个记录的可能还详细一点
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号