IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> MFC消息映射及自定义消息介绍 -> 正文阅读

[C++知识库]MFC消息映射及自定义消息介绍

MFC消息映射的作用就不累述了。个人对MFC消息处理机制的理解,类似qt的信号/槽机制。就是系统产生某一事件和消息,触发程序对应的响应函数,对此事件进行处理。消息映射是图形界面程序的窗口、各种控件与相关函数进行关联的重要机制。没有消息映射,就没有ui交互。
对于mfc的消息映射机制,我认为没有必要去研究其复杂的win32程序原理,具体消息是如何被处理的,只需要知道怎么用就好了。因为,当你有了一个轮子时,你应该考虑如何把它变成一辆车子,而不是,研究这个轮子是怎样被制造的。MFC的出现就是为了封装win32开发的细节。让开发变得更加简单。我们只需要按照MFC实现消息映射的方法来就可以。


MFC消息类型

在MFC中消息分为系统定义消息和程序定义消息。
在这里插入图片描述


三个重要的宏:

DECLARE_MASSAGE_MAP()

声明该类定义了一个消息映射。 程序中的每个 CCmdTarget 派生类都必须提供一个消息映射来处理消息。
在类声明的末尾使用 DECLARE_MESSAGE_MAP 宏

BEGIN_MESSAGE_MAP(theClass, baseClass )

theClass:消息映射类的名称
baseClass:消息映射类的基类名称

END_MESSAGE_MAP()

在类定义成员函数的实现 (.cpp) 文件中,使用 BEGIN_MESSAGE_MAP 宏启动消息映射,然后为每个消息处理程序函数添加宏条目,并使用 END_MESSAGE_MAP 宏完成消息映射。


系统定义消息

系统定义消息有三种类型,分为标准消息(窗口消息),命令消息,通告消息(控件通知消息)。

标准消息(WM_xxx):

除WM_COMMAND之外,所有以WM_开头的消息。例如ON_WM_SYSCOMMAND(),ON_WM_PAINT()。从CWnd派生的类,都可以接收到这类消息。
在初学mfc时我发现此类消息函数只有宏定义,没有与任何函数绑定,是因为,此类消息的处理函数名称固定,不可更改。标准的Windows消息,不需要我们指定处理函数的名称,每个标准Windows消息都有自己的默认处理函数名称。如WM_LBUTTONDOWN所对应的处理函数名称为OnLButtonDown。
WM_xxx 消息对应的宏为:ON_WM_xxx

BEGIN_MESSAGE_MAP(CaDlg, CDialog)
//标准消息宏
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	...
END_MESSAGE_MAP()

在vs2005的类视图中,找到窗体类,右键点击,选择属性。在属性页中点击消息。即可看到窗口消息的所有类型,点击右侧单元格即可添加相应的消息处理函数
在这里插入图片描述

命令消息(WM_COMMAND):

来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。从CCmdTarget派生的类,都可以接收到这类消息。

WM_COMMAND消息中有两个参 数,wparam、lparam,定义如下:
wParam 高位字 通知码
wParam 低位字 命令ID
lParam 发送命令消息的子窗体句柄。
wParam高位字:如果信息是从控件传来,参数wParam高位字指定通知代码。如果信息是从菜单中传来,这个值是零。如果信息是从一个快捷键传来,这个值是1 。
wParam低位字:菜单项,控件或快捷键的标识符。
lParam:如果信息是从控件传来,则 lParam是控件的句柄,如果是从菜单或者快捷键传来,则是0

WM_COMMAND消息 消息对应的宏为
ON_COMMAND(ID,pfn)
ON_COMMAND_EX(ID,pfn)

BEGIN_MESSAGE_MAP(CaDlg, CDialog)
...
//命令消息宏
ON_COMMAND(ID_1_2, &CaDlg::On12)
...
END_MESSAGE_MAP()

在vs资源视图中打开菜单,对菜单项右击,添加事件处理程序,添加相应的消息处理函数
在这里插入图片描述

