From 8f2d69b7f76e954af90305e644b00a98c9c7e9ce Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Thu, 20 Feb 2014 23:15:03 +0800 Subject: [PATCH] Add NHotkey library. --- .../{KeyboardListener.cs => GloablHotkey.cs} | 6 +- Wox/Helper/KeyboardHook.cs | 154 ------------------ Wox/HotkeyControl.xaml | 13 ++ Wox/HotkeyControl.xaml.cs | 68 ++++++++ Wox/MainWindow.xaml.cs | 40 ++--- Wox/ResultItem.xaml.cs | 2 +- Wox/ResultPanel.xaml.cs | 2 +- Wox/SettingWindow.xaml | 4 + Wox/Wox.csproj | 23 ++- Wox/packages.config | 2 + 10 files changed, 124 insertions(+), 190 deletions(-) rename Wox/Helper/{KeyboardListener.cs => GloablHotkey.cs} (98%) delete mode 100644 Wox/Helper/KeyboardHook.cs create mode 100644 Wox/HotkeyControl.xaml create mode 100644 Wox/HotkeyControl.xaml.cs diff --git a/Wox/Helper/KeyboardListener.cs b/Wox/Helper/GloablHotkey.cs similarity index 98% rename from Wox/Helper/KeyboardListener.cs rename to Wox/Helper/GloablHotkey.cs index 49afebbc37..7871633fee 100644 --- a/Wox/Helper/KeyboardListener.cs +++ b/Wox/Helper/GloablHotkey.cs @@ -35,7 +35,7 @@ namespace Wox.Helper /// Listens keyboard globally. /// Uses WH_KEYBOARD_LL. /// - public class KeyboardListener : IDisposable + public class GloablHotkey : IDisposable { private InterceptKeys.LowLevelKeyboardProc hookedLowLevelKeyboardProc; private IntPtr hookId = IntPtr.Zero; @@ -48,7 +48,7 @@ namespace Wox.Helper private const int VK_ALT = 0x12; private const int VK_WIN = 91; - public KeyboardListener() + public GloablHotkey() { // We have to store the LowLevelKeyboardProc, so that it is not garbage collected runtime hookedLowLevelKeyboardProc = LowLevelKeyboardProc; @@ -107,7 +107,7 @@ namespace Wox.Helper return (IntPtr)1; } - ~KeyboardListener() + ~GloablHotkey() { Dispose(); } diff --git a/Wox/Helper/KeyboardHook.cs b/Wox/Helper/KeyboardHook.cs deleted file mode 100644 index 92acd37e4e..0000000000 --- a/Wox/Helper/KeyboardHook.cs +++ /dev/null @@ -1,154 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Windows.Forms; - -namespace Wox.Helper -{ - public sealed class KeyboardHook : IDisposable - { - // Registers a hot key with Windows. - [DllImport("user32.dll")] - private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); - // Unregisters the hot key with Windows. - [DllImport("user32.dll")] - private static extern bool UnregisterHotKey(IntPtr hWnd, int id); - /// - /// Represents the window that is used internally to get the messages. - /// - private class Window : NativeWindow, IDisposable - { - private static int wmHotkey = 0x0312; - - public Window() - { - // create the handle for the window. - CreateHandle(new CreateParams()); - } - - /// - /// Overridden to get the notifications. - /// - /// - protected override void WndProc(ref Message m) - { - base.WndProc(ref m); - - // check if we got a hot key pressed. - if (m.Msg == wmHotkey) - { - // get the keys. - Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF); - XModifierKeys xModifier = (XModifierKeys)((int)m.LParam & 0xFFFF); - - // invoke the event to notify the parent. - if (KeyPressed != null) - KeyPressed(this, new KeyPressedEventArgs(xModifier, key)); - } - } - - public event EventHandler KeyPressed; - - #region IDisposable Members - - public void Dispose() - { - DestroyHandle(); - } - - #endregion - } - - private Window window = new Window(); - private int currentId; - - public KeyboardHook() - { - // register the event of the inner native window. - window.KeyPressed += delegate(object sender, KeyPressedEventArgs args) - { - if (KeyPressed != null) - KeyPressed(this, args); - }; - } - - /// - /// Registers a hot key in the system. - /// - /// The modifiers that are associated with the hot key. - /// The key itself that is associated with the hot key. - public void RegisterHotKey(XModifierKeys xModifier, Keys key) - { - // increment the counter. - currentId = currentId + 1; - - // register the hot key. - if (!RegisterHotKey(window.Handle, currentId, (uint)xModifier, (uint)key)) - { - Log.Error("Couldn’t register the hot key."); - MessageBox.Show("Couldn’t register the hot key."); -#if (DEBUG) - { - throw new InvalidOperationException("Couldn’t register the hot key."); - } -#endif - } - } - - /// - /// A hot key has been pressed. - /// - public event EventHandler KeyPressed; - - #region IDisposable Members - - public void Dispose() - { - // unregister all the registered hot keys. - for (int i = currentId; i > 0; i--) - { - UnregisterHotKey(window.Handle, i); - } - - // dispose the inner native window. - window.Dispose(); - } - - #endregion - } - - /// - /// Event Args for the event that is fired after the hot key has been pressed. - /// - public class KeyPressedEventArgs : EventArgs - { - private XModifierKeys xModifier; - private Keys key; - - internal KeyPressedEventArgs(XModifierKeys xModifier, Keys key) - { - this.xModifier = xModifier; - this.key = key; - } - - public XModifierKeys XModifier - { - get { return xModifier; } - } - - public Keys Key - { - get { return key; } - } - } - - /// - /// The enumeration of possible modifiers. - /// - public enum XModifierKeys : uint - { - Alt = 1, - Control = 2, - Shift = 4, - Win = 8 - } -} diff --git a/Wox/HotkeyControl.xaml b/Wox/HotkeyControl.xaml new file mode 100644 index 0000000000..0a73439bc7 --- /dev/null +++ b/Wox/HotkeyControl.xaml @@ -0,0 +1,13 @@ + + + + + diff --git a/Wox/HotkeyControl.xaml.cs b/Wox/HotkeyControl.xaml.cs new file mode 100644 index 0000000000..e5b2044064 --- /dev/null +++ b/Wox/HotkeyControl.xaml.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Forms; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Wox.Helper; +using Wox.Plugin; +using KeyEventArgs = System.Windows.Input.KeyEventArgs; +using UserControl = System.Windows.Controls.UserControl; + +namespace Wox +{ + public partial class HotkeyControl : UserControl + { + public HotkeyControl() + { + InitializeComponent(); + } + + private void TbHotkey_OnPreviewKeyDown(object sender, KeyEventArgs e) + { + //when alt is pressed, the real key should be e.SystemKey + Key key = (e.Key == Key.System ? e.SystemKey : e.Key); + + string text = string.Empty; + SpecialKeyState specialKeyState = new GloablHotkey().CheckModifiers(); + if (specialKeyState.AltPressed) + { + text += "Alt "; + } + if (specialKeyState.CtrlPressed) + { + text += "Ctrl "; + } + if (specialKeyState.ShiftPressed) + { + text += "Shift "; + } + if (specialKeyState.WinPressed) + { + text += "Win "; + } + if(IsKeyAChar(key)) + { + text += e.Key.ToString(); + } + if (key == Key.Space) + { + text += "Space"; + } + + tbHotkey.Text = text; + } + + private static bool IsKeyAChar(Key key) + { + return key >= Key.A && key <= Key.Z; + } + } +} diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index ce104b4ebf..872d993158 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -1,16 +1,15 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; -using System.Runtime.InteropServices; using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Media.Animation; -using System.Windows.Threading; +using NHotkey; +using NHotkey.Wpf; using Wox.Commands; using Wox.Helper; using Wox.Infrastructure; @@ -18,19 +17,16 @@ using Wox.Plugin; using Wox.PluginLoader; using Application = System.Windows.Application; using KeyEventArgs = System.Windows.Input.KeyEventArgs; -using MessageBox = System.Windows.MessageBox; -using UserControl = System.Windows.Controls.UserControl; namespace Wox { public partial class MainWindow { - private KeyboardHook hook = new KeyboardHook(); private NotifyIcon notifyIcon; Storyboard progressBarStoryboard = new Storyboard(); private bool queryHasReturn = false; - private KeyboardListener keyboardListener = new KeyboardListener(); + private GloablHotkey globalHotkey = new GloablHotkey(); private bool WinRStroked = false; private static object locker = new object(); @@ -41,8 +37,6 @@ namespace Wox InitializeComponent(); InitialTray(); - hook.KeyPressed += OnHotKey; - hook.RegisterHotKey(XModifierKeys.Alt, Keys.Space); resultCtrl.resultItemChangedEvent += resultCtrl_resultItemChangedEvent; ThreadPool.SetMaxThreads(30, 10); InitProgressbarAnimation(); @@ -55,9 +49,23 @@ namespace Wox SetTheme(CommonStorage.Instance.UserSetting.Theme = "Default"); } + HotkeyManager.Current.AddOrReplace("ShowHideWox", Key.W, ModifierKeys.Windows, OnHotkey); this.Closing += MainWindow_Closing; } + private void OnHotkey(object sender, HotkeyEventArgs e) + { + if (!IsVisible) + { + ShowWox(); + } + else + { + HideWox(); + } + e.Handled = true; + } + void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { e.Cancel = true; @@ -114,18 +122,6 @@ namespace Wox resultCtrl.Margin = resultCtrl.GetCurrentResultCount() > 0 ? new Thickness { Top = grid.Margin.Top } : new Thickness { Top = 0 }; } - private void OnHotKey(object sender, KeyPressedEventArgs e) - { - if (!IsVisible) - { - ShowWox(); - } - else - { - HideWox(); - } - } - private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) { resultCtrl.Dirty = true; @@ -215,7 +211,7 @@ namespace Wox WakeupApp(); Plugins.Init(); - keyboardListener.hookedKeyboardCallback += KListener_hookedKeyboardCallback; + globalHotkey.hookedKeyboardCallback += KListener_hookedKeyboardCallback; } private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state) diff --git a/Wox/ResultItem.xaml.cs b/Wox/ResultItem.xaml.cs index 7671c70fc2..e4bb0bf109 100644 --- a/Wox/ResultItem.xaml.cs +++ b/Wox/ResultItem.xaml.cs @@ -72,7 +72,7 @@ namespace Wox if (Result.Action != null) Result.Action(new ActionContext() { - SpecialKeyState = new KeyboardListener().CheckModifiers() + SpecialKeyState = new GloablHotkey().CheckModifiers() }); CommonStorage.Instance.UserSelectedRecords.Add(result); diff --git a/Wox/ResultPanel.xaml.cs b/Wox/ResultPanel.xaml.cs index 118f8923e8..8d6e7cf1ed 100644 --- a/Wox/ResultPanel.xaml.cs +++ b/Wox/ResultPanel.xaml.cs @@ -215,7 +215,7 @@ namespace Wox { resultItemControl.Result.Action(new ActionContext() { - SpecialKeyState = new KeyboardListener().CheckModifiers() + SpecialKeyState = new GloablHotkey().CheckModifiers() }); } diff --git a/Wox/SettingWindow.xaml b/Wox/SettingWindow.xaml index d8cc3f69ca..37247497dc 100644 --- a/Wox/SettingWindow.xaml +++ b/Wox/SettingWindow.xaml @@ -1,6 +1,7 @@  + + + diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 4551a075e5..cffd524546 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -89,6 +89,12 @@ ..\packages\Newtonsoft.Json.5.0.8\lib\net35\Newtonsoft.Json.dll + + ..\packages\NHotkey.1.1.0.0\lib\NHotkey.dll + + + ..\packages\NHotkey.Wpf.1.1.0.0\lib\NHotkey.Wpf.dll + @@ -120,11 +126,13 @@ - - + + + HotkeyControl.xaml + Msg.xaml @@ -140,15 +148,16 @@ ResultItem.xaml - - ResultWindow.xaml - SettingWindow.xaml WebSearchSetting.xaml + + Designer + MSBuild:Compile + MSBuild:Compile Designer @@ -173,10 +182,6 @@ Designer MSBuild:Compile - - MSBuild:Compile - Designer - Designer MSBuild:Compile diff --git a/Wox/packages.config b/Wox/packages.config index edde682830..2e5ba2b823 100644 --- a/Wox/packages.config +++ b/Wox/packages.config @@ -3,5 +3,7 @@ + + \ No newline at end of file