菜单

简介:

1、MFC类层次结构图:

 

CxxxApp类和CxxxDoc类不是CWnd派生,所以没有成员函数MessageBox,可以使用应用程序框架的函数:AfxMessageBox()代替,原型如下:

Int AfxMessageBox(LPCTSTR lpszText,UINT nType=MB_OK,UINT nIDHelp=0);

2、程序类对菜单命令的响应顺序:

视类、文档类、框架类、应用程序类。

3、windows消息分类

(1)标准消息

以WM_开头。

(2)命令消息

来自菜单、加速键或工具栏按钮的消息。都以WM_COMMAND形式呈现。MFC中,通过菜单项的标识(ID)识别;SDK中通过消息的wParam参数识别。

(3)通告消息

由控件产生,例如:按钮的单击、列表框的选择等都会产生这类消息,目的是为了向其父窗口(通常是对话框)通知事件的发生。

结论:

从CWnd派生的类均可继承以上三种消息。

从CCmdTarget派生的类只能接收命令消息和通告消息。

4、菜单命令路由通经

 

 

4、基本菜单操作

(1)获得程序的菜单栏,CWnd::GetMenu()函数,原型如下:

CMenu * GetMenu() const;

返回的是一个CMenu对象指针,可以进行菜单的创建、更新、销毁以及调用其子菜单GetSubMenu函数,原型如下:

CMenu * GetSubMenu(int nPos) const;   //子菜单的索引号

(2)为菜单项添加或移除标记,CMenu::CheckMenuItem()函数,原型如下:

UINT CheckMenuItem(UINT nIDCheckItem, UINT nCheck);

参数含义:指定处理的菜单项,如何处置(MF_CHECKED,MF_UNCHECKED,MF_BYPOSITION,MF_BYCOMMAND)

(3)例如:(红字部分配对使用)

GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_SAVE,MF_BYCOMMAND|MF_CHECKED);

GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION|MF_CHECKED);

6、默认菜单项(黑体字标识)

设置默认菜单项,CMenu::SetDefaultItem()函数,原型如下:

BOOL SetDefaultItem(UINT uItem,BOOL fByPos=FALSE);

参数含义:若为false,第一个参数表示菜单项标识,否则为菜单项位置索引。

结论:

(1)一个子菜单只能有一个默认菜单项。

(2)分隔栏在菜单项中占据索引位置。

7、图形标记菜单

实现图形标记菜单利用CMenu::SetMenuItemBitmaps(),作用是将指定位图与菜单项关联,原型如下:

BOOL SetMenuItemBitmaps(UINT nPosition,UINT nFlags,const CBitMap * pBmpUnChecked,const * CBitMap pBmpChecked);

参数描述:菜单项标识|菜单项位置索引,MF_BYCOMMAND,未选中状态位图,选中状态位图。

m_bitmap.LoadBitmap(IDB_BITMAP1);   //m_bitmap为全局变量

GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION|MF_CHECKED,&m_bitmap,&m_bitmap);

//获取标记菜单项上标记图形的默认尺寸:标记宽度,标记高度

GetSystemMetrics(SM_CXMENUCHECK);

8、禁用菜单项

设置菜单项的状态:能够使用、禁用或变灰显示。CMenu::EnableMenuItem(),原型如下:

UINT EnableMenuItem(UINT nIDEnableItem,UINT nEnable);

GetMenu()->GetSubMenu(0)->EnableMenuItem(1,MF_BYPOSITION|MF_DISABLED|MF_GRAYED);

注意:

//需将CMainFrame类的构造函数中成员变量m_bAutoMenuEnable设置为false。

9、移除和装载菜单

CWnd::SetMenu(),函数原型如下:

BOOL SetMenu(CMenu * pMenu);

例如:

(1)SetMenu(NULL);   //移除

(2)CMenu menu;

 menu.LoadMenu(IDR_MAINFRAME);

 SetMenu(&menu);

     //将菜单句柄和菜单对象分离

 menu.Detach();   //以防程序出现问题 因为此时的menu为一个局部变量

10、MFC菜单命令更新机制

