Win32的消息循环机制是:
产生的消息交由操作系统,将其放到应用程序的消息队列中。应用程序通过GetMessage函数从这个队列中取出一条消息,由DispatchMessage函数把消息又交给操作系统,操作系统调用窗口过程函数WndProc进行处理。该函数利用switch-case结构来判断并响应对应的消息。
MFC消息映射机制:
具体的方法是:在每个能接收和处理消息的类中,定义一个消息和消息函数静态对照表,即消息映射表。消息和对应的消息处理函数是指针成对出现的,当需要处理消息时,程序就搜索对应的消息静态表,寻找是否有该消息,判断该类是否处理消息。如果有,则依照静态表找到并调用对应的消息处理函数。
下面是对应的消息响应函数的定义
1. 在对应的类的头文件中定义消息响应函数的原型,如:
// Generated message map functions
protected:
//{{AFX_MSG(CDrawView)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
在DECLARE_MESSAGE_MAP()这个宏之上有两个AFG-MSG的注释宏。它们之间的3条语句的就是本头文件对应的类的消息响应函数的原型,此例中它们分别对应了(鼠标左键按下、弹起和鼠标移动)。
2. 在对应的类的源文件中的消息映射宏
BEGIN_MESSAGE_MAP(CDrawView, CView)
//{{AFX_MSG_MAP(CDrawView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
上述代码中BEGIN_MESSAGE_MAP(CDrawView, CView)和END_MESSAGE_MAP()之间的就是消息映射表,它们与对应的消息响应函数关联起来。
3. 在相对应类源文件中消息响应函数的定义
在经历了上述两步之后,剩下的当然就是,对消息响应函数的实现了。
总结:
通过以上分析,一个MFC消息映射函数在程序中有三处相关的信息:函数原型、函数实现,及用来关联消息和消息响应函数的宏。
在头文件中AFX_MSG注释宏之间的是消息响应函数原型的声明;
在源文件中两处:
一个在在AFX_MSG_MAP之间注释映射宏,通过它把消息和消息响应函数关联起来:
另一个在源文件中的消息响应函数的实现代码。
内部实现消息映射的OnWndMsgs函数处理消息
首先:判断是否有消息响应函数。方法是:在响应窗口类中查找所需的消息响应函数,由于传递给WindProc函数的是窗口类的指针,所以,OnWndMsg函数到响应的头文件中查找,看看DECLARE_MESSAGE_MAP()之上,两个AFG-MSG的注释宏之间是否有响应的消息响应函数原型声明,再到子类的源文件中,看看BEGIN_MESSAGE_MAP()和END_MESSAGE_MAP() 之间的是否有响应消息映射宏。
再次,有以上步骤就找到消息响应函数,那么接下来调用消息响应函数,对消息进行处理。