Windows消息的查找和匹配

CWnd或者派生類的對(duì)象調(diào)用OnWndMsg搜索本對(duì)象或者基類的消息映射數(shù)組,尋找當(dāng)前消息的消息處理函數(shù)。如果當(dāng)前對(duì)象或者基類處理了當(dāng)前消息,則必定在其中一個(gè)類的消息映射數(shù)組中匹配到當(dāng)前消息的處理函數(shù)。

消息匹配是一個(gè)比較耗時(shí)的任務(wù),為了提高效率,MFC設(shè)計(jì)了一個(gè)消息緩沖池,把要處理的消息和匹配到的消息映射條目(條目包含了消息處理函數(shù)的地址)以及進(jìn)行消息處理的當(dāng)前類等信息構(gòu)成一條緩沖信息,放到緩沖池中。如果以后又有同樣的消息需要同一個(gè)類處理,則直接從緩沖池查找到對(duì)應(yīng)的消息映射條目就可以了。

MFC用哈希查找來(lái)查詢消息映射緩沖池。消息緩沖池相當(dāng)于一個(gè)哈希表,它是應(yīng)用程序的一個(gè)全局變量,可以放512條最新用到的消息映射條目的緩沖信息,每一條緩沖信息是哈希表的一個(gè)入口。

采用AFX_MSG_CACHE結(jié)構(gòu)描述每條緩沖信息,其定義如下:

struct AFX_MSG_CACHE

{

UINT nMsg;

const AFX_MSGMAP_ENTRY* lpEntry;

const AFX_MSGMAP* pMessageMap;

};

nMsg存放消息ID,每個(gè)哈希表入口有不同的nMsg。

lpEnty存放和消息ID匹配的消息映射條目的地址,它可能是this所指對(duì)象的類的映射條目,也可能是這個(gè)類的某個(gè)基類的映射條目,也可能是空。

pMessageMap存放消息處理函數(shù)匹配成功時(shí)進(jìn)行消息處理的當(dāng)前類(this所指對(duì)象的類)的靜態(tài)成員變量messageMap的地址,它唯一的標(biāo)識(shí)了一個(gè)類(每個(gè)類的messageMap變量都不一樣)。

this所指對(duì)象是一個(gè)CWnd或其派生類的實(shí)例,是正在處理消息的MFC窗口對(duì)象。

哈希查找:使用消息ID的值作為關(guān)鍵值進(jìn)行哈希查找,如果成功,即可從lpEntry獲得消息映射條目的地址,從而得到消息處理函數(shù)及其原型。

如何判斷是否成功匹配呢?有兩條標(biāo)準(zhǔn):

第一,當(dāng)前要處理的消息message在哈希表(緩沖池)中有入口;第二,當(dāng)前窗口對(duì)象(this所指對(duì)象)的類的靜態(tài)變量messageMap的地址應(yīng)該等于本條緩沖信息的pMessagMap。MFC通過(guò)虛擬函數(shù)GetMessagMap得到messageMap的地址。

如果在消息緩沖池中沒(méi)有找到匹配,則搜索當(dāng)前對(duì)象的消息映射數(shù)組,看是否有合適的消息處理函數(shù)。

如果匹配到一個(gè)消息處理函數(shù),則把匹配結(jié)果加入到消息緩沖池中,即填寫(xiě)該條消息對(duì)應(yīng)的哈希表入口:

nMsg=message;

pMessageMap=this->GetMessageMap;

lpEntry=查找結(jié)果

然后,調(diào)用匹配到的消息處理函數(shù)。否則(沒(méi)有找到),使用_GetBaseMessageMap得到基類的消息映射數(shù)組,查找和匹配;直到匹配成功或搜尋了所有的基類(到CCmdTarget)為止。

如果最后沒(méi)有找到,則也把該條消息的匹配結(jié)果加入到緩沖池中。和匹配成功不同的是:指定lpEntry為空。這樣OnWndMsg返回,把控制權(quán)返還給AfxCallWndProc函數(shù),AfxCallWndProc將繼續(xù)調(diào)用DefWndProc進(jìn)行缺省處理。

消息映射數(shù)組的搜索在CCmdTarget::OnCmdMsg函數(shù)中也用到了,而且算法相同。為了提高速度,MFC把和消息映射數(shù)組條目逐一比較、匹配的函數(shù)AfxFindMessageEntry用匯編書(shū)寫(xiě)。

const AFX_MSGMAP_ENTRY* AFXAPI

AfxFindMessageEntry(const AFX_MSGMAP_ENTRY* lpEntry,

UINT nMsg, UINT nCode, UINT nID)

第一個(gè)參數(shù)是要搜索的映射數(shù)組的入口;第二個(gè)參數(shù)是Windows消息標(biāo)識(shí);第三個(gè)參數(shù)是控制通知消息標(biāo)識(shí);第四個(gè)參數(shù)是命令消息標(biāo)識(shí)。

對(duì)Windows消息來(lái)說(shuō),nMsg是每條消息不同的,nID和nCode為0。

對(duì)命令消息來(lái)說(shuō),nMsg固定為WM_COMMAND,nID是每條消息不同,nCode都是CN_COMMAND(定義為0)。

對(duì)控制通知消息來(lái)說(shuō),nMsg固定為WM_COMMAND或者WM_NOTIFY,nID和nCode是每條消息不同。

對(duì)于Register消息,nMsg指定為0XC000,nID和nCode為0。在使用函數(shù)AfxFindMessageEntry得到匹配結(jié)果之后,還必須判斷nSig是否等于message,只有相等才調(diào)用對(duì)應(yīng)的消息處理函數(shù)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 來(lái)自:http://blog.csdn.net/liyi268/article/details/623391 作為...
    Caiaolun閱讀 5,761評(píng)論 1 4
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,721評(píng)論 0 5
  • windows消息機(jī)制(MFC) 消息分類與消息隊(duì)列 Windows中,消息使用統(tǒng)一的結(jié)構(gòu)體(MSG)來(lái)存放信息,...
    北風(fēng)知我意閱讀 5,612評(píng)論 0 1
  • 1.面向?qū)ο蟮某绦蛟O(shè)計(jì)思想是什么? 答:把數(shù)據(jù)結(jié)構(gòu)和對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行操作的方法封裝形成一個(gè)個(gè)的對(duì)象。 2.什么是類?...
    少帥yangjie閱讀 5,125評(píng)論 0 14
  • 今天是這個(gè)周的最后一天,早晨我們吃完飯趕緊去學(xué)校,路上艾哲給我唱了“我愛(ài)北京天安門”經(jīng)典的老歌,百聽(tīng)不厭。 下午我...
    艾哲麻麻閱讀 196評(píng)論 0 0

友情鏈接更多精彩內(nèi)容