From 983b2e8c02d80407c57e7191a82fe3e1f3408da6 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Wed, 22 May 2019 23:32:12 +0800 Subject: [PATCH] add KeyboardHook --- .../Controls/Time/TimeBar/TimeBar.cs | 1 - .../Data/Args/KeyboardHookEventArgs.cs | 15 +++++ .../HandyControl_Shared.projitems | 4 +- .../MouseDragElementBehaviorEx.cs | 4 +- .../Tools/Hook/KeyboardHook.cs | 57 +++++++++++++++++++ .../Tools/Interop/NativeMethods.cs | 2 + .../Tools/Interop/UnsafeNativeMethods.cs | 3 +- 7 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 src/Shared/HandyControl_Shared/Data/Args/KeyboardHookEventArgs.cs rename src/Shared/HandyControl_Shared/{Tools => Interactivity}/MouseDragElementBehaviorEx.cs (99%) create mode 100644 src/Shared/HandyControl_Shared/Tools/Hook/KeyboardHook.cs diff --git a/src/Shared/HandyControl_Shared/Controls/Time/TimeBar/TimeBar.cs b/src/Shared/HandyControl_Shared/Controls/Time/TimeBar/TimeBar.cs index fcc658bf..fa0c9a9f 100644 --- a/src/Shared/HandyControl_Shared/Controls/Time/TimeBar/TimeBar.cs +++ b/src/Shared/HandyControl_Shared/Controls/Time/TimeBar/TimeBar.cs @@ -6,7 +6,6 @@ using System.Windows.Input; using System.Windows.Media; using HandyControl.Data; using HandyControl.Interactivity; -using HandyControl.Tools; namespace HandyControl.Controls diff --git a/src/Shared/HandyControl_Shared/Data/Args/KeyboardHookEventArgs.cs b/src/Shared/HandyControl_Shared/Data/Args/KeyboardHookEventArgs.cs new file mode 100644 index 00000000..3d3eb0b3 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Data/Args/KeyboardHookEventArgs.cs @@ -0,0 +1,15 @@ +using System; +using System.Windows.Input; + +namespace HandyControl.Data +{ + internal class KeyboardHookEventArgs : EventArgs + { + public Key Key { get; } + + public KeyboardHookEventArgs(int virtualKey) + { + Key = KeyInterop.KeyFromVirtualKey(virtualKey); + } + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 39535ac9..0b15d2bc 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -113,6 +113,7 @@ + @@ -246,6 +247,7 @@ + @@ -261,7 +263,7 @@ - + diff --git a/src/Shared/HandyControl_Shared/Tools/MouseDragElementBehaviorEx.cs b/src/Shared/HandyControl_Shared/Interactivity/MouseDragElementBehaviorEx.cs similarity index 99% rename from src/Shared/HandyControl_Shared/Tools/MouseDragElementBehaviorEx.cs rename to src/Shared/HandyControl_Shared/Interactivity/MouseDragElementBehaviorEx.cs index a598f167..9232676f 100644 --- a/src/Shared/HandyControl_Shared/Tools/MouseDragElementBehaviorEx.cs +++ b/src/Shared/HandyControl_Shared/Interactivity/MouseDragElementBehaviorEx.cs @@ -2,9 +2,9 @@ using System.Windows.Input; using System.Windows.Media; using HandyControl.Data; -using HandyControl.Interactivity; +using HandyControl.Tools; -namespace HandyControl.Tools +namespace HandyControl.Interactivity { /// /// 鼠标拖动行为,该类是反编译微软的System.Windows.Interactivity程序集得到的,并对其做了些扩展 diff --git a/src/Shared/HandyControl_Shared/Tools/Hook/KeyboardHook.cs b/src/Shared/HandyControl_Shared/Tools/Hook/KeyboardHook.cs new file mode 100644 index 00000000..0bd562fd --- /dev/null +++ b/src/Shared/HandyControl_Shared/Tools/Hook/KeyboardHook.cs @@ -0,0 +1,57 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using HandyControl.Data; +using HandyControl.Tools.Interop; + +namespace HandyControl.Tools +{ + internal class KeyboardHook + { + public static event EventHandler KeyDown; + + public static event EventHandler KeyUp; + + private static IntPtr HookId = IntPtr.Zero; + + private static readonly UnsafeNativeMethods.HookProc Proc = HookCallback; + + public static void Start() => HookId = SetHook(Proc); + + public static void Stop() => UnsafeNativeMethods.UnhookWindowsHookEx(HookId); + + private static IntPtr SetHook(UnsafeNativeMethods.HookProc proc) + { + using (var curProcess = Process.GetCurrentProcess()) + using (var curModule = curProcess.MainModule) + { + if (curModule != null) + { + return UnsafeNativeMethods.SetWindowsHookEx((int)UnsafeNativeMethods.HookType.WH_KEYBOARD_LL, proc, + UnsafeNativeMethods.GetModuleHandle(curModule.ModuleName), 0); + } + return IntPtr.Zero; + } + } + + private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) + { + if (nCode >= 0) + { + if (wParam == (IntPtr)NativeMethods.WM_KEYDOWN) + { + var virtualKey = Marshal.ReadInt32(lParam); + + KeyDown?.Invoke(null, new KeyboardHookEventArgs(virtualKey)); + } + else if (wParam == (IntPtr)NativeMethods.WM_KEYUP) + { + var virtualKey = Marshal.ReadInt32(lParam); + + KeyUp?.Invoke(null, new KeyboardHookEventArgs(virtualKey)); + } + } + return UnsafeNativeMethods.CallNextHookEx(HookId, nCode, wParam, lParam); + } + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Tools/Interop/NativeMethods.cs b/src/Shared/HandyControl_Shared/Tools/Interop/NativeMethods.cs index dcff9ac8..94ae1c3b 100644 --- a/src/Shared/HandyControl_Shared/Tools/Interop/NativeMethods.cs +++ b/src/Shared/HandyControl_Shared/Tools/Interop/NativeMethods.cs @@ -31,6 +31,8 @@ namespace HandyControl.Tools.Interop NIIF_INFO = 0x00000001, NIIF_WARNING = 0x00000002, NIIF_ERROR = 0x00000003, + WM_KEYDOWN = 0x0100, + WM_KEYUP = 0x0101, WM_MOUSEMOVE = 0x0200, WM_LBUTTONDOWN = 0x0201, WM_LBUTTONUP = 0x0202, diff --git a/src/Shared/HandyControl_Shared/Tools/Interop/UnsafeNativeMethods.cs b/src/Shared/HandyControl_Shared/Tools/Interop/UnsafeNativeMethods.cs index 1c893525..2e4d1908 100644 --- a/src/Shared/HandyControl_Shared/Tools/Interop/UnsafeNativeMethods.cs +++ b/src/Shared/HandyControl_Shared/Tools/Interop/UnsafeNativeMethods.cs @@ -186,7 +186,8 @@ namespace HandyControl.Tools.Interop public enum HookType { - WH_MOUSE_LL = 14, + WH_KEYBOARD_LL = 13, + WH_MOUSE_LL = 14 } [StructLayout(LayoutKind.Sequential)]