WPF / C# でのグローバル キーボード フック (WH_KEYBOARD_LL) の使用
この質問では、グローバル キーボード フックを繰り返し押した後に機能しなくなる問題について説明します。キー。
問題:
WH_KEYBOARD_LL を使用して実装されたグローバル キーボード フックは、一定期間の激しいキーストロークの後にキー イベントの受信を停止します。エラーはスローされず、キーストロークが発生した場所に関係なく発生します。
考えられる原因:
スレッドの問題が根本的な問題であると考えられます。
キーボードのコードサンプルフック:
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Windows.Input; namespace MYCOMPANYHERE.WPF.KeyboardHelper { public class KeyboardListener : IDisposable { private static IntPtr hookId = IntPtr.Zero; // Delegate to hook callback (method that will handle key events) private static InterceptKeys.LowLevelKeyboardProc hookCallback; [MethodImpl(MethodImplOptions.NoInlining)] private IntPtr HookCallback( int nCode, IntPtr wParam, IntPtr lParam) { // Handle key events here return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam); } public event RawKeyEventHandler KeyDown; public event RawKeyEventHandler KeyUp; public KeyboardListener() { // Create and assign the hook callback delegate hookCallback = (nCode, wParam, lParam) => { HookCallbackInner(nCode, wParam, lParam); return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam); }; // Set the hook using the delegate as a parameter hookId = InterceptKeys.SetHook(hookCallback); } // Remaining code not shown for brevity } internal static class InterceptKeys { public delegate IntPtr LowLevelKeyboardProc( int nCode, IntPtr wParam, IntPtr lParam); // Hook-related constants public const int WH_KEYBOARD_LL = 13; public const int WM_KEYDOWN = 0x0100; public const int WM_KEYUP = 0x0101; public static IntPtr SetHook(LowLevelKeyboardProc proc) { using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); } } // Other code not shown for brevity } // Event args and handlers for key events public delegate void RawKeyEventHandler(object sender, RawKeyEventArgs args); }
解決策:
回答で示唆されているように、コールバック メソッドへのデリゲートはインラインで作成されるため、ゴミが集められた。デリゲートを生きたままにしてこの問題を防ぐには、デリゲートをメンバー変数に割り当てる必要があります。
// Assign the hook callback delegate to a member variable private InterceptKeys.LowLevelKeyboardProc hookCallback;
これを行うことで、デリゲートは KeyboardListener オブジェクトの存続期間中生きたままになります。これにより、キーボード フックが一定期間後に動作しなくなる問題が解決されるはずです。
以上が急速なキーストロークの後、WPF グローバル キーボード フック (WH_KEYBOARD_LL) が動作しなくなるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。