版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、消息映射的實(shí)現(xiàn)1. Windows消息概述Windows應(yīng)用程序的輸入由Windows系統(tǒng)以消息的形式發(fā)送給應(yīng)用程序的窗口。這些窗口 通過(guò)窗口過(guò)程來(lái)接收和處理消息,然后把控制返還給Windowso消息的分類(lèi)隊(duì)列消息和非隊(duì)列消息從消息的發(fā)送途徑上看,消息分兩種:隊(duì)列消息和非隊(duì)列消息。隊(duì)列消息送到系統(tǒng)消息隊(duì)列, 然后到線(xiàn)程消息隊(duì)列;非隊(duì)列消息直接送給目的窗口過(guò)程。這里,對(duì)消息隊(duì)列闡述如下:Windows維護(hù)一個(gè)系統(tǒng)消息隊(duì)列(System message queue),每個(gè)GUI線(xiàn)程有一個(gè)線(xiàn)程消息 隊(duì)列(Thread message queue)。鼠標(biāo)、鍵盤(pán)事件由鼠標(biāo)或鍵盤(pán)驅(qū)動(dòng)程序轉(zhuǎn)換成輸入消息并把
2、消息放進(jìn)系統(tǒng)消息隊(duì)列,例如 WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAR 等等。Windows 每次從 系統(tǒng)消息隊(duì)列移走一個(gè)消息,確定它是送給哪個(gè)窗口的和這個(gè)窗口是由哪個(gè)線(xiàn)程創(chuàng)建的,然 后,把它放進(jìn)窗口創(chuàng)建線(xiàn)程的線(xiàn)程消息隊(duì)列。線(xiàn)程消息隊(duì)列接收送給該線(xiàn)程所創(chuàng)建窗口的消 息。線(xiàn)程從消息隊(duì)列取出消息,通過(guò)Windows把它送給適當(dāng)?shù)拇翱谶^(guò)程來(lái)處理。除了鍵盤(pán)、鼠標(biāo)消息以外,隊(duì)列消息還有WM_PAINT、WM_TIMER和WM_QUIT。這些隊(duì)列消息以外的絕大多數(shù)消息是非隊(duì)列消息。系統(tǒng)消息和應(yīng)用程序消息從消息的來(lái)源來(lái)看,可以分為:系統(tǒng)定義的消息和應(yīng)用程序定義的
3、消息。系統(tǒng)消息ID的范圍是從0到WM_USER-1,或0X80000到0XBFFFF;應(yīng)用程序消息從WM_USER (0X0400)到0X7FFF,或0XC000到0XFFFF; WM_USER到0X7FFF范圍的消息由應(yīng)用程序自己使用;0XC000到0XFFFF范圍的消息用來(lái)和其他應(yīng)用程序通信,為了 ID的唯一性,使 用:RegisterWindowMessage來(lái)得到該范圍的消息ID。消息結(jié)構(gòu)和消息處理消息的結(jié)構(gòu)為了從消息隊(duì)列獲取消息信息,需要使用MSG結(jié)構(gòu)。例如,:GetMessage函數(shù)(從消息隊(duì) 列得到消息并從隊(duì)列中移走)和:PeekMessage函數(shù)(從消息隊(duì)列得到消息但是可以不移
4、走) 都使用了該結(jié)構(gòu)來(lái)保存獲得的消息信息。MSG結(jié)構(gòu)的定義如下:typedefstructtagMSG / msgHWND hwnd;UINT message;WPARAM wParam;LPARAM lParam;DWORD time;POINT pt; MSG;該結(jié)構(gòu)包括了六個(gè)成員,用來(lái)描述消息的有關(guān)屬性:接收消息的窗口句柄、消息標(biāo)識(shí)(ID)、第一個(gè)消息參數(shù)、第二個(gè)消息參數(shù)、消息產(chǎn)生的時(shí) 間、消息產(chǎn)生時(shí)鼠標(biāo)的位置。應(yīng)用程序通過(guò)窗口過(guò)程來(lái)處理消息如前所述,每個(gè)窗口類(lèi)”都要登記一個(gè)如下形式的窗口過(guò)程:LRESULT CALLBACK MainWndProc (HWND hwnd,/ 窗口句柄U
5、INT msg,/消息標(biāo)識(shí)WPARAM wParam,/ 消息參數(shù) 1LPARAM lParam/ 消息參數(shù) 2)應(yīng)用程序通過(guò)窗口過(guò)程來(lái)處理消息:非隊(duì)列消息由Windows直接送給目的窗口的窗口過(guò)程, 隊(duì)列消息由:DispatchMessage等派發(fā)給目的窗口的窗口過(guò)程。窗口過(guò)程被調(diào)用時(shí),接受四個(gè) 參數(shù):a window handle (窗口句柄);a message identifier (消息標(biāo)識(shí));two 32-bit values called message parameters (兩個(gè) 32 位的消息參數(shù));需要的話(huà),窗口過(guò)程用:GetMessageTime獲取消息產(chǎn)生的時(shí)間,用:
6、GetMessagePos獲取消 息產(chǎn)生時(shí)鼠標(biāo)光標(biāo)所在的位置。在窗口過(guò)程里,用switch/case分支處理語(yǔ)句來(lái)識(shí)別和處理消息。應(yīng)用程序通過(guò)消息循環(huán)來(lái)獲得對(duì)消息的處理每個(gè)GDI應(yīng)用程序在主窗口創(chuàng)建之后,都會(huì)進(jìn)入消息循環(huán),接受用戶(hù)輸入、解釋和處理消息。 消息循環(huán)的結(jié)構(gòu)如下:while (GetMessage(&msg, (HWND) NULL, 0, 0) / 從消息隊(duì)列得到消息if (hwndDlgModeless = (HWND) NULL |!IsDialogMessage(hwndDlgModeless, &msg) &!TranslateAccelerator(hwndMain, h
7、accel, &msg) TranslateMessage(&msg);DispatchMessage(&msg); / 發(fā)送消息消息循環(huán)從消息隊(duì)列中得到消息,如果不是快捷鍵消息或者對(duì)話(huà)框消息,就進(jìn)行消息轉(zhuǎn)換和 派發(fā),讓目的窗口的窗口過(guò)程來(lái)處理。當(dāng)?shù)玫较M_QUIT,或者:GetMessage出錯(cuò)時(shí),退出消息循環(huán)。MFC消息處理使用MFC框架編程時(shí),消息發(fā)送和處理的本質(zhì)也如上所述。但是,有一點(diǎn)需要強(qiáng)調(diào)的是, 所有的MFC窗口都使用同一窗口過(guò)程,程序員不必去設(shè)計(jì)和實(shí)現(xiàn)自己的窗口過(guò)程,而是通 過(guò)MFC提供的一套消息映射機(jī)制來(lái)處理消息。因此,MFC簡(jiǎn)化了程序員編程時(shí)處理消息的 復(fù)雜性。所謂消息映
8、射,簡(jiǎn)單地講,就是讓程序員指定要某個(gè)MFC類(lèi)(有消息處理能力的類(lèi))處理 某個(gè)消息。MFC提供了工具ClassWizard來(lái)幫助實(shí)現(xiàn)消息映射,在處理消息的類(lèi)中添加一些 有關(guān)消息映射的內(nèi)容和處理消息的成員函數(shù)。程序員將完成消息處理函數(shù),實(shí)現(xiàn)所希望的消 息處理能力。如果派生類(lèi)要覆蓋基類(lèi)的消息處理函數(shù),就用ClassWizard在派生類(lèi)中添加一個(gè)消息映射條 目,用同樣的原型定義一個(gè)函數(shù),然后實(shí)現(xiàn)該函數(shù)。這個(gè)函數(shù)覆蓋派生類(lèi)的任何基類(lèi)的同名 處理函數(shù)。下面幾節(jié)將分析 MFC的消息機(jī)制的實(shí)現(xiàn)原理和消息處理的過(guò)程。為此,首先要分析 ClassWizard實(shí)現(xiàn)消息映射的內(nèi)幕,然后討論MFC的窗口過(guò)程,分析MFC
9、窗口過(guò)程是如何實(shí) 現(xiàn)消息處理的。消息映射的定義和實(shí)現(xiàn)1. MFC處理的三類(lèi)消息根據(jù)處理函數(shù)和處理過(guò)程的不同,MFC主要處理三類(lèi)消息:Windows消息,前綴以“WM_”打頭,WM_COMMAND例外。Windows消息直接送 給MFC窗口過(guò)程處理,窗口過(guò)程調(diào)用對(duì)應(yīng)的消息處理函數(shù)。一般,由窗口對(duì)象來(lái)處 理這類(lèi)消息,也就是說(shuō),這類(lèi)消息處理函數(shù)一般是MFC窗口類(lèi)的成員函數(shù)??刂仆ㄖ?,是控制子窗口送給父窗口的WM_COMMAND通知消息。窗口過(guò)程 調(diào)用對(duì)應(yīng)的消息處理函數(shù)。一般,由窗口對(duì)象來(lái)處理這類(lèi)消息,也就是說(shuō),這類(lèi)消 息處理函數(shù)一般是MFC窗口類(lèi)的成員函數(shù)。需要指出的是,Win32使用新的WM_
10、NOFITY來(lái)處理復(fù)雜的通知消息。WM_COMMAND類(lèi)型 的通知消息僅僅能傳遞一個(gè)控制窗口句柄(Iparam)、控制窗ID和通知代碼(wparam)。WM_NOTIFY能傳遞任意復(fù)雜的信息。命令消息,這是來(lái)自菜單、工具條按鈕、加速鍵等用戶(hù)接口對(duì)象的WM_COMMAND 通知消息,屬于應(yīng)用程序自己定義的消息。通過(guò)消息映射機(jī)制,MFC框架把命令按 一定的路徑分發(fā)給多種類(lèi)型的對(duì)象(具備消息處理能力)處理,如文檔、窗口、應(yīng) 用程序、文檔模板等對(duì)象。能處理消息映射的類(lèi)必須從CCmdTarget類(lèi)派生。在討論了消息的分類(lèi)之后,應(yīng)該是討論各類(lèi)消息如何處理的時(shí)候了。但是,要知道怎么處理 消息,首先要知道如何
11、映射消息。MFC消息映射的實(shí)現(xiàn)方法MFC使用ClassWizard幫助實(shí)現(xiàn)消息映射,它在源碼中添加一些消息映射的內(nèi)容,并聲明和 實(shí)現(xiàn)消息處理函數(shù)。現(xiàn)在來(lái)分析這些被添加的內(nèi)容。在類(lèi)的定義(頭文件)里,它增加了消息處理函數(shù)聲明,并添加一行聲明消息映射的宏 DECLARE_MESSAGE_MAP。在類(lèi)的實(shí)現(xiàn)(實(shí)現(xiàn)文件)里,實(shí)現(xiàn)消息處理函數(shù),并使用IMPLEMENT_MESSAGE_MAP宏實(shí) 現(xiàn)消息映射。一般情況下,這些聲明和實(shí)現(xiàn)是由MFC的ClassWizard自動(dòng)來(lái)維護(hù)的??匆粋€(gè) 例子:在AppWizard產(chǎn)生的應(yīng)用程序類(lèi)的源碼中,應(yīng)用程序類(lèi)的定義(頭文件)包含了類(lèi)似如下 的代碼:/AFX_MS
12、G(CTttApp)afx_msg void OnAppAbout();/AFX_MSGDECLARE_MESSAGE_MAP()應(yīng)用程序類(lèi)的實(shí)現(xiàn)文件中包含了類(lèi)似如下的代碼:BEGIN_MESSAGE_MAP(CTApp, CWinApp)/AFX_MSG_MAP(CTttApp)ON_COMMAND(ID_APP_ABOUT, OnAppAbout)/AFX_MSG_MAPEND_MESSAGE_MAP()頭文件里是消息映射和消息處理函數(shù)的聲明,實(shí)現(xiàn)文件里是消息映射的實(shí)現(xiàn)和消息處理函數(shù) 的實(shí)現(xiàn)。它表示讓?xiě)?yīng)用程序?qū)ο筇幚砻钕D_APP_ABOUT,消息處理函數(shù)是OnAppAbout。 為
13、什么這樣做之后就完成了一個(gè)消息映射?這些聲明和實(shí)現(xiàn)到底作了些什么呢?接著,將討 論這些問(wèn)題。在聲明與實(shí)現(xiàn)的內(nèi)部DECLARE_MESSAGE_MAP 宏:首先,看DECLARE_MESSAGE_MAP宏的內(nèi)容:#ifdef _AFXDLL#define DECLARE_MESSAGE_MAP() private: staticconst AFX_MSGMAP_ENTRY _messageEntries; protected: static AFX_DATA const AFX_MSGMAP messageMap; staticconst AFX_MSGMAP* PASCAL _GetBaseM
14、essageMap(); virtualconst AFX_MSGMAP* GetMessageMap() const; #else#define DECLARE_MESSAGE_MAP() private: staticconst AFX_MSGMAP_ENTRY _messageEntries; protected: static AFX_DATA const AFX_MSGMAP messageMap; virtualconst AFX_MSGMAP* GetMessageMap() const; #endifDECLARE_MESSAGE_MAP定義了兩個(gè)版本,分別用于靜態(tài)或者動(dòng)態(tài)鏈接
15、到MFC DLL的情形。BEGIN_MESSAE_MAP 宏然后,看BEGIN_MESSAE_MAP宏的內(nèi)容:#ifdef _AFXDLL#define BEGIN_MESSAGE_MAP(theClass, baseClass) const AFX_MSGMAP* PASCAL theClass:_GetBaseMessageMap() return&baseClass:messageMap; const AFX_MSGMAP* theClass:GetMessageMap() const return&theClass:messageMap; AFX_DATADEF const AFX_M
16、SGMAP theClass:messageMap = &theClass:_GetBaseMessageMap, &theClass:_messageEntries0 ; const AFX_MSGMAP_ENTRY theClass:_messageEntries = #else#define BEGIN_MESSAGE_MAP(theClass, baseClass) const AFX_MSGMAP* theClass:GetMessageMap() const return&theClass:messageMap; AFX_DATADEF const AFX_MSGMAP theCl
17、ass:messageMap = &baseClass:messageMap, &theClass:_messageEntries0 ; const AFX_MSGMAP_ENTRY theClass:_messageEntries = #endif#define END_MESSAGE_MAP() 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 ; 對(duì)應(yīng)地,BEGIN_MESSAGE_MAP定義了兩個(gè)版本,分別用于靜態(tài)或者動(dòng)態(tài)鏈接到MFC DLL的情形。END_MESSAGE_MAP相對(duì)簡(jiǎn)單,就只有一種定義。ON_COMMAND 宏最后,看ON_COMMAND宏的內(nèi)容
18、:#define ON_COMMAND(id, memberFxn) WM_COMMAND,CN_COMMAND,(WORD)id,(WORD)id,AfxSig_vv,(AFX_PMSG)memberFxn;1.消息映射聲明的解釋在清楚了有關(guān)宏的定義之后,現(xiàn)在來(lái)分析它們的作用和功能。消息映射聲明的實(shí)質(zhì)是給所在類(lèi)添加幾個(gè)靜態(tài)成員變量和靜態(tài)或虛擬函數(shù),當(dāng)然它們是與消 息映射相關(guān)的變量和函數(shù)。1.成員變量有兩個(gè)成員變量被添加,第一個(gè)是_messageEntries,第二個(gè)是messageMap。第一個(gè)成員變量的聲明:AFX_MSGMAP_ENTRY _messageEntries這是一個(gè)AFX_M
19、SGMAP_ENTRY類(lèi)型的數(shù)組變量,是一個(gè)靜態(tài)成員變量,用來(lái)容納類(lèi)的消息 映射條目。一個(gè)消息映射條目可以用AFX_MSGMAP_ENTRY結(jié)構(gòu)來(lái)描述。AFX_MSGMAP_ENTRY結(jié)構(gòu)的定義如下:struct AFX_MSGMAP_ENTRY/Windows 消息 IDUINT nMessage;/控制消息的通知碼UINT nCode;/Windows Control 的 IDUINT nID;/如果是一定范圍的消息被映射,則nLastID指定其范圍UINT nLastID;UINT nSig;/消息的動(dòng)作標(biāo)識(shí)/ 響應(yīng)消息時(shí)應(yīng)執(zhí)行的函數(shù)(routine to call (or specia
20、l value)AFX_PMSG pfn;從上述結(jié)構(gòu)可以看出,每條映射有兩部分的內(nèi)容:第一部分是關(guān)于消息ID的,包括前四個(gè) 域;第二部分是關(guān)于消息對(duì)應(yīng)的執(zhí)行函數(shù),包括后兩個(gè)域。在上述結(jié)構(gòu)的六個(gè)域中,pfn是一個(gè)指向CCmdTarger成員函數(shù)的指針。函數(shù)指針的類(lèi)型定義 如下:typedef void (AFX_MSG_CALL CCmdTarget:*AFX_PMSG)(void);當(dāng)使用一條或者多條消息映射條目初始化消息映射數(shù)組時(shí),各種不同類(lèi)型的消息函數(shù)都被轉(zhuǎn) 換成這樣的類(lèi)型:不接收參數(shù),也不返回參數(shù)的類(lèi)型。因?yàn)樗锌梢杂邢⒂成涞念?lèi)都是從 CCmdTarge派生的,所以可以實(shí)現(xiàn)這樣的轉(zhuǎn)換。
21、nSig是一個(gè)標(biāo)識(shí)變量,用來(lái)標(biāo)識(shí)不同原型的消息處理函數(shù),每一個(gè)不同原型的消息處理函數(shù) 對(duì)應(yīng)一個(gè)不同的nSig。在消息分發(fā)時(shí),MFC內(nèi)部根據(jù)nSig把消息派發(fā)給對(duì)應(yīng)的成員函數(shù)處 理,實(shí)際上,就是根據(jù)nSig的值把pfn還原成相應(yīng)類(lèi)型的消息處理函數(shù)并執(zhí)行它。第二個(gè)成員變量的聲明AFX_MSGMAP messageMap;這是一個(gè)AFX_MSGMAP類(lèi)型的靜態(tài)成員變量,從其類(lèi)型名稱(chēng)和變量名稱(chēng)可以猜出,它是一 個(gè)包含了消息映射信息的變量。的確,它把消息映射的信息(消息映射數(shù)組)和相關(guān)函數(shù)打 包在一起,也就是說(shuō),得到了一個(gè)消息處理類(lèi)的該變量,就得到了它全部的消息映射數(shù)據(jù)和 功能。AFX_MSGMAP結(jié)構(gòu)
22、的定義如下:struct AFX_MSGMAP/得到基類(lèi)的消息映射入口地址的數(shù)據(jù)或者函數(shù)#ifdef _AFXDLL/pfnGetBaseMap 指向_GetBaseMessageMap 函數(shù)const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();#else/pBaseMap保存基類(lèi)消息映射入口_messageEntries的地址const AFX_MSGMAP* pBaseMap;#endif/lpEntries保存消息映射入口_messageEntries的地址const AFX_MSGMAP_ENTRY* lpEntries;從上面的定義可以看出,通過(guò)me
23、ssageMap可以得到類(lèi)的消息映射數(shù)組_messageEntries和函 數(shù)_GetBaseMessageMap的地址(不使用MFC DLL時(shí),是基類(lèi)消息映射數(shù)組的地址)。1.成員函數(shù)_GetBaseMessageMap()用來(lái)得到基類(lèi)消息映射的函數(shù)。GetMessageMap()用來(lái)得到自身消息映射的函數(shù)。1.消息映射實(shí)現(xiàn)的解釋消息映射實(shí)現(xiàn)的實(shí)質(zhì)是初始化聲明中定義的靜態(tài)成員函數(shù)_messageEntries和messageMap, 實(shí)現(xiàn)所聲明的靜態(tài)或虛擬函數(shù)GetMessageMap、_GetBaseMessageMap。這樣,在進(jìn)入WinMain函數(shù)之前,每個(gè)可以響應(yīng)消息的MFC類(lèi)都生成
24、了一個(gè)消息映射表, 程序運(yùn)行時(shí)通過(guò)查詢(xún)?cè)摫砼袛嗍欠裥枰憫?yīng)某條消息。1.對(duì)消息映射入口表(消息映射數(shù)組)的初始化如前所述,消息映射數(shù)組的元素是消息映射條目,條目的格式符合結(jié)構(gòu) AFX_MESSAGE_ENTRY的描述。所以,要初始化消息映射數(shù)組,就必須使用符合該格式的數(shù) 據(jù)來(lái)填充:如果指定當(dāng)前類(lèi)處理某個(gè)消息,則把和該消息有關(guān)的信息(四個(gè))和消息處理函 數(shù)的地址及原型組合成為一個(gè)消息映射條目,加入到消息映射數(shù)組中。顯然,這是一個(gè)繁瑣的工作。為了簡(jiǎn)化操作,MFC根據(jù)消息的不同和消息處理方式的不同, 把消息映射劃分成若干類(lèi)別,每一類(lèi)的消息映射至少有一個(gè)共性:消息處理函數(shù)的原型相同。 對(duì)每一類(lèi)消息映射
25、,MFC定義了一個(gè)宏來(lái)簡(jiǎn)化初始化消息數(shù)組的工作。例如,前文提到的 ON_COMMAND宏用來(lái)映射命令消息,只要指定命令I(lǐng)D和消息處理函數(shù)即可,因?yàn)閷?duì)這類(lèi) 命令消息映射條目,其他四個(gè)屬性都是固定的。ON_COMMAND宏的初始化內(nèi)容如下: WM_COMMAND,CN_COMMAND,(WORD)ID_APP_ABOUT,(WORD)ID_APP_ABOUT,AfxSig_vv,(AFX_PMSG)OnAppAbout這個(gè)消息映射條目的含義是:消息ID是ID_APP_ABOUT, OnAppAbout被轉(zhuǎn)換成AFX_PMSG 指針類(lèi)型,AfxSig_vv是MFC預(yù)定義的枚舉變量,用來(lái)標(biāo)識(shí)OnApp
26、About的函數(shù)類(lèi)型為參數(shù) 空(Void)、返回空(Void)。在消息映射數(shù)組的最后,是宏END_MESSAGE_MAP的內(nèi)容,它標(biāo)識(shí)消息處理類(lèi)的消息映射 條目的終止。對(duì)messageMap的初始化如前所述,messageMap的類(lèi)型是AFX_MESSMAP。經(jīng)過(guò)初始化,域lpEntries保存了消息映射數(shù)組_messageEntries的地址;如果動(dòng)態(tài)鏈接到MFC DLL,貝0 pfnGetBaseMap 保存了_GetBaseMessageMap 成員函數(shù)的地址;否則 pBaseMap 保存 了基類(lèi)的消息映射數(shù)組的地址。對(duì)函數(shù)的實(shí)現(xiàn)_GetBaseMessageMap()它返回基類(lèi)的成員變
27、量messagMap (當(dāng)使用MFC DLL時(shí)),使用該函數(shù)得到基類(lèi)消息映射入 口表。GetMessageMap():它返回成員變量messageMap,使用該函數(shù)得到自身消息映射入口表。順便說(shuō)一下,消息映射類(lèi)的基類(lèi)CCmdTarget也實(shí)現(xiàn)了上述和消息映射相關(guān)的函數(shù),不過(guò), 它的消息映射數(shù)組是空的。既然消息映射宏方便了消息映射的實(shí)現(xiàn),那么有必要詳細(xì)的討論消息映射宏。下一節(jié),介紹 消息映射宏的分類(lèi)、用法和用途。1.消息映射宏的種類(lèi)為了簡(jiǎn)化程序員的工作,MFC定義了一系列的消息映射宏和像AfxSig_vv這樣的枚舉變量, 以及標(biāo)準(zhǔn)消息處理函數(shù),并且具體地實(shí)現(xiàn)這些函數(shù)。這里主要討論消息映射宏,常用
28、的分為 以下幾類(lèi)。用于Windows消息的宏,前綴為“ON_WM_”。這樣的宏不帶參數(shù),因?yàn)樗鼘?duì)應(yīng)的消息和消息處理函數(shù)的函數(shù)名稱(chēng)、函數(shù)原型是確定的。 MFC提供了這類(lèi)消息處理函數(shù)的定義和缺省實(shí)現(xiàn)。每個(gè)這樣的宏處理不同的Windows消息。例如:宏ON_WM_CREATE(把消息WM_CREATE映射到OnCreate函數(shù),消息映射條目的第 一個(gè)成員nMessage指定為要處理的Windows消息的ID,第二個(gè)成員nCode指定為0。用于命令消息的宏ON_COMMAND這類(lèi)宏帶有參數(shù),需要通過(guò)參數(shù)指定命令 ID和消息處理函數(shù)。這些消息都映射到WM_COMMAND上,也就是將消息映射條目的第一個(gè)成
29、員nMessage指定為WM_COMMAND, 第二個(gè)成員nCode指定為CN_COMMAND(即0)。消息處理函數(shù)的原型是void (void),不帶參 數(shù),不返回值。除了單條命令消息的映射,還有把一定范圍的命令消息映射到一個(gè)消息處理函數(shù)的映射宏 ON_COMMAND_RANGE。這類(lèi)宏帶有參數(shù),需要指定命令I(lǐng)D的范圍和消息處理函數(shù)。這些 消息都映射到WM_COMMAND上,也就是將消息映射條目的第一個(gè)成員nMessage指定為 WM_COMMAND,第二個(gè)成員nCode指定為CN_COMMAND(即0),第三個(gè)成員nID和第四個(gè) 成員nLastID指定了映射消息的起止范圍。消息處理函數(shù)的原
30、型是void (UINT),有一個(gè)UINT 類(lèi)型的參數(shù),表示要處理的命令消息ID,不返回值。用于控制通知消息的宏這類(lèi)宏可能帶有三個(gè)參數(shù),如ON_CONTROL,就需要指定控制窗口 ID,通知碼和消息處理 函數(shù);也可能帶有兩個(gè)參數(shù),如具體處理特定通知消息的宏ON_BN_CLICKED、ON_LBN_DBLCLK、 ON_CBN_EDITCHANGE等,需要指定控制窗口 ID和消息處理函數(shù)。控制通知消息也被映射到 WM_COMMAND上,也就是將消息映射條目的第一個(gè)成員的 nMessage指定為WM_COMMAND,但是第二個(gè)成員nCode是特定的通知碼,第三個(gè)成員nID 是控制子窗口的ID,第四
31、個(gè)成員nLastID等于第三個(gè)成員的值。消息處理函數(shù)的原型是void (void),沒(méi)有參數(shù),不返回值。還有一類(lèi)宏處理通知消息ON_NOTIFY,它類(lèi)似于ON_CONTROL,但是控制通知消息被映射 到WM_NOTIFY。消息映射條目的第一個(gè)成員的nMessage被指定為WM_NOTIFY,第二個(gè)成 員nCode是特定的通知碼,第三個(gè)成員nID是控制子窗口的ID,第四個(gè)成員nLastID等于第 三個(gè)成員的值。消息處理函數(shù)的原型是void (NMHDR*, LRESULT*),參數(shù)1是NMHDR指針, 參數(shù)2是LRESULT指針,用于返回結(jié)果,但函數(shù)不返回值。對(duì)應(yīng)地,還有把一定范圍的控制子窗口的
32、某個(gè)通知消息映射到一個(gè)消息處理函數(shù)的映射宏, 這類(lèi)宏包括ON_CONTROL_RANGE和ON_NOTIFY_RANGE。這類(lèi)宏帶有參數(shù),需要指定控制 子窗口 ID的范圍和通知消息,以及消息處理函數(shù)。對(duì)于ON_CONTROL_RANGE,是將消息映射條目的第一個(gè)成員的nMessage指定為 WM_COMMAND,但是第二個(gè)成員nCode是特定的通知碼,第三個(gè)成員nID和第四個(gè)成員 nLastID等于指定了控制窗口 ID的范圍。消息處理函數(shù)的原型是void (UINT),參數(shù)表示要處 理的通知消息是哪個(gè)ID的控制子窗口發(fā)送的,函數(shù)不返回值。對(duì)于ON_NOTIFY_RANGE,消息映射條目的第一個(gè)成員的nMessage被指定為WM_NOTIFY, 第二個(gè)成員nCode是特定的通知碼,第三個(gè)成員nID和第四個(gè)成員nLastID指定了控制窗口 ID的范圍。消息處理函數(shù)的原型是void (UINT, NMHDR*,
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 大衛(wèi)地板銷(xiāo)售合同范例
- 平行進(jìn)口車(chē)輛銷(xiāo)售合同范例
- 做餐飲加盟合同范例
- 加盟代理加工合同范例
- 做圍擋合同范例
- 合同范例項(xiàng)目來(lái)源
- 公司簡(jiǎn)易租賃合同范例
- 2024年煤炭貿(mào)易合同范本
- 用戶(hù)反饋在數(shù)字化農(nóng)業(yè)中的收集與處理
- 某地區(qū)水果種植智能化改造項(xiàng)目案例
- 203741_彩繪工程施工組織設(shè)計(jì)
- 1073 法律文書(shū)-國(guó)家開(kāi)放大學(xué)2021年(202101-202107)期末考試真題及答案【2套】-開(kāi)放本科
- 中國(guó)古典發(fā)型
- 基礎(chǔ)生態(tài)學(xué)課后習(xí)題和答案
- 廈門(mén)宏發(fā)繼電器基礎(chǔ)知識(shí)(課堂PPT)
- 財(cái)務(wù)部長(zhǎng)競(jìng)聘PPT課件
- 儲(chǔ)罐大修施工方案
- 專(zhuān)業(yè)安全檢查表-吊索吊具
- 國(guó)槐在園林綠化中的作用
- 2022年住宅室內(nèi)裝飾裝修管理辦法全文
- 消弧線(xiàn)圈基礎(chǔ)施工方案
評(píng)論
0/150
提交評(píng)論