經常有朋友問起,GetKeyState和GetAsyncKeyState到底有什麼差別,分别應該在什麼場景下使用。
那麼,今天我就來翻譯翻譯,什麼叫驚喜。
GetKeyState會傳回虛拟按鍵的狀态。換句話說,GetKeyState會基于你從輸入隊列中檢索到的消息來報告鍵盤按鍵的狀态。這個狀态是虛拟的,也就是說,它和鍵盤的實體狀态是不一樣的。
> 如果使用者在你調用PeekMessage或者GetMessage之前就進行了鍵盤輸入,則GetKeyState不會報告任何鍵盤輸入的變化。
> 如果使用者切換到了其他程式,那麼GetKeyState不會傳回使用者在那個程式中的任何輸入,因為作業系統并沒有将其他程式的鍵盤輸入發送至你的程式的輸入隊列之中。
而GetAsyncKeyState傳回的是按鍵的實體狀态,它是直接擷取硬體中斷的狀态。
那麼,什麼時候應該使用GetKeyState,什麼時候又應該使用GetAsyncKeyState呢? 好問題!
從使用者體驗的角度出發,你應該幾乎總是使用GetKeyState。為何?
如果你正在處理某一條輸入消息并想知道在生成此消息時,使用者都按下了哪些鍵,那麼你就需要使用 GetKeyState。例如,如果要區分滑鼠左鍵單擊和 Alt + 滑鼠左鍵單擊,則必須使用 GetKeyState 來查詢 ALT 鍵的狀态(基于曆史的原因,我們稱之為 VK_MENU)。那是因為你想知道當使用者單擊滑鼠時 ALT 鍵是否按下,而不是此時鍵是否按下。使用者是否在單擊和處理消息之間釋放 ALT 鍵無關緊要。你所關心的隻是 ALT 鍵在單擊時是否按下了。
請注意,如果你要實作上下文菜單處理程式,則你不應使用 GetKeyState 或 GetAsyncKeyState,因為無需任何使用者操作即可以程式設計方式調用上下文菜單。對于
IContextMenu::QueryContextMenu,你應該測試 CMF_EXTENDEDVERBS 标志以檢測是否應該顯示擴充指令而不是直接查詢鍵盤按鍵的裝填。類似地,對于 IContextMenu::InvokeCommand,如果你想根據轉換狀态改變程式的行為,那麼應該測試 CMIC_MASK_CONTROL_DOWN 和CMIC_MASK_SHIFT_DOWN 标志位是否存在。
總結
在拓撲梅爾智慧辦公平台(Topomel Box)的開發過程中,我也使用到了GetKeyState,感覺良好。