隊(duì)列消息和非隊(duì)列消息_第1頁(yè)
隊(duì)列消息和非隊(duì)列消息_第2頁(yè)
隊(duì)列消息和非隊(duì)列消息_第3頁(yè)
隊(duì)列消息和非隊(duì)列消息_第4頁(yè)
全文預(yù)覽已結(jié)束

下載本文檔

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

文檔簡(jiǎn)介

1、隊(duì)列消息和非隊(duì)列消息從消息的發(fā)送途徑來(lái)看,消息可以分成2種:隊(duì)列消息和非隊(duì)列消息。消息隊(duì)列由可 以分成系統(tǒng)消息隊(duì)列和線程消息隊(duì)列。系統(tǒng)消息隊(duì)列由Windows維護(hù),線程消息隊(duì)列則由 每個(gè)GUI線程自己進(jìn)行維護(hù),為避免給non-GUI現(xiàn)成創(chuàng)建消息隊(duì)列,所有線程產(chǎn)生時(shí)并沒(méi) 有消息隊(duì)列,僅當(dāng)線程第一次調(diào)用GDI函數(shù)數(shù)系統(tǒng)給線程創(chuàng)建一個(gè)消息隊(duì)列。隊(duì)列消息送 到系統(tǒng)消息隊(duì)列,然后到線程消息隊(duì)列:非隊(duì)列消息直接送給目的窗口過(guò)程。對(duì)于隊(duì)列消息,最常見(jiàn)的是鼠標(biāo)和鍵盤(pán)觸發(fā)的消息,例如W_M0USERM0VE, WM_CHAR等 消息,還有一些其它的消息,例如:WM_PANT、WM_TIMER和WM_QUIT。當(dāng)

2、鼠標(biāo)、鍵盤(pán)事件 被觸發(fā)后,相應(yīng)的鼠標(biāo)或鍵盤(pán)驅(qū)動(dòng)程序就會(huì)把這些事件轉(zhuǎn)換成相應(yīng)的消息,然后輸送到系 統(tǒng)消息隊(duì)列,由Windows系統(tǒng)去進(jìn)行處理。Windows系統(tǒng)則在適當(dāng)?shù)臅r(shí)機(jī),從系統(tǒng)消息隊(duì) 列中取出一個(gè)消息,根據(jù)前面我們所說(shuō)的USG消息結(jié)構(gòu)確定消息是要被送往那個(gè)窗口,然 后把取出的消息送往創(chuàng)建窗口的線程的相應(yīng)隊(duì)列,下面的事情就該由線程消息隊(duì)列操心了, Windows開(kāi)始忙自己的事情去了。線程看到自己的消息隊(duì)列中有消息,就從隊(duì)列中取出來(lái), 通過(guò)操作系統(tǒng)發(fā)送到合適的窗口過(guò)程去處理。一般來(lái)講,系統(tǒng)總是將消息Post在消息隊(duì)列的末尾。這樣保證窗口以先進(jìn)先出的順序接受消息。然而,WNLPAINT是一個(gè)例外

3、, 同一個(gè)窗口的多個(gè)WM_PAINT被合并成一個(gè)WM_PAINT消息,合并所有的無(wú)效區(qū)域到一個(gè) 無(wú)效區(qū)域。合并W_PAIN的目的是為了減少刷新窗口的次數(shù)。非隊(duì)列消息將會(huì)繞過(guò)系統(tǒng)隊(duì)列和消息隊(duì)列,直接將消息發(fā)送到窗口過(guò)程,。系統(tǒng)發(fā)送 非隊(duì)列消息通知窗口,系統(tǒng)發(fā)送消息通知窗口。例如,當(dāng)用戶激活一個(gè)窗口系統(tǒng)發(fā)送 .ACTIVATE, WM_SETFOCUS, and W.SETCURSOR,這些消息通知窗口它被激活了。非隊(duì)列 消息也可以由當(dāng)應(yīng)用程序調(diào)用系統(tǒng)函數(shù)產(chǎn)生。例如,當(dāng)程序調(diào)用SetWindowPos系統(tǒng)發(fā)送WM_WINDOWPOSCHANGED消息。一些函數(shù)也發(fā)送非隊(duì)列消息,例 如下面我們要談到

4、的函數(shù)。消息的發(fā)送了解了上面的這些基礎(chǔ)理論之后,我們就可以進(jìn)行一下簡(jiǎn)單的消息發(fā)送與接收。把一個(gè)消息發(fā)送到窗口有3種方式:發(fā)送、寄送和廣播。發(fā)送消息的函數(shù)有SendMessage SendMessageCallback' SendNotifyMessage SendMessageTimeout:寄送 消息的函數(shù)主要有 PostUessage、PostThreadMessage、PostQuitMessage:廣播消息的函 數(shù)我知道的只有 BroadcastSystemMessagex BroadcastSystemMessageEx0SendMessage 的原型如下:LRESULT S

5、endMessage (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM IParam),這個(gè)函數(shù)主要是向一個(gè)或多個(gè)窗口發(fā)送一條消息、,一直等到消 息被處理之后才會(huì)返回。不過(guò)需要注意的是,如果接收消息的窗口是同一個(gè)應(yīng)用程序的一 部分,那么這個(gè)窗口的窗口函數(shù)就被作為一個(gè)子程序馬上被調(diào)用;如果接收消息的窗口是被另外的線程所創(chuàng)建的,那么窗口系統(tǒng)就切換到相應(yīng)的線程并旦調(diào)用相應(yīng)的窗口函數(shù),這 條消息不會(huì)被放進(jìn)目標(biāo)應(yīng)用程序隊(duì)列中。函數(shù)的返回值是由接收消息的窗口的窗口函數(shù)返回,返回的值取決于被發(fā)送的消 息。PostMessage 的原型如下:BOOL P。stress a

