在MFC生成的类中,我们会发现几处使用宏的地方,如下
DECLARE_MESSAGE_MAP()
BEGIN_MESSAGE_MAP(CMFCHelloDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
END_MESSAGE_MAP()
声明的宏是什么?
这里就是提供消息循环的地方,这里可以避免使用冗长的虚表,因为如果每个类对他可能接收的消息都有一个虚函数,那么就需要过多的虚表,占用较多的内存空间。
而使用宏只需要将一个消息与与一个成员函数进行关联,也就是绑定,可以利用专门的算法进行快速匹配。
1. 声明消息映射:DECLARE_MESSAGE_MAP()
在库函数中我们可以找到这个宏的定义:
#define DECLARE_MESSAGE_MAP() \
protected: \
static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
virtual const AFX_MSGMAP* GetMessageMap() const; \
这里面就是就是定义为如下两个保护函数:protected:
static const AFX_MSGMAP* PASCAL GetThisMessageMap(); //一个static函数,返回消息映射的
virtual const AFX_MSGMAP* GetMessageMap() const; //一个虚函数,可以被子类继承并重写
这里面的AFX_MSGMAP如下:
struct AFX_MSGMAP
{
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)(); //定义了一个基类函数指针,返回值为const AFX_MSGMAP
const AFX_MSGMAP_ENTRY* lpEntries; //定义了一个指向消息映射结构的指针,返回值为const AFX_MSGMAP_ENTRY
};
而AFX_MSGMAP_ENTRY结构体定义了消息的参数和处理函数
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; // windows message 消息ID
UINT nCode; // control code or WM_NOTIFY code
UINT nID; // control ID (or 0 for windows messages)
UINT nLastID; // used for entries specifying a range of control id's
UINT_PTR nSig; // signature t