前言
消息映射是MFC内建的一个消息分发机制,只要利用数个宏以及固定形式的写法,就可以让Framework知道,一旦消息发生,该如何调用对应的消息处理函数。通俗来讲就是通过宏等技术手段,建立一个消息映射表,将每个窗口下的消息与消息处理函数用类似Map容器的方式进行一一对应。
映射原理
1、使用宏(“DECLARE_MESSAGE_MAP”)在“.h”头文件中声明消息映射表
2、使用宏(“BEGIN_MESSAGE_MAP”,“END_MESSAGE_MAP”)在“.cpp”文件中实现消息映射表
3、当MFC程序的某个窗口产生消息时,窗口类对象通过调用虚函数“GetMessageMap()”获取自身消息映射表。然后执行对应的消息处理函数。
数据结构
宏(“DECLARE_MESSAGE_MAP”)
宏(“BEGIN_MESSAGE_MAP”,“END_MESSAGE_MAP”)
1 //DECLARE_MESSAGE_MAP 2 #define DECLARE_MESSAGE_MAP() \ 3 protected: \ 4 static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \ 5 virtual const AFX_MSGMAP* GetMessageMap() const; \
1 //BEGIN_MESSAGE_MAP 2 BEGIN_MESSAGE_MAP(CHelloDlg, CDialogEx) 3 ON_WM_SYSCOMMAND() 4 ON_WM_PAINT() 5 ON_WM_QUERYDRAGICON() 6 ON_BN_CLICKED(IDC_BUTTON1, &CHelloDlg::OnBnClickedButton1) 7 END_MESSAGE_MAP()
结构体(“AFX_MSGMAP”)
结构体(“AFX_MSGMAP_ENTRY”)
1 //AFX_MSGMAP 2 struct AFX_MSGMAP 3 { 4 const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)(); 5 const AFX_MSGMAP_ENTRY* lpEntries; 6 };
1 //AFX_MSGMAP_ENTRY 2 struct AFX_MSGMAP_ENTRY 3 { 4 UINT nMessage; // windows message 5 UINT nCode; // control code or WM_NOTIFY code 6 UINT nID; // control ID (or 0 for windows messages) 7 UINT nLastID; // used for entries specifying a range of control id's 8 UINT_PTR nSig; // signature type (action) or pointer to message # 9 AFX_PMSG pfn; // routine to call (or special value) 10 }; 11 typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);
分析识别
编写Demo程序,逆向分析其消息映射表,手动定位“Button1”按钮事件,获取事件处理函数地址。
1 //Button1按钮,事件处理函数 2 void CHelloDlg::OnBnClickedButton1() 3 { 4 MessageBox(NULL, NULL); 5 }
未完待续...