3074/Windows/Control/HotkeyManager.cs

100 lines
2.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Interop;
namespace tsf_3074
{
public partial class HotkeyManager
{
private readonly System.Windows.Window _window;
public HotkeyManager(System.Windows.Window window)
{
_window = window;
}
private HwndSource _source;
private readonly Dictionary<int, OnEvent> _listener = new Dictionary<int, OnEvent>();
private const int HotkeyIdStart = 9000;
private int _hotkeyId = HotkeyIdStart;
/**
* Register a hotkey with given modifiers and virtual keys.
* When the keybinding is pressed, the onEvent is invoked.
*/
public void RegisterHotkey(uint fsModifiers, uint vk, OnEvent onEvent)
{
var thisId = _hotkeyId++;
RegisterHotKey(new WindowInteropHelper(_window).Handle, thisId, fsModifiers, vk);
_listener[thisId] = onEvent;
}
public void UnregisterAllHotkeys()
{
var helper = new WindowInteropHelper(_window);
while (_hotkeyId >= HotkeyIdStart)
{
UnregisterHotKey(helper.Handle, _hotkeyId--);
}
}
/**
* Add the hook to the Overlay window
*/
public void OnSourceInitialized()
{
_source = HwndSource.FromHwnd(new WindowInteropHelper(_window).Handle) ?? throw new Exception();
_source.AddHook(HwndHook);
}
/**
* Remove the hook from Overlay window
*/
public void OnClosed()
{
_source.RemoveHook(HwndHook);
_source = null;
UnregisterAllHotkeys();
}
/**
* The callback for keybinding being pressed.
* Don't change this function, use registerHotkey!
*/
private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg != 0x0312) return IntPtr.Zero;
var hotkeyId = wParam.ToInt32();
if (OnHotKeyPressed(hotkeyId))
{
handled = true;
}
return IntPtr.Zero;
}
private bool OnHotKeyPressed(int hotkeyId)
{
var listener = _listener[hotkeyId];
if (listener == null) return false;
listener.Invoke();
return true;
}
[DllImport("User32.dll")]
private static extern bool RegisterHotKey(
[In] IntPtr hWnd,
[In] int id,
[In] uint fsModifiers,
[In] uint vk);
[DllImport("User32.dll")]
private static extern bool UnregisterHotKey(
[In] IntPtr hWnd,
[In] int id);
}
}