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應用程式可以接收以各種形式輸入的資訊,這包括鍵盤 滑鼠動作 計時器產生的訊息,也可以是其他應用程式發來...