VC++:菜单

参考《VC++深入详解》孙鑫

  • 管理者
            菜单由CMenu类管理,CMenu类派生于CObject类。
  • 使用方式
    • 在局部堆栈或全局堆中创建CMenu对象
    • 调用CMenu类的成员函数对其进行操作
    • 调用CWnd::SetMenu将菜单挂接到某个窗口——此函数将新菜单作为窗口菜单,并立即重新对其进行绘制
    • 立即调用CMenu::Detach函数——此函数解除HEMENU与CMenu对象之间的联系
  • COMMAND与UPDATE_COMMAND_UI消息的区别
  • 响应菜单项命令的顺序
    视类->文档类->框架类->应用程序类
  • windows消息分类
    • 标准消息
    • WM_COMMAND之外,所有以WM_开头的消息都是标准消息。从CWnd派生的类,都可以接收到这类消息。
    • 命令消息
    • 来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND形式呈现;在MFC中,通过菜单项的ID来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。从CCmdTarget派生的类,都可以接收到这类消息。
    • 通告消息
    • 由控件产生的消息,例如按钮的单击、列表框的选择等都会产生这类消息,目的是为了向其父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现的;

  • 操作函数
    • 基本菜单操作: GetMenu->GetSubMenu(0);
    • 标记菜单: GetMenu->GetSubMenu(0)->CheckMenuItem(0, MF_BYPOSITION|MF_CHECKED);
    • 默认菜单项: GetMenu->GetSubMenu(0)->SetDefaultItem(1,TRUE);
    • 图形标记菜单: SetMenuItemBitmaps()
      • 第三个参数pBmpUnchecked: 取消菜单项选中状态时的位图
      • 第四个参数pBmpChecked: 选中菜单项时显示的位图
      • GetSystemMetric函数:可以获得图形标记菜单上显示的位图的尺寸
    • 禁用菜单项: EnableMenuItem函数(如果想自己更改菜单项的状态,必须先把m_bAutoMenuEnable变量设置为FALSE,之后自己对菜单项状态的更新才起作用)
    • 移除和装载菜单
      • 移除: SetMenu(NULL);
      • 装载:
        • CMenu menu;
        • menu.LoadMenu(IDR_MAINFRAME);
        • SetMenu(&menu);
        • menu.Detach();
      • 加载菜单后因为菜单是局部对象出现问题的解决方案
        • 把menu定义为CMainFrame的成员变量
        • 调用SetMenu函数把此对象设置为窗口的菜单之后,立即调用CMenu类的另一个成员函数Detach,以便把菜单句柄与这个菜单对象分离
        • 说明:Detach函数会把菜单句柄与这个菜单对象分离,这样当这个局部对象声明周期结束时,它不会去销毁一个它不再拥有的菜单,这个菜单在窗口销毁时会自动销毁。
    • MFC菜单命令更新机制
      • 当要显示菜单时,操作系统发出WM_INITMENUPOPUP消息,然后由程序窗口的基类如CFrameWnd接管;它会创建一个CCmdUI对象,并与程序的第一个菜单项相关联,调用该对象的一个成员函数DoUpdate(),这个函数发出CN_UPDATE_COMMAND_UI消息,这条消息带有一个指向CCmdUI对象的指针;这时,系统会判断是否存在一个ON_UPDATE_COMMAND_UI宏去捕捉这个菜单项消息,如果找到这样一个宏,就调用相应的消息响应函数进行处理,在这个函数中,可以利用传递过来的CCmdUI对象去调用相应的函数,使该菜单项可以使用或禁用该菜单项;当更新完第一个菜单项后,同一个CCmdUI对象就设置为第二个菜单项相关联,依次顺序进行,直到完成所有菜单项的处理。

快捷菜单
  • 添加步骤:
    • 做一个菜单资源
    • 添加右键消息(WM_RBUTTONDOWN)响应函数
    • 在响应函数中添加代码
      • 加载菜单
        • CMenu menu;
        • menu.LoadMenu(IDR_XXX);
        • CMenu *pMenu = menu.GetSubMenu(1);
      • 显示菜单
        • ClientToScreen(&point);
        • pMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x,point.y,GetParent());

动态菜单操作
 
包括针对弹出菜单的动态操作和针对菜单项的动态操作。
  • 添加菜单项目
    • AppendMenu
    • 例子
      • CMenu menu;
      • menu.CreateMenu();
      • GetMenu()->AppendMenu(MF_POPUP,(UINT)menu.m_hMenu,"test");
      • menu.Detach();
  • 插入菜单项目
    • InsertMenu
    • 在两个子菜单之间插入一个子菜单
    • 在两个菜单项之间插入一个新的菜单项 
    • 例子
      • CMenu menu;
      • menu.CreateMenu();
      • GetMenu()->InsertMenu(2,MF_POPUP|MF_BYPOSITION,(UINT)menu.m_hMenu,"Test");  //子菜单
      • GetMenu()->GetSubMenu(0)->InsertMenu(ID_FILE_OPEN,MF_BYCOMMAND|MF_STRING,115,"VC 编程"); //菜单项
      • menu.Detach();
  • 删除菜单
    • BOOL DeleteMenu(UINT nPosition, UINT nFlags);
    • 例子
      • GetMenu()->DeleteMenu(1,MF_BYPOSITION);
      • GetMenu()->GetSubMenu(0)->DetletMenu(2,MF_BYPOSITION);
  • 动态添加菜单项的命令响应
    • 方法:通过编辑resource.h,在其中添加动态菜单项的资源ID,然后为此资源添加相应的消息处理机制。
    • 具体做法:
      • #define IDM_HELLO 111
      • 添加函数中修改为:menu.AppendMenu(MF_STRING,IDM_HELLO,"hello");
      • 添加消息映射及响应函数
        • afx_msg void OnHello();
        • ON_COMMAND(IDM_HELLO,OnHello)  //无分号
        • void CMainFrame::OnHello() {...}

转载于:https://www.cnblogs.com/huan7550/archive/2013/03/21/2973108.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值