Windows 8.1 での GetAsyncKeyState 関数の動作変更について
こんにちは、Visual Studio サポート チームです。
今回は、GetAsyncKeyState 関数の動作の変更についてご紹介します。
キーボードフックの処理内で、GetAsyncKeyState 関数を使用して、Shift キーが押されていることを判断している場合があると思います。
しかしながら、KB2975719 の修正の一部である KB2980433 の対応の結果、この関数の戻り値が変更されることがあります。
具体的には、Shift キーを押下した際、GetAsyncKeyState 関数の戻り値は、0x00000000 または 0x00000001 となります。
この変更に伴い、例えばアプリケーションとしての動作が変わり、予期せぬ問題が発生することが想定されます。
なお、この問題は、キーボードフックしている時のみ確認できる問題となります。
本動作変更の対処方法としては、キーボードフックした際に、GetAsyncKeyState 関数を使用せず、KBDLLHOOKSTRUCT 構造体のメンバー変数 vkCode が VK_LSHIFT か VK_RSHIFT かを判定し、メンバー変数 flags が LLKHF_UP である場合には、SHIFT キーが入力されたと判断する方法があります。
[補足]
以下は対処方法のソースコードの一例となります。
// フックコードのチェック
if(nCode == HC_ACTION){
// lParam はキーボードフックされた際に渡される LPARAM
LPKBDLLHOOKSTRUCT pKey = (LPKBDLLHOOKSTRUCT)lParam;
// vkCode が VK_LSHIFT か VK_RSHIFT かを判定
if (((pKey->vkCode == VK_LSHIFT) || (pKey->vkCode == VK_RSHIFT)) &&
// LLKHF_UP かを判定
((pKey->flags & LLKHF_UP) == 0)) {
// Shift キーが押されたと判断。
}
}
[参考情報]
GetAsyncKeyState https://msdn.microsoft.com/ja-jp/library/cc364583.aspx
KBDLLHOOKSTRUCT structure https://msdn.microsoft.com/en-us/library/windows/desktop/ms644967.aspx
Properties of an item opens randomly when you double-click the item in Windows 8.1 or Windows Server 2012 R2 https://support.microsoft.com/kb/2980433
Windows RT 8.1、8.1 の Windows、および Windows Server 2012 の R2 用の更新プログラムのロールアップ 2014年 8 月 https://support.microsoft.com/kb/2975719