核心編程_消息分流器_第1頁(yè)
核心編程_消息分流器_第2頁(yè)
核心編程_消息分流器_第3頁(yè)
核心編程_消息分流器_第4頁(yè)
核心編程_消息分流器_第5頁(yè)
已閱讀5頁(yè),還剩1頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、自己看核心編程,對(duì)消息分流器不太理解,這篇寫(xiě)的不錯(cuò),所以轉(zhuǎn)載。很好理解,windows操作系統(tǒng)使用消息處理機(jī)制,那么,我們所設(shè)計(jì)的程序如何才能分辨和處理系統(tǒng)中的各種消息呢?這就是消息分流器的作用.簡(jiǎn)單來(lái)說(shuō),消息分流器就是一段代碼,在我的講述中,將分7重來(lái)循序漸進(jìn)的介紹它.從最初的第1重到最成熟的第7重,它的樣子會(huì)有很大的變化.但,實(shí)現(xiàn)的功能都是一樣的,所不同的,僅僅是變得更加簡(jiǎn)練罷了.程序開(kāi)始時(shí)候,會(huì)是main函數(shù),然后會(huì)生成初始的窗口,同時(shí)會(huì)調(diào)用WndProc函數(shù).這是一個(gè)自定義的函數(shù),名字也會(huì)有變化,但其功能是一樣的,就是運(yùn)行消息分流器.WndProc函數(shù)如下:LRESULT CALLBA

2、CK WndProc (HWND hwnd, UINT msg,WPARAM wParam, LPARAM lParam)/.return DefWindowProc(hwnd, msg, wParam, lParam);這其中,hwnd是窗口的句柄,msg是系統(tǒng)發(fā)送來(lái)的消息的名字.wParam和lParam則是隨消息一起發(fā)送來(lái)的消息參數(shù).WndProc函數(shù)使用了消息分流器,下面把消息分流器的內(nèi)容解釋一下:一重,當(dāng)不同的消息出現(xiàn)時(shí),在其中寫(xiě)入相應(yīng)的程序語(yǔ)句即可。LRESULT CALLBACK WndProc (HWND hwnd, UINT msg,WPARAM wParam, LPARAM

3、 lParam) switch(msg) case WM_CREATE: / . return 0; case WM_PAINT: / . return 0; case WM_DESTROY: /. return 0; return DefWindowProc(hwnd, msg, wParam, lParam);二重,運(yùn)用三個(gè)消息分流器進(jìn)行處理。LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) switch(msg) case WM_CREATE: return HANDLE_WM_CRE

4、ATE(hwnd, wParam, lParam, Cls_OnCreate); case WM_PAINT: return HANDLE_WM_PAINT(hwnd, wParam, lParam, Cls_OnPaint); case WM_DESTROY: return HANDLE_WM_DESTROY(hwnd, wParam, lParam, Cls_OnDestroy); return DefWindowProc(hwnd, msg, wParam, lParam);這里的HANDLE_WM_CREATE,HANDLE_WM_PAINT,HANDLE_WM_DESTROY就是消息

5、分流器。與消息不同之處就是在前面增加了“HANDLE_”字符,windows的消息分流器就是這樣的模樣。它的本質(zhì)就是宏定義。其中的四個(gè)參數(shù)有三個(gè)都是從本函數(shù)的入口參數(shù)中直接得到的,即為hwnd, wParam, lParam。只有第四的參數(shù)是表明調(diào)用的函數(shù)。消息分流器是在winowsx.h文件中定義的。由此,可以看出第四個(gè)參數(shù)是調(diào)用的函數(shù),其定義如下:#define HANDLE_WM_CREATE(hwnd, wParam, lParam, fn) (fn)(hwnd), (LPCREATESTRUCT)(lParam) ? 0L : (LRESULT)-1L)#define HANDLE_