通告消息(WM_NOTIFY):

随着控件的种类越来越多,越来越复杂(如列表控件、树控件等),仅仅将wParam,lParam将视为一个32位无符号整数,已经装不下太多信息了。为了给父窗口发送更多的信息,微软定义了一个新的WM_NOTIFY消息来扩展WM_COMMAND消息。
由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现。从CCmdTarget派生的类,都可以接收到这类消息。
WM_NOTIFY消息仍然使用MSG消息结构,只是此时wParam为控件ID,lParam为一个NMHDR指针,
WM_NOTIFY其实就是WM_COMMAND。实际中依然是使用WM_COMMAND来传送WM_NOTIFY。
如BN_CLICKED通知码为WM_COMMAND的wParam的高位字节。

通告消息的宏一般为在通知码前面加上 ON_

BEGIN_MESSAGE_MAP(CaDlg, CDialog)
...
//通告消息宏
ON_BN_CLICKED(IDCANCEL, &CaDlg::OnBnClickedCancel)
...
END_MESSAGE_MAP()

在vs的资源视图中打开窗体,对控件右击,添加事件处理程序,根据向导添加控件的响应函数
在这里插入图片描述

MFC消息映射的三处实现

MFC实现消息映射的三处信息,函数原型,函数实现,用来关联消息和消息响应的宏。

为菜单增加点事件为例,命令消息的三处实现:
在类声明中,定义消息处理函数,并且使用afx_msg作为前缀,在类最后定义DECLARE_MASSAGE_MAP()宏

protected:
	afx_msg void On12();
	DECLARE_MESSAGE_MAP()
};

在cpp文件中实现函数

void CaDlg::On12()
{
	// TODO: 在此添加命令处理程序代码
	MessageBox(L"Menu clicked!");
}

cpp文件中定义宏

BEGIN_MESSAGE_MAP(CaDlg, CDialog)
...
//命令消息宏
ON_COMMAND(ID_1_2, &CaDlg::On12)
...
END_MESSAGE_MAP()

只要定义了上述与消息有关的三处信息后,即可实现消息的响应处理
另外,消息名称与宏定义名称没有任何关系,初学mfc时,命令消息类型是WM_COMMAND,而宏定义名称却是ON_COMMAND。通告消息类型本质上也是WM_COMMAND。而宏定义的名称却不是ON_COMMAND。一度让我很混乱!


程序定义消息

MFC允许用户自定义消息,实现自定义消息分为4步
1.定义消息
系统定义消息ID范围:0x0000-0x03FF,程序定义消息ID范围:0x0400-0x7FFF。系统定义的消息都是小于WM_USER的,所以我们定义消息的ID就要大于WM_USER。推荐大100以上

#define WM_MY_MESSAGE (WM_USER+100)

2.在类声明中写消息处理函数的声明

	afx_msg LRESULT on_my_message(WPARAM wParam,LPARAM lParam);
	...
	DECLARE_MASSAGE_MAP()

3.在BEGIN_MESSAGE_MAP()与END_MESSAGE_MAP()之间添加消息映射宏
MFC自定义消息宏为:ON_MESSAGE(message, memberFxn)

BEGIN_MESSAGE_MAP(CaDlg, CDialog)
...
ON_MESSAGE(WM_MY_MESSAGE,CaDlg::on_my_message)
...
END_MESSAGE_MAP()

4.实现消息处理函数

LRESULT CaDlg::on_my_message(WPARAM wParam,LPARAM lParam){
	MessageBox(L"custom message triggered!");
	return 0;
}

自定义消息映射就完成了。
之后,在需要的地方,发射消息,触发消息映射

SendMessage(WM_MY_MESSAGE);

参考文章

WM_COMMAND与消息的传递
MFC消息分类与消息队列
MFC应用程序传输的消息有三种类型:窗口消息、命令消息和控件通知
百度百科

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:10:02  更:2022-03-08 22:11:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:43:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码