2017-08-16 3 views
0

GetKeyboardState(aByteArray)をWPFアプリケーション(およびほかのアプリケーションも同様)から呼び出すと、SHIFTキーを押し続けると、アプリケーションにフォーカスがあるときだけ正しく検出されます。アプリケーションにフォーカスがないときは、メソッドコールの後に0になる。aByteArray[VK_SHIFT]WINAPIアプリケーションのフォーカスが外れているときGetKeyStateによってGetKeyboardStateの動作が変更されましたか?

しかし、GetKeyState(aVKCode)場合、アプリケーションがフォーカスされていない場合、戻り値は破棄されても、その後GetKeyboardState(aByteArray)を保持SHIFTキーの正しい非ゼロ状態を提供する、aVKCodeの任意の値の直前GetKeyboardState(aByteArray),と呼ばれ。

この動作は直感的ではなく、多くのプログラマの悲嘆を引き起こしているようです。

メッセージに関連する情報があると考えられます。スレッドがメッセージキューからキーボードメッセージを削除すると、ステータスが変わります。キーボードメッセージがスレッドのメッセージキューにポストされたり、キーボードメッセージが他のスレッドのメッセージキューにポストされたり、他のスレッドのメッセージキューから取得されたりすると、ステータスは変化しません。

潜在的に、GetKeyState()は、所望のように動作するGetKeyboardState()ために前GetKeyboardState()に呼び出されなければならないような方法で、メッセージキューと相互作用します。しかし、私はメッセージキューの概念や、Windowsで項目を追加したり削除したりする方法についてよく知らないので、私はここで質問したいと思っていました。誰もがなぜGetKeyboardState()への呼び出しがアプリケーションフォーカスなしで保持されているSHIFTキーをキャプチャできないのか説明できますか?

+0

(キーボード入力)は、スレッド(または入力接続スレッドのグループ)ごとに仮想化されています。各スレッドは、それ自身のキーボード状態情報を維持する。スレッドが所有するウィンドウに入力フォーカスがある間にキーを押すと、他のスレッド(このスレッドに接続されているスレッドを除く)のキーボード状態は更新されません。詳細については、[非同期入力と同期入力、簡単な紹介](https://blogs.msdn.microsoft.com/oldnewthing/20130604-00/?p=4173)を参照してください。 – IInspectable

答えて

1

GetKeyStateは、スレッドの最後に処理されたメッセージに常に関連付けられます。したがって、メッセージハンドラ内でGetKeyStateを使用すると、このメッセージがメッセージキューに置かれたときにキーステートが取得されます。

メッセージ処理が遅れた場合、各メッセージをプログラマが処理できるようになり、その瞬間のキー状態を検出することができます。 I.E .:「マウスクリックが発生したときにShiftキーを押していましたか?」

GetKeyStateを使用すると、その間に他のメッセージが処理された場合は、状態またはメッセージをスキップできます。あなたはGetAsyncKeyState

機能が十分に文書化されて使用する必要があります現在キーの状態を検出する

最後に、GetKeyStateもGetAsyncKeyStateも、シフトキーがプログラム内で押されたかどうかを検出する良い方法ではありません。メッセージを処理し、WM_KEYDOWNを検出します。

+0

ありがとうございました。私が見ているコードでは、キー押下を検出するためにWM_KEYDOWNが使用され、そのメッセージのキーが英数字の場合、WM_KEYDOWNで示されたキーをASCIIに変換できるようにGetKeyStateを使用してシフトまたは したがって、最初の2つの段落で説明した動作が必要です。私がGetKeyStateを使用する理由は、WM_KEYDOWNメッセージの処理を開始する前にShiftキーやcaps lockキーが押されている可能性があり、それらのケースを検出できるようにするためです。 このシナリオでは、どの方法を使用しますか? – Anthony

関連する問題