在 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中文網其他相關文章!