0
点赞
收藏
分享

微信扫一扫

MFC消息映射及自定义消息介绍

color_小浣熊 2022-03-11 阅读 82

文章目录


MFC消息类型

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


三个重要的宏:

DECLARE_MASSAGE_MAP()

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

END_MESSAGE_MAP()

BEGIN_MESSAGE_MAP(theClass, baseClass )

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

在类定义成员函数的实现 (.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允许用户自定义消息,实现自定义消息分为四步
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;
}

5.发射消息

SendMessage(WM_MY_MESSAGE);

参考文章

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

举报

相关推荐

0 条评论