using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows.Input; using Vinno.FIS.Sonopost.Common; using Vinno.FIS.Sonopost.Managers.Interfaces; using Vinno.FIS.Sonopost.Settings; using Vinno.IUS.Common.Log; namespace Vinno.FIS.Sonopost.Managers { internal class KeyBoardListenManager : SonopostManager, IKeyBoardListenManager { private const int WH_KEYBOARD_LL = 13; private const int WM_KEYDOWN = 0x0100; private const int WM_KEYUP = 0x0101; private bool _isLeftKeyDown; private bool _isRightKeyDown; private bool _isStarted; // 声明全局钩子句柄 private IntPtr _keyboardHookID = IntPtr.Zero; // 键盘处理委托实例 private LowLevelKeyboardProc _keyboardProc; // 导入SetWindowsHookEx函数 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); // 导入UnhookWindowsHookEx函数 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); // 导入CallNextHookEx函数 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName); // 声明KeyboardProc委托类型 private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); public EnumKeyboardKey LeftKey { get; private set; } public EnumKeyboardKey RightKey { get; private set; } public event EventHandler LeftKeyPressedEvent; public event EventHandler RightKeyPressedEvent; public KeyBoardListenManager() { _keyboardProc = KeyboardHookCallback; _keyboardHookID = SetKeyboardHook(_keyboardProc); } public void StartKeyBoardListen() { if (!_isStarted) { LeftKey = SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleLeftKeyForKeyBoard; RightKey = SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleRightKeyForKeyBoard; _isStarted = true; Logger.WriteLineInfo($"Start To Listen {LeftKey} & {RightKey}"); } else { if (LeftKey != SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleLeftKeyForKeyBoard || RightKey != SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleRightKeyForKeyBoard) { LeftKey = SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleLeftKeyForKeyBoard; RightKey = SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleRightKeyForKeyBoard; Logger.WriteLineInfo($"Start To Listen {LeftKey} & {RightKey}"); } } } private IntPtr SetKeyboardHook(LowLevelKeyboardProc proc) { using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); } } public void StopKeyBoardListen() { if (!_isStarted) { return; } _isStarted = false; Logger.WriteLineInfo($"Stop KeyBoard Listen"); } public override void DoDispose() { try { StopKeyBoardListen(); UnhookWindowsHookEx(_keyboardHookID); } catch (Exception ex) { Logger.WriteLineError($"KeyBoardListenManager DoDispose Error:{ex}"); } base.DoDispose(); } private IntPtr KeyboardHookCallback(int nCode, IntPtr wParam, IntPtr lParam) { try { if (nCode >= 0 && _isStarted) { if (wParam == (IntPtr)WM_KEYDOWN) { int vkCode = Marshal.ReadInt32(lParam); var pressedKey = KeyInterop.KeyFromVirtualKey(vkCode); if (pressedKey.ToString() == LeftKey.ToString() && !_isLeftKeyDown) { Logger.WriteLineWarn($"LeftKey {pressedKey} Pressed"); _isLeftKeyDown = true; LeftKeyPressedEvent?.Invoke(this, EventArgs.Empty); } else if (pressedKey.ToString() == RightKey.ToString() && !_isRightKeyDown) { Logger.WriteLineWarn($"RightKey {pressedKey} Pressed"); _isRightKeyDown = true; RightKeyPressedEvent?.Invoke(this, EventArgs.Empty); } } else if (wParam == (IntPtr)WM_KEYUP) { int vkCode = Marshal.ReadInt32(lParam); var pressedKey = KeyInterop.KeyFromVirtualKey(vkCode); if (pressedKey.ToString() == LeftKey.ToString()) { _isLeftKeyDown = false; } else if (pressedKey.ToString() == RightKey.ToString()) { _isRightKeyDown = false; } } } } catch (Exception ex) { Logger.WriteLineError($"KeyboardHookCallback Error:{ex}"); } return CallNextHookEx(_keyboardHookID, nCode, wParam, lParam); } } }