SendMessage() 發(fā)出的消息 PreTranslateMessage() 不一定能接收到!
今天在調(diào)試一個(gè)程序時(shí),發(fā)現(xiàn)調(diào)用 SendMessage() 發(fā)送的消息,PreTranslateMessage() 接收不到;試了其它兩個(gè)方法:
(1) 換成 PostMessage() 來(lái)廣播消息,則 PreTranslateMessage() 可以接收到。
(2) 仍然使用 SendMessage() ,將消息處理放在消息隊(duì)列(BEGIN_MESSAGE_MAP)中處理時(shí),也可以接收到。
分析了一下此問題的原因,記錄如下:
PreTranslateMessage 先于 WindowProc() 處理消息。
SendMessage() 發(fā)出的消息 PreTranslateMessage() 能否接收到,要區(qū)分環(huán)境。如果是對(duì)本線程的窗口 SendMessage(),則不經(jīng)過任何消息循環(huán),也不放入消息隊(duì)列,直接調(diào)用WindowProc()。這樣 GetMessage() 和PreTranslateMessage() 都捕獲不到;如果 SendMessage() 是向其它線程或其它進(jìn)程的窗口發(fā)消息,則消息進(jìn)入消息隊(duì)列,GetMessage() 和 PreTranslateMessage() 能捕獲到這個(gè)消息。
PreTranslateMessage() 它是用來(lái)處理 PostMessage() 發(fā)出的,而不處理 SendMessage() 發(fā)出的消息;經(jīng)過 PreTranslateMessage() 轉(zhuǎn)換后的消息就和 SendMessage() 消息一樣由 WindowProc() 處理,像鍵盤消息就需要它來(lái)轉(zhuǎn)換。
MFC 中 PreTranslateMessage() 是 GetMessage() 函數(shù)的下一級(jí)操作,即 GetMessage() 從消息隊(duì)列中獲取消息后,交由 PreTranslateMessage() 處理,若其返回 FALSE 則再交給 TranslateMessage 和 DispatchMessage 處理(進(jìn)入WindowProc);?
如果用 SendMessage(),則消息直接交到 WindowProc() 處理,所以 GetMessage() 不會(huì)取得 SendMessage() 的消息,當(dāng)然 PreTranslateMessage() 也就不會(huì)被調(diào)用。?
所以用 PostMessage()發(fā)送的消息,則消息進(jìn)入消息隊(duì)列,由 GetMessage()取得,PreTranslateMessage() 就有機(jī)會(huì)進(jìn)行處理。
總結(jié): 不是所有的消息都會(huì)經(jīng)過 PreTranslateMessage()。
例如: 通過 SendMessage() 發(fā)到本窗體的消息,直接進(jìn)入WindowProc()。
一個(gè)線程只有一個(gè)消息隊(duì)列,也就只有一個(gè) TranslateMessage() 和 Dispatch 的地方,一般情況下,卻有很多個(gè)WindowProc(),一個(gè)窗口對(duì)應(yīng)一個(gè)windowProc。
也不是所有的消息都會(huì)經(jīng)過 WindowProc(),
例如:如果窗口中含有子窗口,鼠標(biāo)滑過子窗口,鼠標(biāo)移動(dòng)消息直接在 PreTranslateMessage() 里面派發(fā)給了子窗口的 WindowProc()。