首頁 >後端開發 >C++ >為什麼 C# 中的全域鍵盤掛鉤在持續擊鍵後停止運作?

為什麼 C# 中的全域鍵盤掛鉤在持續擊鍵後停止運作?

Barbara Streisand
Barbara Streisand原創
2025-01-03 08:34:42306瀏覽

Why Does My Global Keyboard Hook in C# Stop Working After Sustained Keystrokes?

在WPF / C# 中使用全域鍵盤鉤子(WH_KEYBOARD_LL)

提供的程式碼旨在使用WH_KEYBOARD_全域鉤子建立一個全域鉤子來捕捉一個全域鉤並處理鍵盤事件。雖然實作基本上實現了其預期功能,但出現了一個關鍵問題:在持續擊鍵一段時間後,事件處理突然停止。

此行為表示有潛在的執行緒問題。為了解決這個問題,我們需要確保只要鉤子就位,回呼委託就保持活動狀態。

問題分析

回呼委託 HookCallback 是在 SetHook 方法中內聯定義。因此,一旦方法退出,委託就有資格進行垃圾回收。發生這種情況時,掛鉤將停止接收回調,從而導致觀察到事件處理終止。

解決方案

要修正此問題,我們需要保留對委託並確保其生命週期與鉤子的存在一致。以下是解決問題的修訂後的程式碼:

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;
        private InterceptKeys.LowLevelKeyboardProc callback;

        public KeyboardListener()
        {
            callback = HookCallback;
            hookId = InterceptKeys.SetHook(callback);
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            try
            {
                return HookCallbackInner(nCode, wParam, lParam);
            }
            catch
            {
                Console.WriteLine("There was some error somewhere...");
            }
            return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam);
        }

        private IntPtr HookCallbackInner(int nCode, IntPtr wParam, IntPtr lParam)
        {
            // ... (original code here)

            return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam);
        }

        // ... (rest of the class)
    }
}

在此更新的程式碼中,LowLevelKeyboardProc 委託(回呼)現在是 KeyboardListener 類別的一個欄位。透過維護此引用,我們確保委託在鉤子的整個生命週期中保持活動並可用於回調呼叫。

透過以這種方式解決線程問題,全域鍵盤鉤子將繼續可靠地捕獲和處理鍵盤事件,即使在無情的擊鍵情況下也是如此。

以上是為什麼 C# 中的全域鍵盤掛鉤在持續擊鍵後停止運作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn