版權聲明:本文爲博主原創文章,遵循 CC 4.0 by-sa 版權協議,轉載請附上原文出處連接和本聲明。
本文連接:https://blog.csdn.net/luoti784600/article/details/10070939
MFC的消息映射對於對開發者處理消息可謂十分方便。MFC類繼承衆多,虛函數表佔內存大致使微軟直接不採用虛函數方式。發現《VC++深刻詳解》只大概說了消息映射的原理,沒有詳細介紹其實現,因此寫篇小文章探究下。數組
1、首先在使用消息映射以前,必須先聲明DECLARE_MESSAGE_MAP()緩存
DECLARE_MESSAGE_MAP()是個宏定義,對應的源碼爲:函數
#define DECLARE_MESSAGE_MAP()
private:
static const AFX_MSGMAP_ENTRY _messageEntries[];
protected:
static AFX_DATA const AFX_MSGMAP messageMap;
static const AFX_MSGMAP* PASCAL _GetBaseMessageMap();
virtual const AFX_MSGMAP* GetMessageMap() const; .net
聲明添加了兩個成員變量和兩個成員函數:設計
_messageEntries: 是一個AFX_MSGMAP_ENTRY(定義了消息路由)類型數組,即路由表。指針
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; //消息類型
UINT nCode; // 控制碼
UINT nID; // 控件ID
UINT nLastID; // 控件ID範圍, 對於單控件消息處理,與nID相同
UINT nSig; // 信號類型
AFX_PMSG pfn; //回調函數,即處理函數
};blog
messageMap: 路由信息,包含父類路由信息指針,和本類的路由表指針。繼承
struct AFX_MSGMAP
{
const AFX_MSGMAP* pBaseMap; //指向父類的指針
const AFX_MSGMAP_ENTRY* lpEntries; //路由表指針
};遞歸
2、接着咱們查看BEGIN_MESSAGE_MAP在.cpp文件中的定義內存
BEGIN_MESSAGE_MAP(CMfc_testApp, CWinApp)
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
END_MESSAGE_MAP()
能夠看到BEGIN_MESSAGE_MAP也是一個宏。而後上面的ON_COMMAND也是宏定義,所有展開後代碼爲:
const AFX_MSGMAP* theClass::GetMessageMap() const
{
return &theClass::messageMap;
}
const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap()
{
return &baseClass::messageMap;
}
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap =
{
&baseClass::messageMap, //基類路由信息指針
&theClass::_messageEntries[0] //路由表數組地址
};
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] =
{
{WM_COMMAND,N_COMMAND,(WORD)id,(WORD)id,AfxSig_vv,(AFX_PMSG)&memberFxn },
{0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
};
能夠看到,經過宏定義和消息內嵌的方式,已經所有初始化消息路由相關的成員變量和方法,結構以下圖所示:
3、而後消息循環:CWnd::OnWndMsg(位於WINCORE.cpp文件中)
if (message == pMsgCache->nMsg && pMessageMap == pMsgCache->pMessageMap)
{
//處理在當前類的路由表和緩存命中
}
else
{
// 當前類路由表和緩存找不到,
pMsgCache->nMsg = message;
pMsgCache->pMessageMap = pMessageMap;
//經過pMessageMap = pMessageMap->pBaseMap遞歸往基類深刻查找匹配
for (; pMessageMap != NULL; pMessageMap = pMessageMap->pBaseMap)
{
.....
}
.....
}
總結:
不得不佩服MS牛人在那個年代已經有那麼先進的設計思想!!!
———————————————— 版權聲明:本文爲CSDN博主「luoti784600」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處連接及本聲明。 原文連接:https://blog.csdn.net/luoti784600/article/details/10070939/