6、WM_PAINT(hwnd, wParam, lParam, fn) (fn)(hwnd), 0L)#define HANDLE_WM_DESTROYCLIPBOARD(hwnd, wParam, lParam, fn) (fn)(hwnd), 0L)0L是表示int類型的變量,其數(shù)值為0。int類型時(shí),可在后面加l或者L(小寫(xiě)和大寫(xiě)形式)表明無(wú)符號(hào)數(shù)時(shí),可在后面加u或者U(小寫(xiě)和大寫(xiě)形式)float類型時(shí),可在后面加f或者F(小寫(xiě)和大寫(xiě)形式)例如:128u 1024UL 1L 8Lu 3.14159F 0.1f LRESULT是一個(gè)系統(tǒng)的數(shù)據(jù)類型,其定義如下:typedef LONG_PTR

7、 LRESULT;LONG_PTR也是一個(gè)系統(tǒng)的數(shù)據(jù)類型,其定義如下:#if defined(_WIN64) typedef _int64 LONG_PTR; #else typedef long LONG_PTR;#endif由此可見(jiàn),LRESULT的實(shí)質(zhì)就是64的long類型的變量那么(LRESULT)-1L的實(shí)質(zhì)并不是減法,而是(LRESULT)(-1L),即強(qiáng)制類型轉(zhuǎn)換三重,把消息分流器的宏定義代換回去,就成了下面的樣子LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) switch(

8、msg) case WM_CREATE: return Cls_OnCreate(hwnd, (LPCREATESTRUCT)(lParam) ? 0L : (LRESULT)-1L; / 如果處理了消息,則Cls_OnCreate應(yīng)返回TRUE,導(dǎo)致WndProc返回0,否則Cls_OnCreate返回FALSE,導(dǎo)致WndProc返回-1; case WM_PAINT: return Cls_OnPaint(hwnd), 0L; / 逗號(hào)表達(dá)式;Cls_OnPaint是void類型,這里返回0; case WM_DESTROY: return Cls_OnDestroy(hwnd), 0L

9、; / 同Cls_OnPaint return DefWindowProc(hwnd, msg, wParam, lParam);在逗號(hào)表達(dá)式,C+會(huì)計(jì)算每個(gè)表達(dá)式,但完整的逗號(hào)表達(dá)式的結(jié)果是最右邊表達(dá)式的值。所以,會(huì)return 0。然后,就可以手動(dòng)的編寫(xiě)各個(gè)處理函數(shù)了:Cls_OnCreate,Cls_OnPaint,WM_DESTROY。四重,LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) switch(msg) HANDLE_MSG(hwnd, WM_CREATE, Cls_OnC

10、reate); HANDLE_MSG(hwnd, WM_PAINT, Cls_OnPaint); HANDLE_MSG(hwnd, WM_DESTROY, Cls_OnDestroy); return DefWindowProc(hwnd, msg, wParam, lParam);HANDLE_MSG也是一個(gè)宏,它在windowsx.h中定義,如下:#define HANDLE_MSG(hwnd, message, fn) case (message): return HANDLE_#message(hwnd), (wParam), (lParam), (fn)這個(gè)宏要做的就是根據(jù)不同的me

11、ssage(#用來(lái)連接前后的字符串),把自己“變成”相應(yīng)的HANDLE_XXXXMESSAGE形式的宏,再通過(guò)相應(yīng)的宏來(lái)執(zhí)行消息處理代碼。說(shuō)白了,就是把message的消息做為替換,#就是一個(gè)替換的標(biāo)志。如果沒(méi)有#,就成了HANDLE_message了,這樣,宏是不會(huì)被代換的。如果就單獨(dú)一個(gè),則會(huì)代換,如hwnd和fn。比如實(shí)際代碼中寫(xiě)入:HANDLE_MSG(hwnd, WM_CREATE, Cls_OnCreate)則經(jīng)過(guò)轉(zhuǎn)換就變成:case (WM_CREATE): return HANDLE_WM_CREATE(hwnd), (wParam), (lParam), (Cls_OnCre

12、ate)這與二重一模一樣。以上四重,是消息分離器的基本使用,但,這不完整,消息分離器主要應(yīng)用在對(duì)話框消息處理中。這里,窗口子類化是我們經(jīng)常使用的手段,這也可以通過(guò)消息分流器實(shí)現(xiàn),第五重LRESULT CALLBACK Dlg_Proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) switch(msg) HANDLE_MSG(hwnd, WM_INITDIALO , Cls_OnInitDialog); / 不能直接使用HANDLE_MSG宏 HANDLE_MSG(hwnd, WM_COMMAND, Cls_OnCommand); /

