c 訊息處理

2021-06-26 09:15:49 字數 2780 閱讀 1909

a. 作業系統接收應用程式的視窗訊息,將訊息投遞到該應用程式的訊息佇列中

b. 應用程式在訊息迴圈中呼叫

getmessage

函式從訊息佇列中取出一條一條的訊息,取出訊息後,應用程式可以對訊息進行一些預處理(pretranslatemessage、translatemessage

)。c.

應用程式呼叫

dispatchmessage

,將訊息回傳給作業系統。

d. 系統利用

wndclass

結構體的

lpfnwndproc

成員儲存的視窗過程函式的指標呼叫視窗過程,對訊息進行處理。

總的來說,windows

訊息處理機制是這樣的

:   

首先系統

(也就是

windows)

把來自硬體(滑鼠

,鍵盤等訊息

)和來自應用程式的訊息

放到乙個系統訊息佇列中去。而應用程式需要有自己的訊息佇列

,也就是執行緒訊息佇列

,每乙個執行緒有自己的訊息佇列

,對於多執行緒的應用程式就有和執行緒數目相等的執行緒訊息佇列。

windows訊息佇列把得到的訊息傳送到執行緒訊息佇列,執行緒訊息佇列每次取出一條訊息傳送到指定視窗,不斷迴圈直到程式退出。這個迴圈就是靠訊息環(while(getmessage())translatemessage();dispatchmessage();實現的。getmessage()只是從執行緒訊息中取出一條訊息,translatemessage()把virtue key訊息轉化成character訊息,如vk_f1會轉化成wm_help,而dispatchmessage  則把取出的訊息傳送到目的視窗。如果收到wm_close訊息則結束迴圈,傳送postqiutmessage(0),處理wm_destroy銷毀視窗!

pretranslatemessage是訊息在送給translatemessage函式之前被呼叫的,絕大多數本視窗的訊息都要通過這裡,比較常用,當需要在mfc之前處理某些訊息時,常常要在這裡新增**。

mfc訊息控制流最具特色的地方就是cwnd類的虛函式pretranslatemessage(),通過過載這個函式,可以改變mfc的訊息控制流程,甚至可以作乙個全新的控制流出來。

只有穿過訊息佇列的訊息才受pretranslatemessage()影響。採用sendmessage()或其他類似的方式向視窗直接傳送的而不經過訊息佇列的訊息,直接交到windowproc處理,所以getmessage不會取得sendmessage的訊息,當然pretranslatemessage也就不會被呼叫。如果採用postmessage(),則訊息進入訊息佇列,由getmessage取得,pretranslatemessage()就有機會進行處理。

是否呼叫translatemessage()和dispatchmessage()是由pretranslatemessage()函式的返回值決定的,如果該函式返回true,則不會把該訊息分發給視窗函式處理。 

傳給pretranslatemessage()

的訊息是未經翻譯過的訊息,它沒有經過

translatemessage()

處理。可以在該函式中使用

(pmsg->wparam==vk_return)

來攔截回車鍵。

wparam

中存放的是鍵盤上字元的偽程式碼。

3. translatemessage的作用和用法

translatemessage是用來把虛擬鍵訊息轉換為字元訊息。由於windows對所有鍵盤編碼都是採用虛擬鍵的定義,這樣當按鍵按下時,並不能得到字元訊息,需要鍵盤對映轉換為字元的訊息。

字元訊息被投遞到呼叫執行緒的訊息佇列中,當下一次呼叫getmessage函式時被取出。

當我們敲擊鍵盤上的某個字元鍵時,系統將產生wm_keydown和wm_keyup訊息。這兩個訊息的附加引數(wparam和lparam)包含的是虛擬鍵**和掃瞄碼等資訊,而我們在程式中往往需要得到某個字元的ascii碼,translatemessage這個函式就可以將wm_keydown和wm_ keyup訊息的組合轉換為一條wm_char訊息(該訊息的wparam附加引數包含了字元的ascii碼),並將轉換後的新訊息投遞到呼叫執行緒的訊息佇列中。注意,translatemessage函式並不會修改原有的訊息,它只是產生新的訊息並投遞到訊息佇列中。

也就是說translatemessage會發現訊息裡是否有字元鍵的訊息,如果有字元鍵的訊息,就會產生wm_char訊息。

4. peekmessage和getmessage的區別:

getmessage在沒有訊息的時候等待訊息,cpu低 

peekmessage沒有訊息的時候立刻返回,cpu佔用率高。 

因為遊戲不能靠windows訊息驅動,所以要用peekmessage(); 

5. 例程

如果用pretranslate

函式處理按鍵訊息,由於按鍵訊息一次會產生兩個,在其中加入判斷語句,當按鍵抬起時執行,不然會造成訊息重複執行。

判斷語句:

if(pmsg->message==wm_keyup)

vk_return

是回車的意思

vk_up

方向鍵向上的鍵     vk_down方向鍵中向下的鍵

bool cex_chatdlg::pretranslatemessage(msg* pmsg) 

return 1;

}returncdialog::pretranslatemessage(pmsg);

}

C 中訊息處理

對於處理所有訊息.net 提供了wndproc進行重寫 wndproc ref message m protected override void wndproc ref message m base.wndproc ref m 在.net中,程式驅動採用了事件驅動而不是原來的訊息驅動,雖然.net...

C 中 訊息的處理

1.afx msg 在標頭檔案 drawview.h 中宣告訊息響應函式原型。afx msg 注釋巨集 說明 在注釋巨集之間的宣告在vc中灰色顯示。afx msg巨集表示宣告的是乙個訊息響應函式 afx msg訊息函式 應用程式 框架產生的訊息對映函式 例如 afx msg void onbncli...

訊息和訊息處理之訊息迴圈

在win32程式設計中,訊息迴圈是相當重要的乙個概念,看似很難,但使用起來卻是非常簡單。在winmain函式的最後,有下列 while getmessage msg,null,0,0 windows應用程式可以接收以各種形式輸入的資訊,這包括鍵盤 滑鼠動作 計時器產生的訊息,也可以是其他應用程式發來...