Initial TaskbarLauncher release baseline
This commit is contained in:
116
Services/HotkeyService.cs
Normal file
116
Services/HotkeyService.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace TaskbarLauncher.Services;
|
||||
|
||||
public sealed class HotkeyService : IDisposable
|
||||
{
|
||||
private const int WmHotkey = 0x0312;
|
||||
private const int HotkeyId = 9001;
|
||||
|
||||
private HwndSource? source;
|
||||
private Window? window;
|
||||
|
||||
public event EventHandler? Pressed;
|
||||
|
||||
public void Register(string hotkey)
|
||||
{
|
||||
Unregister();
|
||||
|
||||
window = new Window
|
||||
{
|
||||
Width = 0,
|
||||
Height = 0,
|
||||
ShowInTaskbar = false,
|
||||
WindowStyle = WindowStyle.None,
|
||||
AllowsTransparency = true,
|
||||
Opacity = 0,
|
||||
Left = -10000,
|
||||
Top = -10000
|
||||
};
|
||||
|
||||
window.SourceInitialized += (_, _) =>
|
||||
{
|
||||
var helper = new WindowInteropHelper(window);
|
||||
source = HwndSource.FromHwnd(helper.Handle);
|
||||
source?.AddHook(WndProc);
|
||||
|
||||
ParseHotkey(hotkey, out uint modifiers, out uint key);
|
||||
RegisterHotKey(helper.Handle, HotkeyId, modifiers, key);
|
||||
};
|
||||
|
||||
window.Show();
|
||||
window.Hide();
|
||||
}
|
||||
|
||||
public void Unregister()
|
||||
{
|
||||
if (window is not null)
|
||||
{
|
||||
var helper = new WindowInteropHelper(window);
|
||||
if (helper.Handle != IntPtr.Zero)
|
||||
{
|
||||
UnregisterHotKey(helper.Handle, HotkeyId);
|
||||
}
|
||||
}
|
||||
|
||||
source?.RemoveHook(WndProc);
|
||||
source = null;
|
||||
window?.Close();
|
||||
window = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Unregister();
|
||||
}
|
||||
|
||||
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
if (msg == WmHotkey && wParam.ToInt32() == HotkeyId)
|
||||
{
|
||||
Pressed?.Invoke(this, EventArgs.Empty);
|
||||
handled = true;
|
||||
}
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
private static void ParseHotkey(string hotkey, out uint modifiers, out uint key)
|
||||
{
|
||||
modifiers = 0;
|
||||
key = (uint)KeyInterop.VirtualKeyFromKey(Key.Space);
|
||||
|
||||
foreach (string part in hotkey.Split('+', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (part.Equals("Ctrl", StringComparison.OrdinalIgnoreCase) || part.Equals("Control", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
modifiers |= 0x0002;
|
||||
}
|
||||
else if (part.Equals("Alt", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
modifiers |= 0x0001;
|
||||
}
|
||||
else if (part.Equals("Shift", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
modifiers |= 0x0004;
|
||||
}
|
||||
else if (part.Equals("Win", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
modifiers |= 0x0008;
|
||||
}
|
||||
else if (Enum.TryParse(part, true, out Key parsedKey))
|
||||
{
|
||||
key = (uint)KeyInterop.VirtualKeyFromKey(parsedKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
|
||||
}
|
||||
Reference in New Issue
Block a user