実際にあなたの質問に答える前に、いくつか質問があります。
グローバルな低レベルのキーボード フックを使用して、これをグローバルに実行する必要があるのはなぜですか?
問題を解決する唯一の方法である場合もありますが、このようなグローバル フックを使用することは、多くの理由から一般的に強くお勧めできません。ユーザーが無効または受け入れられないデータを入力するのを防ぐためのより良い方法はたくさんあります。たとえば、特定のコントロールまたはコントロールのセット (たとえば、すべてのテキスト ボックス) に不要なキーを無効にします。これにより、ユーザーは引き続きキーボード ショートカットやその他の英数字以外のキーを使用してアプリケーションを操作できます。これは、アクセシビリティ上の理由から重要です。グローバル フックは、アプリだけでなく、マシン上で実行されている他のすべてのスレッドに影響を与えることに注意してください。これは、おそらく望んでいないことです。
グローバル フックを使用することにしたとしても、英数字以外のキーをすべて無効にする必要があると確信していますか? バックスペースと削除はどうですか?ユーザーは物を削除できるべきではありませんか? タブはどうですか?入る?また、Shift、Ctrl、Alt などの修飾キーは使用できますか?
この設計を続行する前に、本当に低レベルのフックが必要かどうかを真剣に再検討してください。別の解決策を考案する上で助けが必要な場合は、達成したいことを説明して、新しい質問をしてください (たとえば、ユーザーが英数字以外の文字をテキスト ボックス コントロールに入力できないようにしたい。テキストボックス…)。
しかし、私のアドバイスを無視することに固執する場合、解決策はかなり単純です。フック プロシージャに渡されるKBDLLHOOKSTRUCT
構造体のメンバーを調べます。vkCode
メンバーは、押されたキーの仮想キーコードを提供します。おそらく、必要な情報はこれだけです。ただし、そうでない場合に備えて、キーのハードウェア スキャン コードもscanCode
メンバーで提供されます。
残念ながら、あなたが現在持っているコードは間違っています。フック コールバック プロシージャの最初のパラメータは確かにですが、キー コードint
ではありません。むしろ、フック プロシージャがメッセージを処理する方法を通知するコードです。次のように使用します。
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// If nCode is greater than or equal to HC_ACTION, process the message.
if (nCode >= HC_ACTION)
{
KBDLLHOOKSTRUCT* pkbhs = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
// Handle the keys as you wish here.
//
// Remember that pkbhs->vkCode gives you the virtual key code
// of the key that was pressed.
//
// To prevent a particular key from being processed, you should
// return a non-zero value (e.g. 1) immediately.
}
// Pass the message on.
return CallNextHookEx(m_hHook, nCode, wParam, lParam);
}
また、フックをインストールするときに、関数ポインターをキャストする必要はまったくありません。このような無意味なキャストは、潜在的なコンパイル時エラーを隠すだけであり、実行時にクラッシュを引き起こします。簡単に書いてください:
m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, lowLevelKeyboardProc, 0, 0);