Add hotkey setting

This commit is contained in:
qianlifeng
2014-02-22 11:55:48 +08:00
parent efdd8daa01
commit 2f5a4f63b6
11 changed files with 208 additions and 130 deletions

View File

@@ -62,6 +62,7 @@ namespace Wox.Infrastructure
Instance.UserSetting.Theme = "Default";
Instance.UserSetting.ReplaceWinR = true;
Instance.UserSetting.WebSearches = Instance.UserSetting.LoadDefaultWebSearches();
Instance.UserSetting.Hotkey = "Win + W";
}
public static CommonStorage Instance

View File

@@ -4,7 +4,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Wox.Plugin;
namespace Wox.Helper
namespace Wox.Infrastructure
{
public enum KeyEvent : int
{
@@ -29,8 +29,6 @@ namespace Wox.Helper
WM_SYSKEYDOWN = 260
}
/// <summary>
/// Listens keyboard globally.
/// <remarks>Uses WH_KEYBOARD_LL.</remarks>
@@ -153,37 +151,6 @@ namespace Wox.Helper
internal static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);
}
public enum InputType
{
INPUT_MOUSE = 0,
INPUT_KEYBOARD = 1,
INPUT_HARDWARE = 2,
}
[Flags()]
public enum MOUSEEVENTF
{
MOVE = 0x0001, //mouse move
LEFTDOWN = 0x0002, //left button down
LEFTUP = 0x0004, //left button up
RIGHTDOWN = 0x0008, //right button down
RIGHTUP = 0x0010, //right button up
MIDDLEDOWN = 0x0020, //middle button down
MIDDLEUP = 0x0040, //middle button up
XDOWN = 0x0080, //x button down
XUP = 0x0100, //x button down
WHEEL = 0x0800, //wheel button rolled
VIRTUALDESK = 0x4000, //map to entire virtual desktop
ABSOLUTE = 0x8000, //absolute move
}
[Flags()]
public enum KEYEVENTF
{
EXTENDEDKEY = 0x0001,
KEYUP = 0x0002,
UNICODE = 0x0004,
SCANCODE = 0x0008,
}
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{

View File

@@ -5,6 +5,7 @@ namespace Wox.Infrastructure.UserSettings
{
public class UserSetting
{
public string Hotkey { get; set; }
public string Theme { get; set; }
public bool ReplaceWinR { get; set; }
public List<WebSearch> WebSearches { get; set; }

View File

@@ -50,6 +50,8 @@
<Compile Include="ChineseToPinYin.cs" />
<Compile Include="CommonStorage.cs" />
<Compile Include="FuzzyMatcher.cs" />
<Compile Include="GloablHotkey.cs" />
<Compile Include="HotkeyModel.cs" />
<Compile Include="IniParser.cs" />
<Compile Include="UAC.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

View File

@@ -4,10 +4,14 @@
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"
Height="24"
d:DesignHeight="300" d:DesignWidth="300">
<Grid >
<TextBox x:Name="tbHotkey" PreviewKeyDown="TbHotkey_OnPreviewKeyDown"></TextBox>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"></ColumnDefinition>
<ColumnDefinition Width="120"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox x:Name="tbHotkey" VerticalContentAlignment="Center" Grid.Column="0" PreviewKeyDown="TbHotkey_OnPreviewKeyDown"></TextBox>
<TextBlock x:Name="tbMsg" Visibility="Hidden" Margin="5 0 0 0" VerticalAlignment="Center" Grid.Column="1" ></TextBlock>
</Grid>
</UserControl>

View File

@@ -1,17 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
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 NHotkey;
using NHotkey.Wpf;
using Wox.Helper;
using Wox.Infrastructure;
using Wox.Plugin;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using UserControl = System.Windows.Controls.UserControl;
@@ -20,13 +15,34 @@ namespace Wox
{
public partial class HotkeyControl : UserControl
{
public HotkeyModel CurrentHotkey { get; private set; }
public bool CurrentHotkeyAvailable { get; private set; }
public event EventHandler OnHotkeyChanged;
protected virtual void OnOnHotkeyChanged()
{
EventHandler handler = OnHotkeyChanged;
if (handler != null) handler(this, EventArgs.Empty);
}
public HotkeyControl()
{
InitializeComponent();
}
public void SetHotkey(HotkeyModel model)
{
if (model != null)
{
SetHotkey(model.ToString());
}
}
private void TbHotkey_OnPreviewKeyDown(object sender, KeyEventArgs e)
{
tbMsg.Visibility = Visibility.Hidden;
//when alt is pressed, the real key should be e.SystemKey
Key key = (e.Key == Key.System ? e.SystemKey : e.Key);
@@ -34,35 +50,87 @@ namespace Wox
SpecialKeyState specialKeyState = new GloablHotkey().CheckModifiers();
if (specialKeyState.AltPressed)
{
text += "Alt ";
text += "Alt";
}
if (specialKeyState.CtrlPressed)
{
text += "Ctrl ";
text += string.IsNullOrEmpty(text) ? "Ctrl" : " + Ctrl";
}
if (specialKeyState.ShiftPressed)
{
text += "Shift ";
text += string.IsNullOrEmpty(text) ? "Shift" : " + Shift";
}
if (specialKeyState.WinPressed)
{
text += "Win ";
text += string.IsNullOrEmpty(text) ? "Win" : " + Win";
}
if(IsKeyAChar(key))
if (string.IsNullOrEmpty(text))
{
text += e.Key.ToString();
}
if (key == Key.Space)
{
text += "Space";
text += "Ctrl + Alt";
}
tbHotkey.Text = text;
if (IsKeyACharOrNumber(key))
{
text += " + " + key;
}
else if (key == Key.Space)
{
text += " + Space";
}
private static bool IsKeyAChar(Key key)
e.Handled = true;
Dispatcher.DelayInvoke("HotkeyAvailableTest", o => SetHotkey(text), TimeSpan.FromMilliseconds(300));
}
public void SetHotkey(string keyStr)
{
return key >= Key.A && key <= Key.Z;
tbHotkey.Text = keyStr;
tbHotkey.Select(tbHotkey.Text.Length, 0);
CurrentHotkey = new HotkeyModel(keyStr);
CurrentHotkeyAvailable = CheckHotAvailabel(CurrentHotkey);
tbMsg.Visibility = Visibility.Visible;
if (!CurrentHotkeyAvailable)
{
tbMsg.Foreground = new SolidColorBrush(Colors.Red);
tbMsg.Text = "hotkey unavailable";
}
else
{
tbMsg.Foreground = new SolidColorBrush(Colors.Green);
tbMsg.Text = "hotkey available";
}
OnOnHotkeyChanged();
}
private bool CheckHotAvailabel(HotkeyModel hotkey)
{
try
{
HotkeyManager.Current.AddOrReplace("HotkeyAvailableTest", hotkey.CharKey, hotkey.ModifierKeys, OnHotkey);
return true;
}
catch
{
}
finally
{
HotkeyManager.Current.Remove("HotkeyAvailableTest");
}
return false;
}
private void OnHotkey(object sender, HotkeyEventArgs e)
{
}
private static bool IsKeyACharOrNumber(Key key)
{
return (key >= Key.A && key <= Key.Z) || (key >= Key.D0 && key <= Key.D9);
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading;
@@ -8,29 +9,33 @@ using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media.Animation;
using WindowsInput;
using WindowsInput.Native;
using NHotkey;
using NHotkey.Wpf;
using Wox.Commands;
using Wox.Helper;
using Wox.Infrastructure;
using Wox.Plugin;
using Wox.PluginLoader;
using Application = System.Windows.Application;
using ContextMenu = System.Windows.Forms.ContextMenu;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using MenuItem = System.Windows.Forms.MenuItem;
using MessageBox = System.Windows.MessageBox;
using Timer = System.Timers.Timer;
namespace Wox
{
public partial class MainWindow
{
private static readonly object locker = new object();
private readonly GloablHotkey globalHotkey = new GloablHotkey();
private readonly KeyboardSimulator keyboardSimulator = new KeyboardSimulator(new InputSimulator());
private readonly Storyboard progressBarStoryboard = new Storyboard();
private bool WinRStroked;
private NotifyIcon notifyIcon;
Storyboard progressBarStoryboard = new Storyboard();
private bool queryHasReturn = false;
private GloablHotkey globalHotkey = new GloablHotkey();
private bool WinRStroked = false;
private static object locker = new object();
private WindowsInput.KeyboardSimulator keyboardSimulator = new WindowsInput.KeyboardSimulator(new WindowsInput.InputSimulator());
private bool queryHasReturn;
public MainWindow()
{
@@ -49,8 +54,22 @@ namespace Wox
SetTheme(CommonStorage.Instance.UserSetting.Theme = "Default");
}
HotkeyManager.Current.AddOrReplace("ShowHideWox", Key.W, ModifierKeys.Windows, OnHotkey);
this.Closing += MainWindow_Closing;
Closing += MainWindow_Closing;
}
public void SetHotkey(string hotkeyStr)
{
HotkeyModel hotkey = new HotkeyModel(hotkeyStr);
try
{
HotkeyManager.Current.AddOrReplace("ShowHideWox", hotkey.CharKey, hotkey.ModifierKeys, OnHotkey);
}
catch (Exception)
{
MessageBox.Show("Registe hotkey: " + CommonStorage.Instance.UserSetting.Hotkey + " failed.");
}
}
private void OnHotkey(object sender, HotkeyEventArgs e)
@@ -66,7 +85,7 @@ namespace Wox
e.Handled = true;
}
void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
private void MainWindow_Closing(object sender, CancelEventArgs e)
{
e.Cancel = true;
}
@@ -77,7 +96,7 @@ namespace Wox
//This is caused by the Virtual Mermory Page Mechanisam. So, our solution is execute some codes in every min
//which may prevent sysetem uninstall memory from RAM to disk.
System.Timers.Timer t = new System.Timers.Timer(1000 * 60 * 5) { AutoReset = true, Enabled = true };
var t = new Timer(1000*60*5) {AutoReset = true, Enabled = true};
t.Elapsed += (o, e) => Dispatcher.Invoke(new Action(() =>
{
if (Visibility != Visibility.Visible)
@@ -94,8 +113,8 @@ namespace Wox
private void InitProgressbarAnimation()
{
DoubleAnimation da = new DoubleAnimation(progressBar.X2, Width + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
DoubleAnimation da1 = new DoubleAnimation(progressBar.X1, Width, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
var da = new DoubleAnimation(progressBar.X2, Width + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
var da1 = new DoubleAnimation(progressBar.X1, Width, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
Storyboard.SetTargetProperty(da, new PropertyPath("(Line.X2)"));
Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)"));
progressBarStoryboard.Children.Add(da);
@@ -107,19 +126,21 @@ namespace Wox
private void InitialTray()
{
notifyIcon = new NotifyIcon { Text = "Wox", Icon = Properties.Resources.app, Visible = true };
notifyIcon = new NotifyIcon {Text = "Wox", Icon = Properties.Resources.app, Visible = true};
notifyIcon.Click += (o, e) => ShowWox();
System.Windows.Forms.MenuItem open = new System.Windows.Forms.MenuItem("Open");
var open = new MenuItem("Open");
open.Click += (o, e) => ShowWox();
System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem("Exit");
var exit = new MenuItem("Exit");
exit.Click += (o, e) => CloseApp();
System.Windows.Forms.MenuItem[] childen = { open, exit };
notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen);
MenuItem[] childen = {open, exit};
notifyIcon.ContextMenu = new ContextMenu(childen);
}
private void resultCtrl_resultItemChangedEvent()
{
resultCtrl.Margin = resultCtrl.GetCurrentResultCount() > 0 ? new Thickness { Top = grid.Margin.Top } : new Thickness { Top = 0 };
resultCtrl.Margin = resultCtrl.GetCurrentResultCount() > 0
? new Thickness {Top = grid.Margin.Top}
: new Thickness {Top = 0};
}
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
@@ -149,7 +170,6 @@ namespace Wox
}
}, TimeSpan.FromSeconds(1), tbQuery.Text);
}
}, TimeSpan.FromMilliseconds(150));
}
@@ -205,9 +225,10 @@ namespace Wox
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
Left = (SystemParameters.PrimaryScreenWidth - ActualWidth) / 2;
Top = (SystemParameters.PrimaryScreenHeight - ActualHeight) / 3;
Left = (SystemParameters.PrimaryScreenWidth - ActualWidth)/2;
Top = (SystemParameters.PrimaryScreenHeight - ActualHeight)/3;
SetHotkey(CommonStorage.Instance.UserSetting.Hotkey);
WakeupApp();
Plugins.Init();
@@ -219,16 +240,16 @@ namespace Wox
if (CommonStorage.Instance.UserSetting.ReplaceWinR)
{
//todo:need refatoring. move those codes to CMD file or expose events
if (keyevent == KeyEvent.WM_KEYDOWN && vkcode == (int)Keys.R && state.WinPressed)
if (keyevent == KeyEvent.WM_KEYDOWN && vkcode == (int) Keys.R && state.WinPressed)
{
WinRStroked = true;
Dispatcher.BeginInvoke(new Action(OnWinRPressed));
return false;
}
if (keyevent == KeyEvent.WM_KEYUP && WinRStroked && vkcode == (int)Keys.LWin)
if (keyevent == KeyEvent.WM_KEYUP && WinRStroked && vkcode == (int) Keys.LWin)
{
WinRStroked = false;
keyboardSimulator.ModifiedKeyStroke(WindowsInput.Native.VirtualKeyCode.LWIN, WindowsInput.Native.VirtualKeyCode.CONTROL);
keyboardSimulator.ModifiedKeyStroke(VirtualKeyCode.LWIN, VirtualKeyCode.CONTROL);
return false;
}
}
@@ -294,7 +315,8 @@ namespace Wox
if (list.Count > 0)
{
//todo:this should be opened to users, it's their choise to use it or not in thier workflows
list.ForEach(o =>
list.ForEach(
o =>
{
if (o.AutoAjustScore) o.Score += CommonStorage.Instance.UserSelectedRecords.GetSelectedCount(o);
});
@@ -302,7 +324,8 @@ namespace Wox
{
resultCtrl.Dispatcher.Invoke(new Action(() =>
{
List<Result> l = list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == tbQuery.Text).ToList();
List<Result> l =
list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == tbQuery.Text).ToList();
resultCtrl.AddResults(list);
}));
}
@@ -311,7 +334,7 @@ namespace Wox
public void SetTheme(string themeName)
{
ResourceDictionary dict = new ResourceDictionary
var dict = new ResourceDictionary
{
Source = new Uri("pack://application:,,,/Themes/" + themeName + ".xaml")
};
@@ -348,13 +371,13 @@ namespace Wox
public void ShowMsg(string title, string subTitle, string iconPath)
{
Msg m = new Msg { Owner = GetWindow(this) };
var m = new Msg {Owner = GetWindow(this)};
m.Show(title, subTitle, iconPath);
}
public void OpenSettingDialog()
{
SettingWidow s = new SettingWidow(this);
var s = new SettingWidow(this);
s.Show();
}

View File

@@ -3,6 +3,7 @@ using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Wox.Helper;
using Wox.Infrastructure;
using Wox.Plugin;
namespace Wox

View File

@@ -24,7 +24,7 @@
<ComboBox x:Name="themeComboBox" SelectionChanged="ThemeComboBox_OnSelectionChanged" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<wox:HotkeyControl />
<wox:HotkeyControl x:Name="ctlHotkey" />
</StackPanel>
</StackPanel>
</TabItem>

View File

@@ -31,6 +31,8 @@ namespace Wox
this.mainWindow = mainWindow;
InitializeComponent();
Loaded += Setting_Loaded;
ctlHotkey.OnHotkeyChanged += ctlHotkey_OnHotkeyChanged;
ctlHotkey.SetHotkey(CommonStorage.Instance.UserSetting.Hotkey);
cbReplaceWinR.Checked += (o, e) =>
{
CommonStorage.Instance.UserSetting.ReplaceWinR = true;
@@ -43,6 +45,16 @@ namespace Wox
};
}
void ctlHotkey_OnHotkeyChanged(object sender, System.EventArgs e)
{
if (ctlHotkey.CurrentHotkeyAvailable)
{
mainWindow.SetHotkey(ctlHotkey.CurrentHotkey.ToString());
CommonStorage.Instance.UserSetting.Hotkey = ctlHotkey.CurrentHotkey.ToString();
CommonStorage.Instance.Save();
}
}
private void Setting_Loaded(object sender, RoutedEventArgs e)
{
foreach (string theme in LoadAvailableThemes())

View File

@@ -129,7 +129,6 @@
<Compile Include="Helper\Log.cs" />
<Compile Include="Helper\PluginInstaller.cs" />
<Compile Include="Helper\WoxException.cs" />
<Compile Include="Helper\GloablHotkey.cs" />
<Compile Include="HotkeyControl.xaml.cs">
<DependentUpon>HotkeyControl.xaml</DependentUpon>
</Compile>