下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
MFC中消息映射機(jī)制分析
摘要:MFC以層次結(jié)構(gòu)組織起來,比較龐雜,尤其是它的消息映射機(jī)制,更是涉及到很多底層的東西。本文通過對(duì)整個(gè)消息映射機(jī)制進(jìn)行系統(tǒng)的分析,可以幫助程序開發(fā)人員更好地了解MFC,進(jìn)行可視化編程。關(guān)鍵詞:消息驅(qū)動(dòng);消息映射;MFC程序設(shè)計(jì)1引言微軟公司提供的MFC基本類庫(MicrosoftFoundationClasses),是進(jìn)行可視化編程時(shí)使用最為流行的一個(gè)類庫。MFC封裝了大部分WindowsAPI函數(shù)和Windows控件,使得程序的開發(fā)變得簡(jiǎn)單,極大的縮短了程序的開發(fā)周期。MFC獨(dú)創(chuàng)的Document/View框架結(jié)構(gòu),能夠?qū)⒐芾頂?shù)據(jù)的代碼和顯示數(shù)據(jù)的程序代碼分開,并且設(shè)計(jì)了一套方便的消息映射和命令傳遞機(jī)制,方便程序員的開發(fā)使用。其中消息映射機(jī)制本身比較龐大和復(fù)雜,對(duì)它的分析和了解無疑有助于我們寫出更為合理的高效的程序。這里我們分析一下MFC的消息映射機(jī)制,以了解MFC是如何對(duì)Windows的消息加以封裝,方便用戶的開發(fā)。2SDK下的消息機(jī)制實(shí)現(xiàn)首先,簡(jiǎn)單回顧一下SDK下我們是如何進(jìn)行Windows的程序開發(fā)的。Windows程序的運(yùn)行是依靠外部發(fā)生的事件來驅(qū)動(dòng)的,事件由操作系統(tǒng)捕捉,以消息的形式進(jìn)入消息隊(duì)列,然后通過消息循環(huán)從隊(duì)列中不斷取出消息,送到對(duì)應(yīng)的窗口過程里處理。相對(duì)于DOS程序,Windows是以WinMain作為程序的入口點(diǎn),以下就是一個(gè)簡(jiǎn)化的Win32程序的主體,通過while語句實(shí)現(xiàn)消息循環(huán):WinMain(…){MSGmsg;RegisterClass(…);//注冊(cè)窗口類CreateWindow(…);
//創(chuàng)建窗口ShowWindow(…);
//顯示窗口UpdateWindow(…);While(GetMessage(&msg,…)){//消息循環(huán)TranslateMessage(…);DispatchMessage(…);}returnmsg.wParam;}其中,msg代表消息,程序是通過GetMessage函數(shù)從和某個(gè)線程相對(duì)應(yīng)的消息隊(duì)列里面把消息取出來并放到消息變量msg里面。然后TranslateMessage函數(shù)用來把鍵盤消息轉(zhuǎn)化并放到響應(yīng)的消息隊(duì)列里面,最后DispatchMessage函數(shù)把消息分發(fā)到相關(guān)的窗口過程去處理。窗口過程根據(jù)消息的類型對(duì)不同的消息進(jìn)行相關(guān)的處理。在SDK編程過程中,用戶需要在窗口過程中分析消息的類型及其參數(shù)的含義,然后做不同的處理,相對(duì)比較麻煩;而MFC把消息調(diào)用的過程給封裝起來,使用戶能夠通過ClassWizard方便的使用和處理Windows的各種消息。3MFC中的消息映射機(jī)制在MFC的框架結(jié)構(gòu)下,“消息映射”是通過巧妙的宏定義,形成一張消息映射表格來進(jìn)行的。這樣一旦消息發(fā)生,F(xiàn)ramework就可以根據(jù)消息映射表格來進(jìn)行消息映射和命令傳遞。首先在需要進(jìn)行消息處理的類的頭文件(.H)里,都會(huì)含有DECLARE_MESSAGE_MAP()宏,聲明該類擁有消息映射表格:classCscribbleDoc:publicCdocument{
…DECLARE_MESSAGE_MAP()};然后在類應(yīng)用程序文件(.CPP)實(shí)現(xiàn)這一表格BEGIN_MESSAGE_MAP(CInheritClass,CBaseClass)
//{{AFX_MSG_MAP(CInheritClass)ON_COMMAND(ID_EDIT_COPY,OnEditCopy)………
//}}AFX_MSG_MAPEND_MESSAGE_MAP()這里主要進(jìn)行消息映射的實(shí)現(xiàn),把它和消息處理函數(shù)聯(lián)系在一起。其中出現(xiàn)三個(gè)宏,第一個(gè)宏是BEGIN_MESSAGE_MAP有兩個(gè)參數(shù),分別是擁有消息表格的類,及其父類。第二個(gè)宏是ON_COMMAND,指定命令消息的處理函數(shù)名稱。第三個(gè)宏是END_MESSAGE_MAP()作為結(jié)尾符號(hào)。中間的奇怪符號(hào)//}}和//{{,是ClassWizard產(chǎn)生的,對(duì)程序無影響。觀察DECLARE_MESSAGE_MAP的定義:#defineDECLARE_MESSAGE_MAP()\private:\staticconstAFX_MESSAGE_ENTRY_messageEntries[];\protected:\staticAFX_DATAconstAFX_MSGMAPmessageMap;\virtualconstAFX_MSGMAP*GetMessageMap()const;\里面又包含了MFC新定義的兩個(gè)數(shù)據(jù)結(jié)構(gòu),如下:AFX_MSGMAP_ENTRYstructAFX_MSGMAP_ENTRY{
UINTnMessage;//windowsmessage
UINTnCode;
//controlcodeorWM_NOTIFYcode
UINTnID;//controlID(or0forwindowsmessages)
UINTnLastID;
//usedforentriesspecifyingarangeofcontrolid's
UINTnSig;
//signaturetype(action)orpointertomessage#
AFX_PMSGpfn;
//routinetocall(orspecialvalue)};和AFX_MSGMAPstructAFX_MSGMAP{
constAFX_MSGMAP*pBaseMap;
constAFX_MSGMAP_ENTRY*lpEntries;};其中AFX_MSGMAP_ENTRY結(jié)構(gòu)包含了一個(gè)消息的所有相關(guān)信息,而AFX_MSGMAP主要作用有兩個(gè),一是用來得到基類的消息映射入口地址。二是得到本身的消息映射入口地址。實(shí)際上,MFC把所有的消息一條條填入到AFX_MSGMAP_ENTRY結(jié)構(gòu)中去,形成一個(gè)數(shù)組,該數(shù)組存放了所有的消息和與它們相關(guān)的參數(shù)。同時(shí)通過AFX_MSGMAP能得到該數(shù)組的首地址,同時(shí)得到基類的消息映射入口地址。當(dāng)本身對(duì)該消息不響應(yīng)的時(shí)候,就可以上溯到基類的消息映射表尋找對(duì)應(yīng)的消息響應(yīng)。現(xiàn)在我們來分析MFC是如何讓窗口過程來處理消息的,實(shí)際上所有MFC的窗口類都通過鉤子函數(shù)_AfxCbtFilterHook截獲消息,并且在鉤子函數(shù)_AfxCbtFilterHook中把窗口過程設(shè)定為AfxWndProc。原來的窗口過程保存在成員變量m_pfnSuper中。在MFC框架下,一般一個(gè)消息的處理過程是這樣的。(1)函數(shù)AfxWndProc接收Windows操作系統(tǒng)發(fā)送的消息。(2)函數(shù)AfxWndProc調(diào)用函數(shù)AfxCallWndProc進(jìn)行消息處理,這里一個(gè)進(jìn)步是把對(duì)句柄的操作轉(zhuǎn)換成對(duì)CWnd對(duì)象的操作。(3)函數(shù)AfxCallWndProc調(diào)用CWnd類的方法WindowProc進(jìn)行消息處理。(4)WindowProc調(diào)用OnWndMsg進(jìn)行正式的消息處理,即把消息派送到相關(guān)的方法中去處理。在CWnd類中都保存了一個(gè)AFX_MSGMAP的結(jié)構(gòu),而在AFX_MSGMAP結(jié)構(gòu)中保存有所有我們用ClassWizard生成的消息的數(shù)組的入口,我們把傳給OnWndMsg的message和數(shù)組中的所有的message進(jìn)行比較,找到匹配的那一個(gè)消息。實(shí)際上系統(tǒng)是通過函數(shù)AfxFindMessageEntry來實(shí)現(xiàn)的。找到了那個(gè)message,實(shí)際上我們就得到一個(gè)AFX_MSGMAP_ENTRY結(jié)構(gòu),而我們?cè)谏厦嬉呀?jīng)提到AFX_MSGMAP_ENTRY保存了和該消息相關(guān)的所有信息,其中主要是消息的動(dòng)作標(biāo)識(shí)和相關(guān)的執(zhí)行函數(shù)。然后我們就可以根據(jù)消息的動(dòng)作標(biāo)識(shí)調(diào)用相關(guān)的執(zhí)行函數(shù),而這個(gè)執(zhí)行函數(shù)實(shí)際上就是通過ClassWizard在類實(shí)現(xiàn)中定義的一個(gè)方法。這樣就把消息的處理轉(zhuǎn)化到類中的一個(gè)方法的實(shí)現(xiàn)上。(5)如果OnWndMsg方法沒有對(duì)消息進(jìn)行處理的話,就調(diào)用DefWindowProc對(duì)消息進(jìn)行處理。這是實(shí)際上是調(diào)用原來的窗口過程進(jìn)行缺省的消息處理。所以如果正常的消息處理的話,MFC窗口類是完全脫離了原來的窗口過程,用自己的一套體系結(jié)構(gòu)實(shí)現(xiàn)消息的映射和處理。即先調(diào)用MFC窗口類掛上去的窗口過程,再調(diào)用原先的窗口過程。用戶面對(duì)的消息參數(shù)將不再是固定的wParam和lParam,而是和消息類型具體相關(guān)的參數(shù)。比如和消息WM_LButtonDown相對(duì)應(yīng)的方法OnLButtonDown的兩個(gè)參數(shù)是nFlags和point。nFlags表示在按下鼠標(biāo)左鍵的時(shí)候是否有其他虛擬鍵按下,point更簡(jiǎn)單,就是表示鼠標(biāo)的位置。同時(shí)MFC窗口類消息傳遞中還提供了兩個(gè)函數(shù),分別為WalkPreTranslateTree和PreTranslateMessage。我們知道利用MFC框架生成的程序,都是從CWinApp開始執(zhí)行的,而CWinapp實(shí)際繼承了CWinThread類。在CWinThread的運(yùn)行過程中會(huì)調(diào)用窗口類中的WalkPreTranslateTree方法。而WalkPreTranslateTree方法實(shí)際上就是從當(dāng)前窗口開始查找愿意進(jìn)行消息翻譯的類,直到找到窗口沒有父類為止。在WalkPreTranslateTree方法中調(diào)用了PreTranslateMessage方法。實(shí)際上PreTranslateMessage最大的好處是我們?cè)谙⑻幚砬翱梢栽谶@個(gè)方法里面先做一些事情。舉一個(gè)簡(jiǎn)單的例子,比如我們希望在一個(gè)CEdit對(duì)象里,把所有的輸入的字母都以大寫的形式出現(xiàn)。我們只需要
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 小學(xué)新教師的培訓(xùn)工作計(jì)劃范文
- 2025初三新學(xué)期個(gè)人學(xué)習(xí)計(jì)劃書2
- 幼兒園中秋節(jié)活動(dòng)計(jì)劃
- 公司業(yè)務(wù)員個(gè)人工作回顧及發(fā)展計(jì)劃
- 2025稅務(wù)部門年終工作計(jì)劃
- 門五金商業(yè)計(jì)劃書
- “工會(huì)計(jì)劃學(xué)?!惫?huì)工作計(jì)劃
- 2025語文一年級(jí)下冊(cè)學(xué)期教學(xué)計(jì)劃
- 《地震地質(zhì)基礎(chǔ)》課件
- 《地鐵暗挖施工工法》課件
- 2025年天津高中學(xué)業(yè)水平合格性考試政治試卷試題(含答案解析)
- 小學(xué)六年級(jí)家長(zhǎng)會(huì)課件
- 2024 年學(xué)校教務(wù)副校長(zhǎng)述職:以教育改革創(chuàng)新鑄學(xué)校卓越發(fā)展
- 【MOOC】馬克思主義基本原理-華東師范大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 福建省泉州市四校2024-2025學(xué)年高三上學(xué)期第一次聯(lián)考語文試題(含答案)
- 河北省邯鄲市2023-2024學(xué)年高二上學(xué)期期末質(zhì)量檢測(cè)數(shù)學(xué)試題
- 【MOOC】財(cái)務(wù)管理-四川大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 【MOOC】電子技術(shù)實(shí)驗(yàn)-北京科技大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 2024年律師事務(wù)所工作計(jì)劃(7篇)
- 2024屆高考語文詩歌復(fù)習(xí)教考融合之《李憑箜篌引》(含解析)
- 臨床提高膿毒性休克患者1h集束化措施落實(shí)率PDCA品管圈
評(píng)論
0/150
提交評(píng)論