在Win32编程中,我们已经意识到消息的重要性,它是一个程序运行的动力源泉!在MFC中它的消息机制就叫消息映射机制;
消息映射是MFC内建的一个消息分派机制,只要运用数个宏,以及固定形式的写法,类似填表格,就可以让我们的框架知道,一旦消息发生,应该往哪一个类去传递,每一个类只能拥有一个消息映射表格,也可以没有;这些关键的宏有三个,分别为:
DECLARE_MESSAGE_MAP
BEGIN_MESSAGE_MAP
END_MESSAGE_MAP
同样我们用00篇的示例程序加些代码来演示消息映射的使用,代码如下:
/*
*HelloMFC.h
*/
#ifndef _HELLO_MFC_
#define _HELLO_MFC_
class CMyApp : public CWinApp{
public:
virtual BOOL InitInstance();
};
class CMainWindow : public CFrameWnd{
public:
CMainWindow();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
};
#endif
/*
*HelloMFC.cpp
*/
#include <afxwin.h>
#include "HelloMFC.h"
CMyApp myApp;
BOOL CMyApp::InitInstance()
{
m_pMainWnd = new CMainWindow;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
BEGIN_MESSAGE_MAP(CMainWindow, CFrameWnd)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
CMainWindow::CMainWindow()
{
Create(NULL, TEXT("Hello MFC"));
}
void CMainWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
AfxMessageBox(TEXT("OnLeftButtonDown"));
}
接下来我们就把这三个宏替换回原来代码来看看,MFC到底怎么做的
/*
*HelloMFC.h
*/
#ifndef _HELLO_MFC_
#define _HELLO_MFC_
class CMyApp : public CWinApp{
public:
virtual BOOL InitInstance();
};
class CMainWindow : public CFrameWnd{
public:
CMainWindow();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//DECLARE_MESSAGE_MAP()
protected:
//这里我们将返回的结构体相关定义贴出来,以方便理解
/*
typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; // windows 消息
UINT nCode; // 控制码或通知码
UINT nID; // 命令消息ID (windows 消息为0)
UINT nLastID; // 命令消息的ID范围的终点
UINT_PTR nSig; // 消息动作标志
AFX_PMSG pfn; //函数指针,响应消息时执行的函数
};
struct AFX_MSGMAP
{
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
const AFX_MSGMAP_ENTRY* lpEntries;
};
*/
static const AFX_MSGMAP* PASCAL GetThisMessageMap();
virtual const AFX_MSGMAP* GetMessageMap() const;
};
#endif
/*
*HelloMFC.cpp
*/
#include <afxwin.h>
#include "HelloMFC.h"
CMyApp myApp;
BOOL CMyApp::InitInstance()
{
m_pMainWnd = new CMainWindow;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
//BEGIN_MESSAGE_MAP(CMainWindow, CFrameWnd)
const AFX_MSGMAP* CMainWindow::GetMessageMap() const
{
return GetThisMessageMap();
}
const AFX_MSGMAP* PASCAL CMainWindow::GetThisMessageMap()
{
typedef CMainWindow ThisClass;
typedef CFrameWnd TheBaseClass;
static const AFX_MSGMAP_ENTRY _messageEntries[] = {
//ON_WM_LBUTTONDOWN()
//AfxSig_vwp代表我们的消息相应函数应该定义成什么样 AfxSig枚举类型中定义了很多函数形式
{ WM_LBUTTONDOWN, 0, 0, 0, AfxSig_vwp,
(AFX_PMSG)(AFX_PMSGW) (static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, CPoint) > (&ThisClass::OnLButtonDown))
},
//END_MESSAGE_MAP()
{
0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0
}
};
static const AFX_MSGMAP messageMap = {
&TheBaseClass::GetThisMessageMap, &_messageEntries[0] };
return &messageMap;
}
CMainWindow::CMainWindow()
{
Create(NULL, TEXT("Hello MFC"));
}
void CMainWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
AfxMessageBox(TEXT("OnLeftButtonDown"));
}
MFC的三大消息类型:
1.标准消息
任何以WM打头的消息都属于标准消息(WM_COMMAND除外),在我们上面的例子使用的就是标准消息!
2.WM_COMMAND命令消息
这是来自菜单,工具条按钮、加速键等用户接口对象WM_COMMAND通知消息,属于应用程序自己定义的消息。通过消息映射机制,MFC框架把命令按一定的路径分发给多种类型的对象(具备消息处理能力)处理,如文档窗口,运用程序,文档模板等对象。能处理消息映射的消息须从CCmdTarget类派生;
3.控件通知
通常,控件通知在某些重要事件发生时,由控件窗口发送到父窗口,如打开一个组合框,控件通知为进一步控制子窗口提供了j机会;