ShortcutsHelper/Services/KeyCaptureService.cs

130 lines
4.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Gma.System.MouseKeyHook;
namespace ShortcutsHelper.Services
{
public class KeyCaptureService : IDisposable
{
private IKeyboardMouseEvents? _globalHook;
private bool _isCapturing = false;
private List<string> _capturedKeys = new();
public event EventHandler<string>? KeyCaptured;
public event EventHandler? CaptureCancelled;
public bool IsCapturing => _isCapturing;
public void StartCapturing()
{
if (_isCapturing) return;
_isCapturing = true;
_capturedKeys.Clear();
_globalHook = Hook.GlobalEvents();
_globalHook.KeyDown += OnKeyDown;
_globalHook.KeyUp += OnKeyUp;
}
public void StopCapturing()
{
_isCapturing = false;
if (_globalHook != null)
{
_globalHook.KeyDown -= OnKeyDown;
_globalHook.KeyUp -= OnKeyUp;
_globalHook.Dispose();
_globalHook = null;
}
}
private void OnKeyDown(object? sender, KeyEventArgs e)
{
if (!_isCapturing) return;
if (e.KeyCode == Keys.Escape)
{
StopCapturing();
CaptureCancelled?.Invoke(this, EventArgs.Empty);
return;
}
var keyString = BuildKeyString(e);
if (!string.IsNullOrEmpty(keyString))
{
_capturedKeys.Clear();
_capturedKeys.Add(keyString);
}
}
private void OnKeyUp(object? sender, KeyEventArgs e)
{
if (!_isCapturing || _capturedKeys.Count == 0) return;
StopCapturing();
KeyCaptured?.Invoke(this, _capturedKeys.First().Replace(" ", ""));
}
private string BuildKeyString(KeyEventArgs e)
{
var parts = new List<string>();
if ((Control.ModifierKeys & Keys.Control) != 0) parts.Add("Ctrl");
if ((Control.ModifierKeys & Keys.Alt) != 0) parts.Add("Alt");
if ((Control.ModifierKeys & Keys.Shift) != 0) parts.Add("Shift");
if ((Control.ModifierKeys & Keys.LWin) != 0 || (Control.ModifierKeys & Keys.RWin) != 0) parts.Add("Win");
if (e.KeyCode != Keys.ControlKey && e.KeyCode != Keys.LControlKey && e.KeyCode != Keys.RControlKey &&
e.KeyCode != Keys.Menu && e.KeyCode != Keys.LMenu && e.KeyCode != Keys.RMenu &&
e.KeyCode != Keys.ShiftKey && e.KeyCode != Keys.LShiftKey && e.KeyCode != Keys.RShiftKey &&
e.KeyCode != Keys.LWin && e.KeyCode != Keys.RWin)
{
parts.Add(GetKeyName(e.KeyCode));
}
return string.Join("+", parts);
}
private string GetKeyName(Keys key)
{
return key switch
{
Keys.Space => "Space",
Keys.Enter => "Enter",
Keys.Tab => "Tab",
Keys.Back => "Backspace",
Keys.Delete => "Delete",
Keys.Insert => "Insert",
Keys.Home => "Home",
Keys.End => "End",
Keys.PageUp => "PageUp",
Keys.PageDown => "PageDown",
Keys.Up => "↑",
Keys.Down => "↓",
Keys.Left => "←",
Keys.Right => "→",
Keys.F1 => "F1",
Keys.F2 => "F2",
Keys.F3 => "F3",
Keys.F4 => "F4",
Keys.F5 => "F5",
Keys.F6 => "F6",
Keys.F7 => "F7",
Keys.F8 => "F8",
Keys.F9 => "F9",
Keys.F10 => "F10",
Keys.F11 => "F11",
Keys.F12 => "F12",
_ => key.ToString()
};
}
public void Dispose()
{
StopCapturing();
}
}
}