Skip to content

消息映射机制

1.Win32消息

在win32中,一个窗口的所有操作都是通过消息机制完成的,如下

c++
#include <windows.h>
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
        case WM_DESTROY:
        case WM_PAINT:
        return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow)
{
    // ............
	MSG msg = { };
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return 0;
}

MFC的消息处理机制是基于消息映射(MessageMap)的,它允许开发者将特定的Windows消息映射到特定的成员函数(称为消息处理函数)上。

2.MFC消息映射步骤

2.1 声明消息映射

DECLARE_MESSAGE_MAP是一个宏,它必须在MFC类的头文件中声明,以便MFC框架能够识别该类具有消息映射

需要给哪个对话框声明消息映射,就在哪个对话框的头文件中声明DECLARE_MESSAGE_MAP

c++
class CMFCTEST1Dlg : public CDialogEx
{
public:

protected:
	// 省略其他
	DECLARE_MESSAGE_MAP()   // 注意不用写分号,这是个宏
};

2.2 定义消息映射

在头文件中声明消息映射后,需要在相应的cpp文件中使用BEGIN_MESSAGE_MAPEND_MESSAGE_HAP宏来定义消息映射。

c++
// 构造函数
CMFCTEST1Dlg::CMFCTEST1Dlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_MFC_TEST1_DIALOG, pParent)
{
    // 省略
}

BEGIN_MESSAGE_MAP(CMFCTEST1Dlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    // 用来添加各种映射消息
END_MESSAGE_MAP()

BEGIN_MESSAGE_MAPEND_MESSAGE_MAP也都是个宏

  • BEGIN_MESSAGE_MAP有两个参数
    • 第一个是当前对话框类的名称
    • 第二个是对话框的基类的名称
  • END_MESSAGE_MAP宏标记消息映射的结束。

在创建好一个MFC项目之后,两个宏之间已经自动添加了部分消息

当我们在资源视图双击一个控件时,也会自动往这两个宏之前添加一个消息映射,例如下面添加一个按钮的点击消息

c++
BEGIN_MESSAGE_MAP(CMFCTEST1Dlg, CDialogEx)
	ON_BN_CLICKED(IDOK, &CMFCTEST1Dlg::OnBnClickedOk)
END_MESSAGE_MAP()

给控件添加消息时

  • 一般第一个参数是控件的ID,可以在属性视图看到
  • 第二个是该消息处理函数的地址,这个函数会在对话框的头文件生成,下面继续

2.3 声明消息处理函数

声明消息处理函数要在相应对话框类的头文件中声明

c++
class CMFCTEST1Dlg : public CDialogEx
{
public:
	CMFCTEST1Dlg(CWnd* pParent = nullptr);	// 标准构造函数
// 省略其他
protected:
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedOk();
};

afx_msg也是一个宏,它代表着此函数是一个消息处理函数

2.4 定义函数

接下来需要在对话框类相应的cpp文件中,定义刚才声明的函数

c++
void CMFCTEST1Dlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	CDialogEx::OnOK();
}

以上就是MFC中,给一个空间添加事件的步骤,这些步骤一般在对话框编辑视图中,直接双击某个空间会自动生成相应控件常用的消息处理函数,例如button会生成点击事件

想要生成其他事件,可以点击属性视图中的事件页

但是MFC给一个控件自定义的消息很少,往往我们需要用到一个事件,但这个空间没有相应的自定义事件时,我们需要自己重写相应的控件类,后面会有介绍

MIT Licensed