今天用C語言寫一個Win32程序,要給這個程序加入鍵盤接口。但是奇怪的是,程序怎麼也不肯響應WM_KEYDOWN消息,設置了斷點DEBUG,也沒有響應。我又調用GetAsyncKeyState()函數檢查鍵是否按下,結果證明是按下了。新建一個Win32程序能夠響應的。天底下最郁悶的事情莫過於此!於是心裡大罵微軟那些號稱天才的程序員。
百度一下,也有很多兄弟遇到我一樣的問題,但是在那麼多解答中, 發現只有一個答正確了,其他的都是在湊熱鬧,有的甚至說要用HOOK。原來,我的窗體上有一個Button控件,我按下之後,窗口焦點(Focus)被它搶走了,所以我的主窗口就無法響應了。背後的原因是鍵盤是一個共享設備,所以Windows只讓獲得焦點的窗口能夠響應鍵盤消息。並且Windows創建了一個system message queue儲存鍵盤和鼠標消息,然後等應用程序處理完一個消息後,才把下一個消息放到應用程序的application''s message queue 裡。之所以要兩個隊列,是為了進行同步,使消息能夠正確的分發到應用程序。比如當一個用戶按鍵過快時,應用程序的處理速度可能趕不上用戶按鍵的速度。如果用戶按鍵的過程中切換了窗口焦點(比如按下ALT-TAB),那麼接著的鍵盤消息就應該分發到新獲得焦點的窗口去。如果只有一個消息隊列則不能做到這一點。(參考《Programming Windows》第5版)
調用SetFocus(hWnd)解決問題。