MFC 菜单

目录

MFC菜单

菜单使用

添加菜单资源

将菜单设置到窗口

ON_COMMAND消息处理

命令消息 WM_COMMAND 的处理顺序

设置菜单项状态

右键菜单


MFC菜单

在Win32编程中,使用菜单句柄 HMENU 来标识菜单,在MFC中使用CMenu类对象表示菜单。封装了关于菜单的各种操作成员函数,另外还封装了一个非常重要的成员变量m_hMenu(菜单句柄)

菜单使用

(1)添加菜单资源

(2)将菜单设置到窗口

  • 利用pFrame调用Create函数时,传参。
  • 在处理框架窗口的WM_CREATE消息时
    • CMenu menu ;   // 完成菜单句柄加载到菜单对象里,并且完成对象句柄绑定
    • menu.LoadMenu(...); // 使用句柄设置为窗口的菜单

添加菜单资源

添加一个菜单

修改 新建 ID 为 ID_NEW

将菜单设置到窗口

方式一:利用pFrame调用Create函数时,传参。

pFrame->Create(NULL,"MFCCreate",WS_OVERLAPPEDWINDOW,CFrameWnd::rectDefault,NULL,(char*)IDR_MENU1);

根据提供的参数,Create() 函数的参数含义如下:

  • 第一个参数 NULL 表示窗口的父窗口为默认值,即没有父窗口。
  • 第二个参数 "MFCCreate" 是窗口的标题,将显示在窗口的标题栏上。
  • 第三个参数 WS_OVERLAPPEDWINDOW 是窗口的样式标志,表示创建一个具有标题栏、边框和控制菜单的重叠窗口。
  • 第四个参数 CFrameWnd::rectDefault 是窗口的初始位置和大小。CFrameWnd::rectDefault 是一个常量,表示使用默认的大小和位置。
  • 第五个参数 NULL 表示没有指定父窗口,因为这是一个顶级窗口。
  • 第六个参数 (char*)IDR_MENU1 是窗口的菜单资源标识符,用于关联窗口的菜单。

此时新建这个下拉菜单是灰色的,无法点击。这是因为店家这个菜单的消息没被处理

方式二;在处理框架窗口的WM_CREATE消息时

int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs) {
	menu.LoadMenu(IDR_MENU1);
	this->SetMenu( &menu );// 等价与 ::SetMenu(this->m_hWnd, menu.m_hMenu);
	return CFrameWnd::OnCreate(pcs);
}

调用类的成员函数本质还是调用Win32 API 

代码说明:可以实现将指定的菜单资源加载到窗口,并将其设置为窗口的菜单,以便在窗口中显示和处理菜单项的相关操作。 

  • 调用 LoadMenu(IDR_MENU1) 函数,将菜单资源 IDR_MENU1 加载到 menu 对象中。本质还是调用Win32 API
  • 通过调用 ::SetMenu(this->m_hWnd, menu.m_hMenu) 函数,将 menu 对象的菜单句柄 m_hMenu 设置为当前窗口的菜单。

值得注意的是,菜单对象应该作为框架窗口对象成员变量

LoadMenu内部代码,通过菜单ID拿到菜单句柄,把句柄和菜单对象绑定

_AFXWIN_INLINE BOOL CMenu::LoadMenu(UINT nIDResource)
	{ return Attach(::LoadMenuW(AfxFindResourceHandle(
		MAKEINTRESOURCE(nIDResource), RT_MENU), MAKEINTRESOURCEW(nIDResource))); }

attach函数:

把菜单句柄赋值给对象成员变量

调用SetPermanent函数把句柄绑定到菜单对象

BOOL CMenu::Attach(HMENU hMenu)
{
	ASSERT(m_hMenu == NULL);        // only attach once, detach on destroy
	if (hMenu == NULL)
	{
		return FALSE;
	}
    
	// Capture menu in object first to ensure it does not leak if the map cannot be allocated/expanded 
	m_hMenu=hMenu;

	CHandleMap* pMap = afxMapHMENU(TRUE); // create map if not exist
	ASSERT(pMap != NULL);
	pMap->SetPermanent(m_hMenu, this);
	return TRUE;
}

通过菜单句柄就能拿到菜单对象 

inline void CHandleMap::SetPermanent(HANDLE h, CObject* permOb)
	{ m_permanentMap[(LPVOID)h] = permOb; }

ON_COMMAND消息处理

可以在MSDN中搜索 ON_COMMAND 就可以找到 WM_COMMAND 消息的处理

在框架窗口的消息映射中处理,ON_COMMAND(菜单项ID,处理消息的函数名)

