2017-08-16 110 views
0

當從WPF應用程序(以及其他應用程序)調用WINAPI命令GetKeyboardState(aByteArray)時,只有在應用程序具有焦點時,才能正確檢測到按住SHIFT鍵。當應用程序沒有焦點時,方法調用後aByteArray[VK_SHIFT]0當應用程序不在焦點時,由GetKeyState修改的WINAPI GetKeyboardState行爲?

但是,如果GetKeyState(aVKCode)是爲aVKCode任何價值GetKeyboardState(aByteArray),之前立即調用,即使返回值被丟棄,然後GetKeyboardState(aByteArray)將提供舉行SHIFT鍵的正確非零狀態,當應用程序不在焦點。

這種行爲是違反直覺的,似乎導致了很多程序員的悲痛。我認爲GetKeyboardState的文檔中有相關信息,其內容如下:

狀態隨線程從其消息隊列中刪除鍵盤消息而發生更改。當鍵盤消息被髮布到線程的消息隊列時,狀態不會改變,也不會隨着鍵盤消息被髮布到其他線程的消息隊列或從其他線程的消息隊列中檢索到而改變。

潛在地,GetKeyState()以這樣一種方式,它之前必須GetKeyboardState()爲了GetKeyboardState()稱爲表現爲期望的消息隊列相互作用。但是,我並不熟悉消息隊列的概念以及Windows如何添加和刪除項目,所以我想我會在這裏問。任何人都可以解釋爲什麼一個電話GetKeyboardState()獨自無法捕捉沒有應用程序重點舉行的SHIFT密鑰?

+0

(鍵盤)輸入每個線程(或一組輸入連接的線程)被虛擬化。每個線程維護自己的鍵盤狀態信息。當線程擁有輸入焦點的窗口時按下鍵不會更新任何其他線程中的鍵盤狀態(連接到此線程的鍵除外)。有關[異步輸入vs同步輸入,快速介紹]的更多詳細信息,請參閱https://blogs.msdn.microsoft.com/oldnewthing/20130604-00/?p=4173。 – IInspectable

回答

1

GetKeyState總是關聯到線程的最後處理的消息。因此,在消息處理程序中使用GetKeyState時,如果將此消息放入消息隊列中,您將獲得keystate。

如果消息處理被延遲,這保證每個消息都可以被程序員處理,並且他可以在那一刻檢測到關鍵狀態。 I.E .:「發生鼠標點擊時Shift鍵是否關閉?」

只要使用GetKeyState可以跳過狀態或消息,如果其他消息之間進行處理。

要檢測當前國家重點則必須使用GetAsyncKeyState

的功能是有據可查的。

最後:GetKeyState和GetAsyncKeyState都不是檢測程序中是否按下shift鍵的好方法。處理消息並檢測WM_KEYDOWN。

+0

感謝您的信息。我正在查看的代碼使用WM_KEYDOWN來檢測按鍵,並且如果該消息中的鍵是字母數字,那麼我使用GetKeyState來查找shift或capslock是否已關閉,以便可以將由WM_KEYDOWN指示的鍵轉換爲ASCII。 因此,我確實需要在前兩段中描述的行爲。我選擇使用GetKeyState的原因是,在開始處理WM_KEYDOWN消息之前,可能會按下shift和/或大寫鎖定鍵,但我仍然希望能夠檢測到這些情況。 在這種情況下,你會使用哪種方法? – Anthony

相關問題