13、不能直接使用HANDLE_MSG宏 return false; 由于是窗口子類化,所以,最后,返回的是false,以表明,如果沒(méi)有約定響應(yīng)的消息,則返回父親窗口false,如果有,則返回ture,這是與前四重不同的地方。一般情況下,對(duì)話框過(guò)程函數(shù)應(yīng)該在處理了消息的情況下返回TRUE,如果沒(méi)有處理,則返回FALSE。如果對(duì)話框過(guò)程返回了FALSE,那么對(duì)話框管理器為這條消息準(zhǔn)備默認(rèn)的對(duì)話操作。但是,這其中有錯(cuò)誤,因?yàn)橛械南?需要單獨(dú)處理。單獨(dú)處理的消息列表見(jiàn)SetDlgMsgResult宏。第六重這點(diǎn)小問(wèn)題,這就需要用到SetDlgMsgResult(hwnd, msg, result)宏。

14、LRESULT CALLBACK Dlg_Proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)switch(msg) case WM_INITDIALO: return (SetDlgMsgResult(hwnd, Msg, HANDLE_WM_INITDIALO(hwnd), (wParam), (lParam), (fn); case WM_COMMAND: return (SetDlgMsgResult(hwnd, Msg, HANDLE_WM_COMMAND(hwnd), (wParam), (lParam), (fn); r

15、eturn false; 這里,就用直接用到了第二重的消息分流器,而拋棄了其他。這個(gè)宏定義如下:#define SetDlgMsgResult(hwnd, msg, result) ( ( (msg) = WM_CTLCOLORMSGBOX | (msg) = WM_CTLCOLOREDIT | (msg) = WM_CTLCOLORLISTBOX | (msg) = WM_CTLCOLORBTN | (msg) = WM_CTLCOLORDLG | (msg) = WM_CTLCOLORSCROLLBAR | (msg) = WM_CTLCOLORSTATIC | (msg) = WM_CO

16、MPAREITEM | (msg) = WM_VKEYTOITEM | (msg) = WM_CHARTOITEM | (msg) = WM_QUERYDRAGICON | (msg) = WM_INITDIALOG ) ? (BOOL)(result) : (SetWindowLongPtr(hwnd), DWLP_MSGRESULT, (LPARAM)(LRESULT)(result), TRUE)為了表述清楚,所以用了此格式,這是一個(gè)三項(xiàng)表達(dá)式,首先對(duì)消息類型進(jìn)行考察。如果對(duì)話框過(guò)程處理的消息恰巧為返回特定值中的一個(gè),則如實(shí)返回result;不要被前面的BOOL蒙蔽,BOOL在頭文件中的

17、定義實(shí)際上是一個(gè)int型,一旦需要返回非TRUE或FALSE的其他值,照樣可以;這樣,我們的Cls_OnInitDialog就能夠正確的返回它的BOOL值了,而Cls_OnCommand在處理之后,也可以由后面的逗號(hào)表達(dá)式正確的返回一個(gè)TRUE表示消息已處理。第七重我們還可以把case也包含進(jìn)來(lái),就成了如下的樣子。LRESULT CALLBACK Dlg_Proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) switch(msg) chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Cls_OnInitDialo

18、g); chHANDLE_DLGMSG(hwnd, WM_COMMAND, Cls_OnCommand); return false;chHANDLE_DLGMSG是牛人定義的一個(gè)宏,它把case也包含進(jìn)來(lái)了。#define chHANDLE_DLGMSG(hwnd, message, fn) case (message): return (SetDlgMsgResult(hwnd, uMsg, HANDLE_#message(hwnd), (wParam), (lParam), (fn) 這樣,程序中的語(yǔ)句 switch (uMsg) chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog); chHANDLE_DLGMSG(hwnd, WM_SIZE, Dlg_OnSize); chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand); 就被翻譯成: switch (uMsg) case (WM_INITDIALOG): return (SetDlgMsgResult(hwnd, uMsg, HANDLE_WM_I

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 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ì)用戶上傳內(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論