(1)当要显示菜单时,操作系统发出WM_INITMENUPOPUP消息,然后由应用程序窗口的基类如CFrameWnd接管,它会创造一个CCmdUI对象,并与程序的第一个菜单项相关联,调用该对象的一个成员函数DoUpdate(),该函数发出ON_UPDATE_COMMAND_UI消息,这条消息带有一个指向CCmdUI对象的指针。系统判断是否存在一个ON_UPDATE_COMMAND_UI的宏,如果存在就调用相应的函数处理,在该函数中,可以利用传递过来的CCmdUI对象去调用,使用某个菜单项或禁用某个菜单项。更新完第一个菜单后,同一个CCmdUI对象就设置为第二个菜单项相关联,依次进行,直到完成所有菜单项的处理。

 

 

(2)CCmdUI类成员变量m_nID,用于保存当前菜单项、工具栏按钮,或者其他由CCmdUI对象表示的UI对象的标识。

(3)CCmdUI类成员变量m_nIndex,用于保存当前菜单项的位置索引。

8、快捷菜单

1

void CMenuView::OnContextMenu(CWnd*, CPoint point)

{

CMenu* pPopup = menu.GetSubMenu(0);

。。。。

pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,

pWndPopupOwner);

}

其中TrackPopupMenu原型如下:

BOOL TrackPopupMenu(UINT nFlags,int x,int y,CWnd * pWnd,LPCRECT lpRect=NULL)

nFlags:指定菜单在屏幕上显示的位置。

x,y:指快捷菜单显示位置处的x,y坐标。相对于屏幕坐标而不是客户区坐标(ClientToScreen(&point)使用该函数进行转化)

pWnd:指定快捷菜单的拥有者。

lpRect:指定一块矩形区域。鼠标点击其他处该快捷菜单也不会消失。

(2)区别

pPopup ->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_LEFTALIGN,point.x,point.y,this);

pPopup ->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_LEFTALIGN,point.x,point.y,Get Parent());//这种方法好像不对,编译不通过

9、动态菜单操作(针对弹出式菜单动态操作、针对菜单项的动态操作)

(1)动态的添加菜单项目,CMenu::AppendMenu函数原型如下:

BOOL AppendMenu(UINT nFlags,UINT_PTR nIDNewItem=0,LPCTSTR lpszNewItem=NULL);  末尾添加

nFlags:新添加菜单项目的状态信息。(禁用加灰菜单、移除对号标记菜单等)

nIDNewItem:如果第一个参数为MF_POPUP,则为顶层菜单句柄;否为新菜单项的命令ID。

            如果第一个参数为MF_SEPARATOR,nIDNewItem值忽略。

lpszNewItem:如果第一个参数为MF_STRING,则指向新添加菜单项目的文本的指针。

           如果第一个参数为MF_OWNERDRAW,则指向该菜单项目一个附加数据指针。

           如果第一个参数为MF_SEPARATOR,lpszNewItem值忽略。

(2)CMenu::CreatePopupMenu,作用:创建一个弹出菜单并关联菜单对象。

(3)插入菜单项:(在两个子菜单项中添加,在两个菜单项中添加)CMenu::InsertMenu()

BOOL InsertMenu(UINT nPosition,UINT nFlags,UINT_PTR nIDNewItem=0,LPCTSTR lpszNewItem=NULL) 根据具体位置添加

参数含义同AppendMenu函数,但nFlags会多几个组合MF_BYPOSITION和MF_BYCOMMAND.

(4)删除菜单项CMenu::DeleteMenu(),原型如下:

BOOL DeleteMenu (UINT nPosition,UINT nFlags);

13、动态添加菜单项的命令响应:

(1)Resource.h 中添加预定义内容  #define IDM_HELLO 111

(2)menu.AppendMenu(MF_STRING,IDM_HELLO,"hello");

(3)MainFrm.h文件中 AFX_MSG之后,DECLARE_MESSAGE_MAP之前添加:afx_msg void OnHello();

(4)MainFrm.cpp文件中BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间添加:

ON_COMMAND(IDM_HELLO,OnHello)不加分号。

(5)MainFrm.cpp文件中实现函数OnHello的实体

void CMainFrame::OnHello()

{

MessageBox("hello");

}

14、框架类窗口截获菜单命令消息(不用在视类中处理)

方法是:在框架类中添加OnCommand虚函数.    return TRUE;//中断消息路由路径。

