mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-06 03:07:04 +02:00
Refactoring
This commit is contained in:
192
Wox.Infrastructure/Hotkey/GlobalHotkey.cs
Normal file
192
Wox.Infrastructure/Hotkey/GlobalHotkey.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox.Infrastructure.Hotkey
|
||||
{
|
||||
public enum KeyEvent : int
|
||||
{
|
||||
/// <summary>
|
||||
/// Key down
|
||||
/// </summary>
|
||||
WM_KEYDOWN = 256,
|
||||
|
||||
/// <summary>
|
||||
/// Key up
|
||||
/// </summary>
|
||||
WM_KEYUP = 257,
|
||||
|
||||
/// <summary>
|
||||
/// System key up
|
||||
/// </summary>
|
||||
WM_SYSKEYUP = 261,
|
||||
|
||||
/// <summary>
|
||||
/// System key down
|
||||
/// </summary>
|
||||
WM_SYSKEYDOWN = 260
|
||||
}
|
||||
|
||||
public static class InterceptKeys
|
||||
{
|
||||
public delegate IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam);
|
||||
|
||||
private static int WH_KEYBOARD_LL = 13;
|
||||
|
||||
public static IntPtr SetHook(LowLevelKeyboardProc proc)
|
||||
{
|
||||
using (Process curProcess = Process.GetCurrentProcess())
|
||||
using (ProcessModule curModule = curProcess.MainModule)
|
||||
{
|
||||
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, UIntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern short GetKeyState(int keyCode);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct INPUT
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public Int32 type;//0-MOUSEINPUT;1-KEYBDINPUT;2-HARDWAREINPUT
|
||||
[FieldOffset(4)]
|
||||
public KEYBDINPUT ki;
|
||||
[FieldOffset(4)]
|
||||
public MOUSEINPUT mi;
|
||||
[FieldOffset(4)]
|
||||
public HARDWAREINPUT hi;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MOUSEINPUT
|
||||
{
|
||||
public Int32 dx;
|
||||
public Int32 dy;
|
||||
public Int32 mouseData;
|
||||
public Int32 dwFlags;
|
||||
public Int32 time;
|
||||
public IntPtr dwExtraInfo;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct KEYBDINPUT
|
||||
{
|
||||
public Int16 wVk;
|
||||
public Int16 wScan;
|
||||
public Int32 dwFlags;
|
||||
public Int32 time;
|
||||
public IntPtr dwExtraInfo;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct HARDWAREINPUT
|
||||
{
|
||||
public Int32 uMsg;
|
||||
public Int16 wParamL;
|
||||
public Int16 wParamH;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Listens keyboard globally.
|
||||
/// <remarks>Uses WH_KEYBOARD_LL.</remarks>
|
||||
/// </summary>
|
||||
public class GlobalHotkey : IDisposable
|
||||
{
|
||||
private InterceptKeys.LowLevelKeyboardProc hookedLowLevelKeyboardProc;
|
||||
private IntPtr hookId = IntPtr.Zero;
|
||||
public delegate bool KeyboardCallback(KeyEvent keyEvent, int vkCode, SpecialKeyState state);
|
||||
public event KeyboardCallback hookedKeyboardCallback;
|
||||
|
||||
//Modifier key constants
|
||||
private const int VK_SHIFT = 0x10;
|
||||
private const int VK_CONTROL = 0x11;
|
||||
private const int VK_ALT = 0x12;
|
||||
private const int VK_WIN = 91;
|
||||
|
||||
public GlobalHotkey()
|
||||
{
|
||||
// We have to store the LowLevelKeyboardProc, so that it is not garbage collected runtime
|
||||
hookedLowLevelKeyboardProc = LowLevelKeyboardProc;
|
||||
// Set the hook
|
||||
hookId = InterceptKeys.SetHook(hookedLowLevelKeyboardProc);
|
||||
}
|
||||
|
||||
public SpecialKeyState CheckModifiers()
|
||||
{
|
||||
SpecialKeyState state = new SpecialKeyState();
|
||||
if ((InterceptKeys.GetKeyState(VK_SHIFT) & 0x8000) != 0)
|
||||
{
|
||||
//SHIFT is pressed
|
||||
state.ShiftPressed = true;
|
||||
}
|
||||
if ((InterceptKeys.GetKeyState(VK_CONTROL) & 0x8000) != 0)
|
||||
{
|
||||
//CONTROL is pressed
|
||||
state.CtrlPressed = true;
|
||||
}
|
||||
if ((InterceptKeys.GetKeyState(VK_ALT) & 0x8000) != 0)
|
||||
{
|
||||
//ALT is pressed
|
||||
state.AltPressed = true;
|
||||
}
|
||||
if ((InterceptKeys.GetKeyState(VK_WIN) & 0x8000) != 0)
|
||||
{
|
||||
//ALT is pressed
|
||||
state.WinPressed = true;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
bool continues = true;
|
||||
|
||||
if (nCode >= 0)
|
||||
{
|
||||
if (wParam.ToUInt32() == (int)KeyEvent.WM_KEYDOWN ||
|
||||
wParam.ToUInt32() == (int)KeyEvent.WM_KEYUP ||
|
||||
wParam.ToUInt32() == (int)KeyEvent.WM_SYSKEYDOWN ||
|
||||
wParam.ToUInt32() == (int)KeyEvent.WM_SYSKEYUP)
|
||||
{
|
||||
if (hookedKeyboardCallback != null)
|
||||
continues = hookedKeyboardCallback((KeyEvent)wParam.ToUInt32(), Marshal.ReadInt32(lParam), CheckModifiers());
|
||||
}
|
||||
}
|
||||
|
||||
if (continues)
|
||||
{
|
||||
return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam);
|
||||
}
|
||||
return (IntPtr)1;
|
||||
}
|
||||
|
||||
~GlobalHotkey()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
InterceptKeys.UnhookWindowsHookEx(hookId);
|
||||
}
|
||||
}
|
||||
}
|
||||
124
Wox.Infrastructure/Hotkey/HotkeyModel.cs
Normal file
124
Wox.Infrastructure/Hotkey/HotkeyModel.cs
Normal file
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Wox.Infrastructure.Hotkey
|
||||
{
|
||||
public class HotkeyModel
|
||||
{
|
||||
public bool Alt { get; set; }
|
||||
public bool Shift { get; set; }
|
||||
public bool Win { get; set; }
|
||||
public bool Ctrl { get; set; }
|
||||
public Key CharKey { get; set; }
|
||||
|
||||
public ModifierKeys ModifierKeys
|
||||
{
|
||||
get
|
||||
{
|
||||
ModifierKeys modifierKeys = ModifierKeys.None;
|
||||
if (Alt)
|
||||
{
|
||||
modifierKeys = ModifierKeys.Alt;
|
||||
}
|
||||
if (Shift)
|
||||
{
|
||||
modifierKeys = modifierKeys | ModifierKeys.Shift;
|
||||
}
|
||||
if (Win)
|
||||
{
|
||||
modifierKeys = modifierKeys | ModifierKeys.Windows;
|
||||
}
|
||||
if (Ctrl)
|
||||
{
|
||||
modifierKeys = modifierKeys | ModifierKeys.Control;
|
||||
}
|
||||
return modifierKeys;
|
||||
}
|
||||
}
|
||||
|
||||
public HotkeyModel() { }
|
||||
|
||||
public HotkeyModel(string hotkeyString)
|
||||
{
|
||||
ParseHotkey(hotkeyString);
|
||||
}
|
||||
|
||||
public HotkeyModel(bool alt, bool shift, bool win, bool ctrl, Key key)
|
||||
{
|
||||
Alt = alt;
|
||||
Shift = shift;
|
||||
Win = win;
|
||||
Ctrl = ctrl;
|
||||
CharKey = key;
|
||||
}
|
||||
|
||||
private void ParseHotkey(string hotkeyString)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hotkeyString))
|
||||
{
|
||||
List<string> keys = hotkeyString.Replace(" ", "").Split('+').ToList();
|
||||
if (keys.Contains("Alt"))
|
||||
{
|
||||
Alt = true;
|
||||
keys.Remove("Alt");
|
||||
}
|
||||
if (keys.Contains("Shift"))
|
||||
{
|
||||
Shift = true;
|
||||
keys.Remove("Shift");
|
||||
}
|
||||
if (keys.Contains("Win"))
|
||||
{
|
||||
Win = true;
|
||||
keys.Remove("Win");
|
||||
}
|
||||
if (keys.Contains("Ctrl"))
|
||||
{
|
||||
Ctrl = true;
|
||||
keys.Remove("Ctrl");
|
||||
}
|
||||
if (keys.Count > 0)
|
||||
{
|
||||
string charKey = keys[0];
|
||||
try
|
||||
{
|
||||
CharKey = (Key)Enum.Parse(typeof(Key), charKey);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string text = string.Empty;
|
||||
if (Ctrl)
|
||||
{
|
||||
text += "Ctrl";
|
||||
}
|
||||
if (Alt)
|
||||
{
|
||||
text += string.IsNullOrEmpty(text) ? "Alt" : " + Alt";
|
||||
}
|
||||
if (Shift)
|
||||
{
|
||||
text += string.IsNullOrEmpty(text) ? "Shift" : " + Shift";
|
||||
}
|
||||
if (Win)
|
||||
{
|
||||
text += string.IsNullOrEmpty(text) ? "Win" : " + Win";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(CharKey.ToString()))
|
||||
{
|
||||
text += string.IsNullOrEmpty(text) ? CharKey.ToString() : " + " + CharKey;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user