Add NHotkey library.

This commit is contained in:
qianlifeng
2014-02-20 23:15:03 +08:00
parent 445f06f4b3
commit 8f2d69b7f7
10 changed files with 124 additions and 190 deletions

View File

@@ -35,7 +35,7 @@ namespace Wox.Helper
/// Listens keyboard globally.
/// <remarks>Uses WH_KEYBOARD_LL.</remarks>
/// </summary>
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();
}

View File

@@ -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);
/// <summary>
/// Represents the window that is used internally to get the messages.
/// </summary>
private class Window : NativeWindow, IDisposable
{
private static int wmHotkey = 0x0312;
public Window()
{
// create the handle for the window.
CreateHandle(new CreateParams());
}
/// <summary>
/// Overridden to get the notifications.
/// </summary>
/// <param name="m"></param>
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<KeyPressedEventArgs> 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);
};
}
/// <summary>
/// Registers a hot key in the system.
/// </summary>
/// <param name="xModifier">The modifiers that are associated with the hot key.</param>
/// <param name="key">The key itself that is associated with the hot key.</param>
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("Couldnt register the hot key.");
MessageBox.Show("Couldnt register the hot key.");
#if (DEBUG)
{
throw new InvalidOperationException("Couldnt register the hot key.");
}
#endif
}
}
/// <summary>
/// A hot key has been pressed.
/// </summary>
public event EventHandler<KeyPressedEventArgs> 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
}
/// <summary>
/// Event Args for the event that is fired after the hot key has been pressed.
/// </summary>
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; }
}
}
/// <summary>
/// The enumeration of possible modifiers.
/// </summary>
public enum XModifierKeys : uint
{
Alt = 1,
Control = 2,
Shift = 4,
Win = 8
}
}

13
Wox/HotkeyControl.xaml Normal file
View File

@@ -0,0 +1,13 @@
<UserControl x:Class="Wox.HotkeyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Height="50"
Width="300"
d:DesignHeight="300" d:DesignWidth="300">
<Grid >
<TextBox x:Name="tbHotkey" PreviewKeyDown="TbHotkey_OnPreviewKeyDown"></TextBox>
</Grid>
</UserControl>

68
Wox/HotkeyControl.xaml.cs Normal file
View File

@@ -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;
}
}
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -215,7 +215,7 @@ namespace Wox
{
resultItemControl.Result.Action(new ActionContext()
{
SpecialKeyState = new KeyboardListener().CheckModifiers()
SpecialKeyState = new GloablHotkey().CheckModifiers()
});
}

View File

@@ -1,6 +1,7 @@
<Window x:Class="Wox.SettingWidow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wox="clr-namespace:Wox"
Icon="Images\app.png"
Title="Wox Setting"
ResizeMode="NoResize"
@@ -22,6 +23,9 @@
<TextBlock Text="Theme:" />
<ComboBox x:Name="themeComboBox" SelectionChanged="ThemeComboBox_OnSelectionChanged" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<wox:HotkeyControl />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Header="Web Search">

View File

@@ -89,6 +89,12 @@
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net35\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NHotkey">
<HintPath>..\packages\NHotkey.1.1.0.0\lib\NHotkey.dll</HintPath>
</Reference>
<Reference Include="NHotkey.Wpf">
<HintPath>..\packages\NHotkey.Wpf.1.1.0.0\lib\NHotkey.Wpf.dll</HintPath>
</Reference>
<Reference Include="PresentationUI, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="ReachFramework" />
<Reference Include="System" />
@@ -120,11 +126,13 @@
<Compile Include="Commands\PluginCommand.cs" />
<Compile Include="Commands\SystemCommand.cs" />
<Compile Include="DispatcherExtensions.cs" />
<Compile Include="Helper\KeyboardHook.cs" />
<Compile Include="Helper\Log.cs" />
<Compile Include="Helper\PluginInstaller.cs" />
<Compile Include="Helper\WoxException.cs" />
<Compile Include="Helper\KeyboardListener.cs" />
<Compile Include="Helper\GloablHotkey.cs" />
<Compile Include="HotkeyControl.xaml.cs">
<DependentUpon>HotkeyControl.xaml</DependentUpon>
</Compile>
<Compile Include="Msg.xaml.cs">
<DependentUpon>Msg.xaml</DependentUpon>
</Compile>
@@ -140,15 +148,16 @@
<Compile Include="ResultItem.xaml.cs">
<DependentUpon>ResultItem.xaml</DependentUpon>
</Compile>
<Compile Include="ResultWindow.xaml.cs">
<DependentUpon>ResultWindow.xaml</DependentUpon>
</Compile>
<Compile Include="SettingWindow.xaml.cs">
<DependentUpon>SettingWindow.xaml</DependentUpon>
</Compile>
<Compile Include="WebSearchSetting.xaml.cs">
<DependentUpon>WebSearchSetting.xaml</DependentUpon>
</Compile>
<Page Include="HotkeyControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -173,10 +182,6 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="ResultWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="SettingWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@@ -3,5 +3,7 @@
<package id="InputSimulator" version="1.0.4.0" targetFramework="net35" />
<package id="log4net" version="2.0.3" targetFramework="net35" />
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net35" />
<package id="NHotkey" version="1.1.0.0" targetFramework="net35" />
<package id="NHotkey.Wpf" version="1.1.0.0" targetFramework="net35" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net35" />
</packages>