0

別のアプリケーションの指定されたウィンドウを作成/破棄するイベントをキャッチしようとしています。この目的のために私は設定しWM_SHELLHOOKました。

これが私のWPFアプリケーションからの簡略化されたコードです:

public delegate IntPtr ProcDelegate(int hookCode, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(
    int hookId, ProcDelegate handler, IntPtr hInstance, uint threadId);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);

private void buttonClick(object sender, RoutedEventArgs e)
{
    IntPtr hookHandler;

    using (Process curProcess = Process.GetCurrentProcess())
    using (ProcessModule curModule = curProcess.MainModule)
    {
        var moduleHandle = GetModuleHandle(curModule.ModuleName);
        hookHandler = SetWindowsHookEx(
            10 /*WH_SHELL*/, shellHookHandler, moduleHandle, 0);
    }

    if (hookHandler == IntPtr.Zero)
    {
        // Get here error 1428 (ERROR_HOOK_NEEDS_HMOD) -
        // "Cannot set nonlocal hook without a module handle."
        throw new Exception(Marshal.GetLastWin32Error().ToString());
    }
}

private IntPtr shellHookHandler(int hookCode, IntPtr wParam, IntPtr lParam)
{
    // Some code...
    return IntPtr.Zero;
}

問題は、SetWindowsHookEx常に0を返し、最後のエラーは

1428(ERROR_HOOK_NEEDS_HMOD)モジュールハンドルなしで非ローカルフックを設定することはできません。

私は別の関連する質問を見ました。マウスやキーボードなどにフックを設定すると、すべて問題ありません。

このエラーを修正する方法を教えてください。ありがとう。

4

1 に答える 1

1

フックに関するMSDNのドキュメントには、「アプリケーションが別のアプリケーションのスレッドにフックプロシージャをインストールする場合、そのプロシージャはDLLに含まれている必要があります」と記載されています。

これは、DLLが他のアプリケーションのアドレス空間にロードされているためです。次に、メインアプリケーションに情報を渡すためのメカニズム(メモリマップトファイルなど)を見つける必要があります。

ただし、ほとんどのドキュメント(ここで説明されています)とは異なり、キーボードとマウスのフックはDLLなしで機能します。それが彼らがあなたのために働いた理由です。

于 2012-01-28T22:21:54.317 に答える