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 _capturedKeys = new(); public event EventHandler? 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(); 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(); } } }