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


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

添加 Menu 选项

a 对应 ID ID_DEMO_Ab 对应 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 菜单响应路由 // 这个记录的可能还详细一点
posted @   double64  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示