KeyBoardListenManager.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.InteropServices;
  4. using System.Windows.Input;
  5. using Vinno.FIS.Sonopost.Common;
  6. using Vinno.FIS.Sonopost.Managers.Interfaces;
  7. using Vinno.FIS.Sonopost.Settings;
  8. using Vinno.IUS.Common.Log;
  9. namespace Vinno.FIS.Sonopost.Managers
  10. {
  11. internal class KeyBoardListenManager : SonopostManager, IKeyBoardListenManager
  12. {
  13. private const int WH_KEYBOARD_LL = 13;
  14. private const int WM_KEYDOWN = 0x0100;
  15. private const int WM_KEYUP = 0x0101;
  16. private bool _isLeftKeyDown;
  17. private bool _isRightKeyDown;
  18. private bool _isStarted;
  19. // 声明全局钩子句柄
  20. private IntPtr _keyboardHookID = IntPtr.Zero;
  21. // 键盘处理委托实例
  22. private LowLevelKeyboardProc _keyboardProc;
  23. // 导入SetWindowsHookEx函数
  24. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  25. private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
  26. // 导入UnhookWindowsHookEx函数
  27. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  28. [return: MarshalAs(UnmanagedType.Bool)]
  29. private static extern bool UnhookWindowsHookEx(IntPtr hhk);
  30. // 导入CallNextHookEx函数
  31. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  32. private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
  33. [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  34. private static extern IntPtr GetModuleHandle(string lpModuleName);
  35. // 声明KeyboardProc委托类型
  36. private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
  37. public EnumKeyboardKey LeftKey { get; private set; }
  38. public EnumKeyboardKey RightKey { get; private set; }
  39. public event EventHandler LeftKeyPressedEvent;
  40. public event EventHandler RightKeyPressedEvent;
  41. public KeyBoardListenManager()
  42. {
  43. _keyboardProc = KeyboardHookCallback;
  44. _keyboardHookID = SetKeyboardHook(_keyboardProc);
  45. }
  46. public void StartKeyBoardListen()
  47. {
  48. if (!_isStarted)
  49. {
  50. LeftKey = SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleLeftKeyForKeyBoard;
  51. RightKey = SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleRightKeyForKeyBoard;
  52. _isStarted = true;
  53. Logger.WriteLineInfo($"Start To Listen {LeftKey} & {RightKey}");
  54. }
  55. else
  56. {
  57. if (LeftKey != SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleLeftKeyForKeyBoard || RightKey != SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleRightKeyForKeyBoard)
  58. {
  59. LeftKey = SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleLeftKeyForKeyBoard;
  60. RightKey = SonopostUserDefinedSettings.Instance.CaptureSetting.FootToggleRightKeyForKeyBoard;
  61. Logger.WriteLineInfo($"Start To Listen {LeftKey} & {RightKey}");
  62. }
  63. }
  64. }
  65. private IntPtr SetKeyboardHook(LowLevelKeyboardProc proc)
  66. {
  67. using (Process curProcess = Process.GetCurrentProcess())
  68. using (ProcessModule curModule = curProcess.MainModule)
  69. {
  70. return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
  71. }
  72. }
  73. public void StopKeyBoardListen()
  74. {
  75. if (!_isStarted)
  76. {
  77. return;
  78. }
  79. _isStarted = false;
  80. Logger.WriteLineInfo($"Stop KeyBoard Listen");
  81. }
  82. public override void DoDispose()
  83. {
  84. try
  85. {
  86. StopKeyBoardListen();
  87. UnhookWindowsHookEx(_keyboardHookID);
  88. }
  89. catch (Exception ex)
  90. {
  91. Logger.WriteLineError($"KeyBoardListenManager DoDispose Error:{ex}");
  92. }
  93. base.DoDispose();
  94. }
  95. private IntPtr KeyboardHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
  96. {
  97. try
  98. {
  99. if (nCode >= 0 && _isStarted)
  100. {
  101. if (wParam == (IntPtr)WM_KEYDOWN)
  102. {
  103. int vkCode = Marshal.ReadInt32(lParam);
  104. var pressedKey = KeyInterop.KeyFromVirtualKey(vkCode);
  105. if (pressedKey.ToString() == LeftKey.ToString() && !_isLeftKeyDown)
  106. {
  107. Logger.WriteLineWarn($"LeftKey {pressedKey} Pressed");
  108. _isLeftKeyDown = true;
  109. LeftKeyPressedEvent?.Invoke(this, EventArgs.Empty);
  110. }
  111. else if (pressedKey.ToString() == RightKey.ToString() && !_isRightKeyDown)
  112. {
  113. Logger.WriteLineWarn($"RightKey {pressedKey} Pressed");
  114. _isRightKeyDown = true;
  115. RightKeyPressedEvent?.Invoke(this, EventArgs.Empty);
  116. }
  117. }
  118. else if (wParam == (IntPtr)WM_KEYUP)
  119. {
  120. int vkCode = Marshal.ReadInt32(lParam);
  121. var pressedKey = KeyInterop.KeyFromVirtualKey(vkCode);
  122. if (pressedKey.ToString() == LeftKey.ToString())
  123. {
  124. _isLeftKeyDown = false;
  125. }
  126. else if (pressedKey.ToString() == RightKey.ToString())
  127. {
  128. _isRightKeyDown = false;
  129. }
  130. }
  131. }
  132. }
  133. catch (Exception ex)
  134. {
  135. Logger.WriteLineError($"KeyboardHookCallback Error:{ex}");
  136. }
  137. return CallNextHookEx(_keyboardHookID, nCode, wParam, lParam);
  138. }
  139. }
  140. }