(1)框架类获取视类的成员变量

CMainFrame::GetActiveView成员函数,获取与框架类相关联的当前视类的指针。原型如下:CView * GetActiveView()const; // 返回的是CView,如果不是用户所需还需类型转换。

例如:CTelNoteView * pView=(CTelNoteView *)GetActiveView();  //获取当前视类指针。

(2)m_bAutoMenuEnable=FALSE;



本文转自 韬光星夜 51CTO博客,原文链接:http://blog.51cto.com/xfqxj/476997,如需转载请自行联系原作者

相关文章
|
8月前
|
数据采集 人工智能 运维
医疗大模型落地方案:技术选型、部署策略与调优
医疗大模型正推动医疗行业数字化转型,其落地涉及技术选型、部署策略和调优方案。技术选型需根据需求选择适合的模型类型与架构;部署策略包括本地化、私有云及混合模式,注重数据安全与系统集成;调优方案从数据、模型到应用层面全面优化性能。通过多学科协作与持续改进,医疗大模型可更好地融入临床工作流,提升医疗效率与质量。
831 5
医疗大模型落地方案:技术选型、部署策略与调优
|
运维 监控 安全
高效运维管理:提升系统稳定性的策略与实践
【10月更文挑战第2天】 在当今数字化时代,运维管理成为企业IT部门的重要任务。本文将探讨如何通过高效的运维管理策略和最佳实践,提升系统的稳定性,确保业务持续平稳运行。通过分析常见问题、预防措施以及应对策略,我们将揭示高效运维的关键要素,助您打造一个可靠的IT环境。
|
11月前
|
机器学习/深度学习 人工智能 自然语言处理
GraphAgent:自动构建知识图谱,能够处理结构化和非结构化数据,并通过知识图谱展示复杂关系
GraphAgent 是香港大学和香港科技大学联合推出的智能图形语言助手,能够处理结构化和非结构化数据,并通过知识图谱展示复杂关系。
768 9
GraphAgent:自动构建知识图谱,能够处理结构化和非结构化数据,并通过知识图谱展示复杂关系
|
存储 Ubuntu 关系型数据库
Ubuntu 20.04 卸载与安装 MySQL 5.7 详细教程
该文档提供了在Ubuntu上卸载和安装MySQL 5.7的步骤。首先,通过`apt`命令卸载所有MySQL相关软件包及配置。然后,下载特定版本(5.7.32)的MySQL安装包,解压并安装所需依赖。接着,按照特定顺序安装解压后的deb包,并在安装过程中设置root用户的密码。安装完成后,启动MySQL服务,连接数据库并验证。最后,提到了开启GTID和二进制日志的配置方法。
4675 5
|
消息中间件 架构师 Cloud Native
软考高级系统架构师论文,到底该怎么写
软考高级系统架构师论文,到底该怎么写
484 0
|
前端开发 开发者
CSS中的长度单位详解
通过合理选择和组合使用不同的长度单位,开发者可以实现高效、灵活和响应式的Web布局设计。以上详解希望能帮助你更好地理解和应用CSS中的长度单位,提高页面的表现力和可维护性。
475 3
|
算法
串ababaaababaa的next和串ababaabab的nextval
本文介绍了计算字符串的next数组和nextval数组的方法,通过分析两个具体的例子来展示如何计算这些数组,这些数组通常用于KMP算法中。
904 0
串ababaaababaa的next和串ababaabab的nextval
|
Linux Python Windows
Linux 系统中 挂载 U 盘 方法
在 Linux 系统中,与 Windows 不一样的是,无法自动识别加载外部设备例如 U 盘、硬盘;例如用 PyCharm 或 IDEA 打开 U 盘中的内容,在没有完成挂载操作之前是不可行的 如果想实现上面操作,第一步,需要对 U 盘等外接移动设备完成 挂载操作
Linux 系统中 挂载 U 盘 方法
|
存储 大数据 Linux
Docker部署三个centos7容器
用完完成在容器环境中部署大数据相关组件
|
前端开发
HTML侧边导航栏
本文用最简洁的语言,来教会读者,如果用html+css来制作,侧边导航栏,本案例以手机商城中的部分为例子来制作。
401 0
HTML侧边导航栏