6、ge (HWXD hWnd, UINT Msg, WPARAM wParam, LPARAM IParam),該函數(shù)把一條消息放置到創(chuàng)建hWnd窗口的線程的消息隊(duì)列中, 該函數(shù)不等消息被處理就馬上將控制返回。需要注意的是,如果hWnd參數(shù)為HWND.BROADCAST,那么,消息將被寄送給系統(tǒng)中的所有的重疊窗口和彈出窗口,但是 子窗口不會(huì)收到該消息;如果hWnd參數(shù)為NULL,則該函數(shù)類似于將dwThreadID參數(shù)設(shè)置 成當(dāng)前線程的標(biāo)志來(lái)調(diào)用PostThreadMEssage函數(shù)。從上面的這2個(gè)具有代表性的函數(shù),我們可以看出消息的發(fā)送方式和寄送方式的區(qū)別 所在:被發(fā)送的消息是否會(huì)被立即處理,

7、函數(shù)是否立即返回。被發(fā)送的消息會(huì)被立即處理, 處理完畢后函數(shù)才會(huì)返回;被寄送的消息不會(huì)被立即處理,他被放到一個(gè)先進(jìn)先出的隊(duì)列 中,一直等到應(yīng)用程序空線的時(shí)候才會(huì)被處理,不過(guò)函數(shù)放置消息后立即返回。實(shí)際上,發(fā)送消息到一個(gè)窗口處理過(guò)程和直接調(diào)用窗口處理過(guò)程之間并沒(méi)有太大的區(qū)別,他們 直接的唯一區(qū)別就在于你可以要求操作系統(tǒng)截獲所有被發(fā)送的消息,但是不能夠截獲對(duì)窗 口處理過(guò)程的直接調(diào)用。以寄送方式發(fā)送的消息通常是與用戶輸入事件相對(duì)應(yīng)的,因?yàn)檫@些事件不是十分緊迫,可以進(jìn)行緩慢的緩沖處理,例如赳標(biāo)、健盤(pán)消息會(huì)被寄送,而 按鈕等消息則會(huì)被發(fā)送。廣播消息用得比較少,BroadcastSystemMessage

8、函數(shù)原型如下:long BroadcastSystemMessage(DWORD dwFlags, LPDWORD IpdwRecipients, UINT uiMessage, WPARAM wParam, LPARAM IParam);該函數(shù)可以向指定的接收者發(fā)送一條消息, 這些接收者可以是應(yīng)用程序、可安裝的驅(qū)動(dòng)程序、網(wǎng)絡(luò)驅(qū)動(dòng)程序、系統(tǒng)級(jí)別的設(shè)備驅(qū)動(dòng)消 息和他們的任意組合。需要注意的是,如果dwFlags參數(shù)是BSF_QUERY并且至少一個(gè)接收 者返回了BROADCAST_QUERY_DENY,則返回值為0 ,如果沒(méi)有指定BSF_QUERY,則函數(shù)將消息發(fā) 送給所有接收者,并且忽略其返回值

9、。消息的接收消息的接收主要有 3 個(gè)函數(shù):GetMessage、PeekMessage、WaitMessageoGetMessage 原型如下:BOOL GetMessage (LPMSG IpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);該函數(shù)用來(lái)獲取與hWnd參數(shù)所指定的窗口相關(guān)的且wMsgFilterMin和wMsgFilterMax參數(shù)所給出的消息值范圍內(nèi)的消息。需要注意的是, 如果hWnd為NULL,則GetMessage獲取屬于調(diào)用該函數(shù)應(yīng)用程序的任一窗口的消息,如果 wMsgFilterMin 和wMsgFilte

10、rMax都是0,則GetMessage就返回所有可得到的消息。函數(shù)獲取之后將刪 除消息隊(duì)列中的除WM-PAINT消息之外的其他消息,至于WM_PAINT則只有在其處理之后才 被刪除。PeekMessage 原型如下:BOOL PeekMessage (LPMSG IpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINTwRemoveMsg);該函數(shù)用于查看應(yīng)用程序的消息隊(duì)列,如果其中有消息就將其放入IpMsg所指的結(jié)構(gòu) 中,不過(guò),與GetMessage不同的是,PeekMessage函數(shù)不會(huì)等到有消息放入隊(duì)列時(shí)才返回。 同樣,

11、如果hWnd為NULL,則PeekMessage獲取屬于調(diào)用該函數(shù)應(yīng)用程序的任一窗口的消 息,如果hWnd=-l,那么函數(shù)只返回把hWnd參數(shù)為NULL的PostAppMessage函數(shù)送去的消 息。如果 wMsgFilterMin 和wMsgFilterMax都是0 ,則PeekMessage就返回所有可得到的消息。函數(shù)獲取之后將 刪除消息隊(duì)列中的除WM_PAINT消息之外的其他消息,至于WNLPAINT則只有在其處理之后 才被刪除。WaitMessage原型如下:BOOL VaitMessage ();當(dāng)一個(gè)應(yīng)用程序無(wú)事可做時(shí),該函數(shù)就 將控制權(quán)交給另外的應(yīng)用程序,同時(shí)將該應(yīng)用程序掛起,直到一個(gè)新的消息被放入應(yīng)用程 序的隊(duì)列之中才返回。消息的處理接下來(lái)我們談一下消息的處理,首先我們來(lá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)論