>백엔드 개발 >C++ >빠른 키 입력 후 내 WPF 전역 키보드 후크(WH_KEYBOARD_LL)가 작동을 멈추는 이유는 무엇입니까?

빠른 키 입력 후 내 WPF 전역 키보드 후크(WH_KEYBOARD_LL)가 작동을 멈추는 이유는 무엇입니까?

Barbara Streisand
Barbara Streisand원래의
2024-12-30 17:50:10956검색

Why Does My WPF Global Keyboard Hook (WH_KEYBOARD_LL) Stop Working After Rapid Keystrokes?

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

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.