Menggunakan Cangkuk Papan Kekunci Global (WH_KEYBOARD_LL) dalam WPF / C#
Soalan ini membincangkan isu cangkuk papan kekunci global berhenti berfungsi selepas berulang kali memukul kekunci.
Masalah:
Kait papan kekunci global yang dilaksanakan menggunakan WH_KEYBOARD_LL berhenti menerima peristiwa penting selepas tempoh ketukan kekunci yang sengit. Tiada ralat dilemparkan dan ia berlaku tidak kira di mana ketukan kekunci berlaku.
Punca yang Disyaki:
Isu threading disyaki sebagai masalah asas.
Contoh Kod untuk Papan Kekunci Cangkuk:
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); }
Penyelesaian:
Seperti yang dicadangkan oleh jawapan, wakil kepada kaedah panggil balik dibuat sebaris, yang boleh menyebabkan kaedah itu menjadi dikumpul sampah. Untuk memastikan perwakilan terus hidup dan mengelakkan isu ini, anda perlu menetapkan wakil kepada pembolehubah ahli.
// Assign the hook callback delegate to a member variable private InterceptKeys.LowLevelKeyboardProc hookCallback;
Dengan melakukan ini, perwakilan akan terus hidup sepanjang hayat objek KeyboardListener. Ini sepatutnya menyelesaikan isu di mana cangkuk papan kekunci berhenti berfungsi selepas satu tempoh masa.
Atas ialah kandungan terperinci Mengapa Cangkuk Papan Kekunci Global WPF Saya (WH_KEYBOARD_LL) Berhenti Berfungsi Selepas Ketukan Kekunci Pantas?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!