void CMyFrameWnd::OnNew() {
	AfxMessageBox("框架类处理了新建菜单项被点击");
}

命令消息 WM_COMMAND 的处理顺序

框架类比应用程序类先处理 WM_COMMAND 消息

在应用程序类中也处理 WM_COMMAND 消息,框架类处理完后,其他的就不处理了,只处理一次

对比系统消息,如WM_CREATE只在框架窗口类处理。只有WM_COMMAND会在多个类的中处理

设置菜单项状态

需要处理消息 WM_INITMENUPOPUP 菜单激活,即将显示还没显示,可以调用两个API:CheckMenuItem 、 EnableMenuItem 处理。在MFC中也是要处理这个消息 

void CMyFrameWnd::OnInitMenuPopup(CMenu* pPopup, UINT nPos, BOOL i) {
	//	pPopup->CheckMenuItem( ID_NEW, MF_CHECKED );
	::CheckMenuItem(pPopup->m_hMenu, ID_NEW, MF_CHECKED);
}

右键菜单

右键菜单即是上下文菜单,右击鼠标可以显示一个类似Win右击鼠标可以显示刷新一样

WM_CONTEXTMENU    API:::TrackPopupMenu

ON_WM_CONTEXTMENU  成员函数:CMenu::TrackPopupMenu

菜单是包含两个部分,也就是说CMenu对象是整个菜单

void CMyFrameWnd::OnContextMenu(CWnd* pWnd, CPoint pt) {
	//	HMENU hPopup = ::GetSubMenu(menu.m_hMenu,0);
	//	::TrackPopupMenu( hPopup, TPM_LEFTALIGN|TPM_TOPALIGN, pt.x, pt.y,
	//										0, this->m_hWnd, NULL );
	CMenu* pPopup = menu.GetSubMenu(0);
	pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, this);
}

TrackPopupMenu函数只能显示弹出式菜单,需要先拿到对应的句柄,调用GetSubMenu函数,参数0表示”文件“,可以拿到文件菜单的下拉菜单

  • TPM_LEFTALIGN 将菜单左对齐,即菜单的左边缘与触发菜单的点对齐。
  • TPM_TOPALIGN 将菜单上对齐,即菜单的上边缘与触发菜单的点对齐。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/266801.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB - 四元数(quaternion)

系列文章目录 前言 一、简介 四元数是一种四元超复数,用于三维旋转和定向。 四元数的表示形式为 abicjdk,其中 a、b、c 和 d 为实数,i、j 和 k 为基元,满足等式:i2 j2 k2 ijk -1。 四元数集用 H 表示&#xff0c…

vmware安装中标麒麟高级服务器操作系统软件 V7.0操作系统

vmware安装中标麒麟高级服务器操作系统软件 V7.0操作系统 1、下载中标麒麟高级服务器操作系统软件 V7.0镜像2、安装中标麒麟高级服务器操作系统软件 V7.0操作系统 1、下载中标麒麟高级服务器操作系统软件 V7.0镜像 官方提供使用通道 访问官网 链接: https://www.kylinos.cn/ 下…

【Python】基于flaskMVT架构与session实现博客前台登录登出功能

目录 一、MVT说明 1.Model层 2.View层 3.Template层 二、功能说明 三、代码框架展示 四、具体代码实现 models.py 登录界面前端代码 博客界面前端代码(profile.html) main.py 一、MVT说明 MVT架构是Model-View-Template的缩写,是…

VS(Visual Studio)更改文件编码

vs默认编码是GB2312,更改为UTF-8 工具->自定义

Tomcat与Netty比较

Tomcat介绍Tomcat支持的协议Tomcat的优缺点Netty介绍Netty支持的协议Netty的优点和缺点Tomcat和Netty的区别Tomcat和Netty的应用场Tomcat和Netty来处理大规模并发连接的优化Tomcat与Netty的网络模型的区别Tomcat与Netty架构设计拓展 Tomcat介绍 Tomcat是一个免费的、开放源代码…

nodejs+vue+ElementUi摄影作品图片分享工作室管理系统

第1周 2.21~2.27 查阅资料,学习vscode开发平台和vue框架技术 第2周 2.28~3.6 对软件功能需求进行分析, 软件功能模块划分及软件界面设计 第3周 3.7~3.13 撰写并提交毕业设计开题报告、英文资料翻译 第4周 3.14&#xff5…

深度学习中的池化

1 深度学习池化概述 1.1 什么是池化 池化层是卷积神经网络中常用的一个组件,池化层经常用在卷积层后边,通过池化来降低卷积层输出的特征向量,避免出现过拟合的情况。池化的基本思想就是对不同位置的特征进行聚合统计。池化层主要是模仿人的…

【docker笔记】docker理论及安装

前言 本笔记来源于尚硅谷docker教学视频 视频地址:https://www.bilibili.com/video/BV1gr4y1U7CY/?spm_id_from333.337.search-card.all.click 纯手打笔记,来之不易,感谢支持~ Docker简介 docker为什么会出现 想象一下:一个应用…

Web前端-JavaScript(Dom基础)

文章目录 1.1 DOM 介绍1.1.1 DOM简介1.1.2 DOM树 1.2. 获取元素1.2.1 根据ID获取元素1.2.2 根据标签名获取元素1.2.3 其它方式获取元素1.2.4 获取特殊元素 1.3 事件基础1.3.1 事件概述1.3.2 事件三要素1.3.3 执行事件步骤1.3.4 鼠标事件 1.4 操作元素1.4.1 操作元素内容1.4.2 属…

Java小案例-MusiQ音乐网站

目录 前言 项目功能 技术栈 后端 前端 开发环境 项目展示 前台-首页-展示 前台-首页-代码 前台-歌单-展示 前台-歌单-代码 前台-歌手-展示 前台-歌手-代码 前台-其他页面展示 后台-登录-展示 后台-登录-代码 后台-首页-展示 首台-首页-代码 后台-其他页面-展…

PyQt6 QColorDialog颜色对话框控件

锋哥原创的PyQt6视频教程: 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计50条视频,包括:2024版 PyQt6 Python桌面开发 视频教程(无废话版…

基于Qt之QChart 图表(优美的曲线图案例)

## 项目演示 平台:ubuntu18.04 Qt版本:QT5.14.2 源码位置GitCode:https://gitcode.com/m0_45463480/QCharts/tree/main ## QChart 图表 自从 Qt 发布以来,给跨平台的用户带来很多便利。在 Qt5.7 之前,Qt 在开源社区版本里没有 Qt Charts(自带的绘图组件库)。这使得像…

SpringBoot的日志管理

🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全栈,…

Kubernetes api-server源码阅读2(Debug Kubernetes篇)

云原生学习路线导航页(持续更新中) 本文是 Kubernetes api-server源码阅读 系列第二篇,主要讲述如何实现 kubernetes api-server 的 debug 参考b站视频地址:Kubernetes源码开发之旅二 1.本篇章任务 Go-Delve:go语言的…

INFINI Gateway 如何防止大跨度查询

背景 业务每天生成一个日期后缀的索引,写入当日数据。 业务查询有时会查询好多天的数据,导致负载告警。 现在想对查询进行限制–只允许查询一天的数据(不限定是哪天),如果想查询多天的数据就走申请。 技术分析 在每…

排序算法——桶排序

把数据放进若干个桶,然后在桶里用其他排序,近乎分治思想。从数值的低位到高位依次排序,有几位就排序几次。例如二位数就排两次,三位数就排三次,依次按照个十百...的顺序来排序。 第一次排序:50 12 …

二级指针的作用 -- 将变量从函数中带出

使用一级指针不能将变量带出 void test(int *p) {static int nub 10; /*使用static是保证函数结束, 变量依然存在, 不然即使将它带出来, 函数结束时这片内存已经被释放了就没有意义了*/p &nub; }int main(void) {int *p NULL;test(p);printf("%d",*p);return …

计算机网络-网络层

计算机网络-网络层 以下笔记整理为哔哩哔哩湖科大教书匠的《计算机网络微课堂》的教学视频。 链接:计算机网络微课堂 1. 网络层概述 1.1 网络层的主要任务是实现网络互联,进而实现数据包在各网络之间的传输。 1.2 要实现网络层任务,需要解决…

java中静态修饰符(static)的使用

static-静态 修饰属性 静态属性,也称为静态变量 类变量等 static 数据类型 属性名; 使用 静态内容独立存放在方法区 静态内容在内存中只有一份,被该类所有对象共享 普通属性所有对象在对象内容中都有一份 可以通过类名.静态属性名的方式直接访问静态属性 静态属性封装之…

Milvus数据一致性介绍及选择方法

1、Milvus 时钟机制 Milvus 通过时间戳水印来保障读链路的一致性,如下图所示,在往消息队列插入数据时, Milvus 不光会为这些插入记录打上时间戳,还会不间断地插入同步时间戳,以图中同步时间戳 syncTs1 为例&#xff0…