04 消息映射

在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机会;

猜你喜欢

转载自blog.csdn.net/lifeshave/article/details/85390432
04