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 중국어 웹사이트의 기타 관련 기사를 참조하세요!