トップ回答者
GetKeyboardStateによる入力キー取得

質問
-
VC++初めてのプログラムがキー入力制御で…四苦八苦してます。
取得したいキー以外のキー入力は無視するようにしたいです。低レベルキーボードフック
「hHook = SetWindowsHookEx(WH_KEYBOARD_LL, HookProc, hInst, 0);」
というのを使うとキー入力が取得できるということがわかりました。しかし、キー入力を取得しようと
LRESULT CALLBACK HookProc(int nCode, WPARAM wp, LPARAM lp)
{
BYTE state[256];
if (GetKeyboardState( state ) == 0) return ::CallNextHookEx(hHook, nCode, wp, lp);
if( state[0x53] & 0x80 )
{
// Sキーが押されている
OutputDebugString(TEXT("S \n"));
}
::CallNextHookEx(hHook, nCode, wp, lp);
return TRUE;
}
としてもうまくいきません。どこがだめなのかさっぱりわからず、お手上げ状態です。
どうか助言をお願いします。
回答
-
日本語のリファレンスではなく英語のほう(http://msdn.microsoft.com/en-us/library/ms644985(VS.85).aspx)を見るとわかりますが、LPARAM には、KBDLLHOOKSTRUCT 構造体へのポインタが渡されます。
日本語のリファレンスには書いてないですね。何のポインタかわからなきゃ使えないのに...
わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/
すべての返信
-
-
Hongliangさん返信ありがとうございます。
ご指摘を参考に以下のように修正してみたのですが…
取得できなかったです。
LRESULT CALLBACK HookProc(int nCode, WPARAM wp, LPARAM lp)
{
if (nCode < 0 || nCode == HC_NOREMOVE ) return ::CallNextHookEx(hHook, nCode, wp, lp);
SHORT sKeyState = GetAsyncKeyState('S');
if( sKeyState & 0x8000)
{
OutputDebugString(TEXT("S(+) \n"));
return ::CallNextHookEx(hHook, nCode, wp, lp);;
}
::CallNextHookEx(hHook, nCode, wp, lp);
return TRUE;
}佐祐理さん返信ありがとうございます。
デバッグは別のEXEファイル(同一ソリューションにて作成)でおこなっております。
lparamについてはhttp://msdn.microsoft.com/ja-jp/library/cc429971.aspxを参照してみたのですが、
理解できずに困ってます。
デバッグ実行でブレイクポイントを設定し(HookProc内最初のif文のところ)
lp変数をウォッチリストにいれてみたのですが、long型の1244076という値が入っているだけのようで…
ぜんぜん見当違いなことやってたらすみません。 -
もしかして、行うべきは、キーボードフックではなくアプリケーションが通常受け取るキー処理をどうするかではありませんか?
GUI(WinMainで始まるプログラム) プログラムであれば、キー処理はフォーカスを持つウィンドウ(アクティブなフレームウィンドウでフォーカス入力を拒否しない子ウィンドウのいずれか)がキー入力を受け取ります。
CUIであれば、キー入力処理は、コンソール入出力APIがOSからのキー処理を受け入れ、それを標準入出力などのC RuntimeやC++ Runtime で受け取れるようにしています。
なんとなく思っただけで、本当にキーボードフックをして、特定キー入力のみに制限するのが目的なのかもしれませんが...
わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/ -
日本語のリファレンスではなく英語のほう(http://msdn.microsoft.com/en-us/library/ms644985(VS.85).aspx)を見るとわかりますが、LPARAM には、KBDLLHOOKSTRUCT 構造体へのポインタが渡されます。
日本語のリファレンスには書いてないですね。何のポインタかわからなきゃ使えないのに...
わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/ -
とっちゃんさん 返信ありがとうございます。
英語のサイト参考になりました(英語読めませんが…^^;)
以下のように修正したところ取得することができました。
助言いただいた皆様のおかげです。ありがとうございます。LRESULT CALLBACK HookProc(int nCode, WPARAM wp, LPARAM lp)
{
if (nCode < 0 || nCode == HC_NOREMOVE ) return ::CallNextHookEx(hHook, nCode, wp, lp);
KBDLLHOOKSTRUCT*pK = (KBDLLHOOKSTRUCT*)lp;
// Sキーが押されている
if (pK->vkCode == 83 ){
if (pK->flags == 0 )
{
OutputDebugString(TEXT("S(p+) \n"));
sKeyFlg = true;
return true;
}else{
OutputDebugString(TEXT("S(p-) \n"));
sKeyFlg = false;
}
}
return true;
}これから実際のアプリを作らないといけないんですけどね~^^;