0

このブログから取得したクラスを使用しています: http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx

private static IntPtr HookCallback(
    int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
    {
        int vkCode = Marshal.ReadInt32(lParam);
        Console.WriteLine((Keys)vkCode);
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

この関数は単一のキーのキー コードを取得します。ctrl+C をキャッチできるように変更したかったので、上記の関数を次のように変更しました。

    private static IntPtr HookCallback(
    int nCode, IntPtr wParam, IntPtr lParam)
{
    if ((Keys)(vkCode) == Keys.C && (Control.ModifierKeys == Keys.Control))
    {
        int vkCode = Marshal.ReadInt32(lParam);
        Console.WriteLine((Keys)vkCode);
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

問題は、Control.ModifierKeys が常に NONE を返すことです。結果をググりすぎました。ソリューションの別のモジュールのクラスでこのコードを使用していることに注意してください。私はここで何をしていますか、解決策を提供してください。

4

2 に答える 2

1

はい、これは一般的にはうまくいきませんが、特にプログラム自体にGUIがない場合や、非表示のウィンドウを使用している場合はそうです。Windowsは、個々のプロセスごとにキーボードの状態を維持し、プログラムがキーボードメッセージを受信すると更新されます。これが必要なのは、キーストロークがメッセージキューに保存され、後でプログラムによって取得されるためです。キーボードフックの問題は、メッセージを受け取ったのはあなたのプロセスではなく、別のプロセスであったことです。あなたはまだ古いキーボードの状態を持っています。

本当に信頼できるものにするには、他のプロセスのキーボードの状態を知る必要があります。しかし、それはあなたが得ることができるものではありません、GetKeyboardState()関数はあなた自身の状態を取得することを許可することだけを許可します。これは一般に、キーストロークを入力キーに変換することを非常に困難にします。WH_KEYBOARDフックははるかに優れたソリューションですが、C#でそのようなフックを作成することはできません。

回避策は、Controlキーの状態を自分で追跡することです。または、GetAsyncKeyState()をピンボークして、コントロールキーの実際のバッファリングされていない状態を確認します。

于 2013-01-10T10:56:41.540 に答える
0

それはあなたにはうまくいきません!

Control.ModifierKeys の実装では、パラメーター 0x10、0x11、および 0x12 を使用して Windows API 関数 GetKeyState() を 3 回呼び出し、結果を適切に ors するだけです。

ただし、状態は、メッセージ キューのどのメッセージが処理されているかに関連付けられています。

代わりに PInvoke を使用して Windows API 関数GetAsyncKeyState()を呼び出す必要があると思います。

于 2013-01-10T10:36:27.490 に答える