首頁 > 後端開發 > C++ > 為什麼我的 WPF 全域鍵盤掛鉤 (WH_KEYBOARD_LL) 在快速按鍵後停止運作?

為什麼我的 WPF 全域鍵盤掛鉤 (WH_KEYBOARD_LL) 在快速按鍵後停止運作?

Barbara Streisand
發布: 2024-12-30 17:50:10
原創
956 人瀏覽過

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

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板