0

私のC#アプリでは、キーフックを実行したいのですが、キーが押されたときに呼び出されるメソッドが別のスレッドで呼び出されるようにします。このようにして、アプリケーションが他の何かでビジー状態だったために、プログラムによってキーが省略されることはありません。どうすれば別のスレッドで作成できますか?フックを作成するスレッドによっては、キーが押されたときに呼び出されるメソッドがそのスレッドで呼び出されるという情報を見つけましたが、それは起こりません。フックしたスレッドに関係なく、このメソッドは常にメインスレッドで呼び出されます。助けてください。これが私のコードの概要です:

int HookProc(int code, int wParam, ref lParamStruct lParam)
{
    // ... this should be invoked in another thread - thread th, which I use to call SetWindowsHook
}
void SetWindowsHook()
{
    lpMsg msg = new lpMsg();

    PeekMessage(out msg, new IntPtr(0), 0, 0, PM_NOREMOVE);

    hhook = SetWindowsHookEx(WH_KEYBOARD_LL, HookProc, new IntPtr(0), 0);

    while (GetMessage(out msg, new IntPtr(0), 0, 0))
    {
        DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
        if (abortThreadFlag)
            break;

    }
    UnhookWindowsHookEx(hhook);
}

SetWindowsHookはこの方法で呼び出されますが、idはメソッドを別のスレッドで呼び出すように強制しません。

 Thread th = new Thread(SetWindowsHook);
 th.Start()
4

1 に答える 1

3

メッセージループのポイントは、Windowsにフックプロシージャを呼び出す機会を与えることです。コードを呼び出す方法は他にありません。侵入してスレッドにコードを実行させることはできません。これにより、恐ろしい再入可能性の問題が発生します。フックプロシージャは、コードがGetMessage()を呼び出す場合にのみ実行できます。そして、そのスレッドのコンテキストで実行されます。GetCurrentThreadId()の戻り値を調べることで、これを確認できます。

それ以外の場合、スレッドを使用しても、スローフック手順の修正にはなりません。Windowsは、フックプロシージャが戻るまで、他の入力イベントをディスパッチしません。十分に遅くすると、Windowsはフックを強制的に強制終了して回復します。代わりに、スレッドセーフキューからフィードするワーカースレッドを使用して、フックプロシージャがすぐに戻るようにすることを検討してください。

于 2012-07-07T12:53:02.020 に答える