diff --git a/ClipForge/GlobalHotkeyService.cs b/ClipForge/GlobalHotkeyService.cs
index d786b51..551cb5e 100644
--- a/ClipForge/GlobalHotkeyService.cs
+++ b/ClipForge/GlobalHotkeyService.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Runtime.InteropServices;
using Microsoft.UI.Xaml;
@@ -6,39 +6,49 @@ namespace ClipForge
{
public class GlobalHotkeyService
{
- // These two lines talk directly to Windows to register/unregister hotkeys
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
- // This is the ID we'll use to identify our clip hotkey
private const int HOTKEY_CLIP = 1;
+ private const uint MOD_NOREPEAT = 0x4000; // don't fire on key repeat
- // Alt key modifier
- private const uint MOD_ALT = 0x0001;
-
- // F9 key
- private const uint VK_F9 = 0x78;
-
- // This is the "event" that fires when the hotkey is pressed
public event Action? ClipRequested;
private IntPtr _hwnd;
+ private uint _modifiers;
+ private uint _vk;
- public void Initialize(IntPtr hwnd)
+ /// Register the clip hotkey. Use settings values (e.g. HotkeyModifiers, HotkeyVirtualKey).
+ public void Initialize(IntPtr hwnd, uint modifiers, uint vk)
{
_hwnd = hwnd;
- RegisterHotKey(_hwnd, HOTKEY_CLIP, MOD_ALT, VK_F9);
+ _modifiers = modifiers;
+ _vk = vk;
+ TryRegister();
+ }
+
+ /// Update the hotkey at runtime (e.g. after user remaps). Unregisters old and registers new.
+ public bool UpdateHotkey(uint modifiers, uint vk)
+ {
+ UnregisterHotKey(_hwnd, HOTKEY_CLIP);
+ _modifiers = modifiers;
+ _vk = vk;
+ return TryRegister();
+ }
+
+ private bool TryRegister()
+ {
+ uint mod = _modifiers | MOD_NOREPEAT;
+ return RegisterHotKey(_hwnd, HOTKEY_CLIP, mod, _vk);
}
public void ProcessHotkey(int id)
{
if (id == HOTKEY_CLIP)
- {
ClipRequested?.Invoke();
- }
}
public void Cleanup()
diff --git a/ClipForge/HotkeyHelper.cs b/ClipForge/HotkeyHelper.cs
new file mode 100644
index 0000000..f1f50fa
--- /dev/null
+++ b/ClipForge/HotkeyHelper.cs
@@ -0,0 +1,175 @@
+using System;
+using System.Collections.Generic;
+using Windows.System;
+
+namespace ClipForge
+{
+ /// Converts between hotkey modifier/vk and display strings.
+ public static class HotkeyHelper
+ {
+ public const uint MOD_ALT = 0x0001;
+ public const uint MOD_CONTROL = 0x0002;
+ public const uint MOD_SHIFT = 0x0004;
+ public const uint MOD_WIN = 0x0008;
+ public const uint MOD_NOREPEAT = 0x4000;
+
+ private static readonly Dictionary KeyNames = new()
+ {
+ { VirtualKey.LeftButton, "LMB" },
+ { VirtualKey.RightButton, "RMB" },
+ { VirtualKey.Cancel, "Cancel" },
+ { VirtualKey.Back, "Backspace" },
+ { VirtualKey.Tab, "Tab" },
+ { VirtualKey.Clear, "Clear" },
+ { VirtualKey.Enter, "Enter" },
+ { VirtualKey.Shift, "Shift" },
+ { VirtualKey.Control, "Ctrl" },
+ { VirtualKey.Menu, "Alt" },
+ { VirtualKey.Pause, "Pause" },
+ { VirtualKey.CapitalLock, "Caps Lock" },
+ { VirtualKey.Kana, "Kana" },
+ { VirtualKey.Hangul, "Hangul" },
+ { VirtualKey.Junja, "Junja" },
+ { VirtualKey.Final, "Final" },
+ { VirtualKey.Hanja, "Hanja" },
+ { VirtualKey.Kanji, "Kanji" },
+ { VirtualKey.Escape, "Escape" },
+ { VirtualKey.Convert, "Convert" },
+ { VirtualKey.NonConvert, "NonConvert" },
+ { VirtualKey.Accept, "Accept" },
+ { VirtualKey.ModeChange, "ModeChange" },
+ { VirtualKey.Space, "Space" },
+ { VirtualKey.PageUp, "PgUp" },
+ { VirtualKey.PageDown, "PgDn" },
+ { VirtualKey.End, "End" },
+ { VirtualKey.Home, "Home" },
+ { VirtualKey.Left, "Left" },
+ { VirtualKey.Up, "Up" },
+ { VirtualKey.Right, "Right" },
+ { VirtualKey.Down, "Down" },
+ { VirtualKey.Select, "Select" },
+ { VirtualKey.Print, "Print" },
+ { VirtualKey.Execute, "Execute" },
+ { VirtualKey.Snapshot, "Print Screen" },
+ { VirtualKey.Insert, "Insert" },
+ { VirtualKey.Delete, "Delete" },
+ { VirtualKey.Help, "Help" },
+ { VirtualKey.Number0, "0" },
+ { VirtualKey.Number1, "1" },
+ { VirtualKey.Number2, "2" },
+ { VirtualKey.Number3, "3" },
+ { VirtualKey.Number4, "4" },
+ { VirtualKey.Number5, "5" },
+ { VirtualKey.Number6, "6" },
+ { VirtualKey.Number7, "7" },
+ { VirtualKey.Number8, "8" },
+ { VirtualKey.Number9, "9" },
+ { VirtualKey.A, "A" },
+ { VirtualKey.B, "B" },
+ { VirtualKey.C, "C" },
+ { VirtualKey.D, "D" },
+ { VirtualKey.E, "E" },
+ { VirtualKey.F, "F" },
+ { VirtualKey.G, "G" },
+ { VirtualKey.H, "H" },
+ { VirtualKey.I, "I" },
+ { VirtualKey.J, "J" },
+ { VirtualKey.K, "K" },
+ { VirtualKey.L, "L" },
+ { VirtualKey.M, "M" },
+ { VirtualKey.N, "N" },
+ { VirtualKey.O, "O" },
+ { VirtualKey.P, "P" },
+ { VirtualKey.Q, "Q" },
+ { VirtualKey.R, "R" },
+ { VirtualKey.S, "S" },
+ { VirtualKey.T, "T" },
+ { VirtualKey.U, "U" },
+ { VirtualKey.V, "V" },
+ { VirtualKey.W, "W" },
+ { VirtualKey.X, "X" },
+ { VirtualKey.Y, "Y" },
+ { VirtualKey.Z, "Z" },
+ { VirtualKey.LeftWindows, "Win" },
+ { VirtualKey.RightWindows, "Win" },
+ { VirtualKey.Application, "App" },
+ { VirtualKey.Sleep, "Sleep" },
+ { VirtualKey.NumberPad0, "Num 0" },
+ { VirtualKey.NumberPad1, "Num 1" },
+ { VirtualKey.NumberPad2, "Num 2" },
+ { VirtualKey.NumberPad3, "Num 3" },
+ { VirtualKey.NumberPad4, "Num 4" },
+ { VirtualKey.NumberPad5, "Num 5" },
+ { VirtualKey.NumberPad6, "Num 6" },
+ { VirtualKey.NumberPad7, "Num 7" },
+ { VirtualKey.NumberPad8, "Num 8" },
+ { VirtualKey.NumberPad9, "Num 9" },
+ { VirtualKey.Multiply, "Num *" },
+ { VirtualKey.Add, "Num +" },
+ { VirtualKey.Separator, "Num ," },
+ { VirtualKey.Subtract, "Num -" },
+ { VirtualKey.Decimal, "Num ." },
+ { VirtualKey.Divide, "Num /" },
+ { VirtualKey.F1, "F1" },
+ { VirtualKey.F2, "F2" },
+ { VirtualKey.F3, "F3" },
+ { VirtualKey.F4, "F4" },
+ { VirtualKey.F5, "F5" },
+ { VirtualKey.F6, "F6" },
+ { VirtualKey.F7, "F7" },
+ { VirtualKey.F8, "F8" },
+ { VirtualKey.F9, "F9" },
+ { VirtualKey.F10, "F10" },
+ { VirtualKey.F11, "F11" },
+ { VirtualKey.F12, "F12" },
+ { VirtualKey.F13, "F13" },
+ { VirtualKey.F14, "F14" },
+ { VirtualKey.F15, "F15" },
+ { VirtualKey.F16, "F16" },
+ { VirtualKey.F17, "F17" },
+ { VirtualKey.F18, "F18" },
+ { VirtualKey.F19, "F19" },
+ { VirtualKey.F20, "F20" },
+ { VirtualKey.F21, "F21" },
+ { VirtualKey.F22, "F22" },
+ { VirtualKey.F23, "F23" },
+ { VirtualKey.F24, "F24" },
+ { VirtualKey.NumberKeyLock, "NumLock" },
+ { VirtualKey.Scroll, "Scroll Lock" },
+ { VirtualKey.LeftShift, "Shift" },
+ { VirtualKey.RightShift, "Shift" },
+ { VirtualKey.LeftControl, "Ctrl" },
+ { VirtualKey.RightControl, "Ctrl" },
+ { VirtualKey.LeftMenu, "Alt" },
+ { VirtualKey.RightMenu, "Alt" },
+ };
+
+ /// Format modifier flags + virtual key as display string (e.g. "Alt + PgUp").
+ public static string ToDisplayString(uint modifiers, uint vk)
+ {
+ var parts = new List();
+ if ((modifiers & MOD_WIN) != 0) parts.Add("Win");
+ if ((modifiers & MOD_CONTROL) != 0) parts.Add("Ctrl");
+ if ((modifiers & MOD_ALT) != 0) parts.Add("Alt");
+ if ((modifiers & MOD_SHIFT) != 0) parts.Add("Shift");
+ var keyName = GetKeyName((VirtualKey)vk);
+ if (!string.IsNullOrEmpty(keyName))
+ parts.Add(keyName);
+ return parts.Count > 0 ? string.Join(" + ", parts) : "None";
+ }
+
+ public static string GetKeyName(VirtualKey key)
+ {
+ return KeyNames.TryGetValue(key, out var name) ? name : key.ToString();
+ }
+
+ /// True if the key is typically used only as a modifier (don't use as sole key).
+ public static bool IsModifierKey(VirtualKey key)
+ {
+ return key == VirtualKey.LeftWindows || key == VirtualKey.RightWindows
+ || key == VirtualKey.Control || key == VirtualKey.LeftControl || key == VirtualKey.RightControl
+ || key == VirtualKey.Menu || key == VirtualKey.LeftMenu || key == VirtualKey.RightMenu
+ || key == VirtualKey.Shift || key == VirtualKey.LeftShift || key == VirtualKey.RightShift;
+ }
+ }
+}
diff --git a/ClipForge/SettingsService.cs b/ClipForge/SettingsService.cs
index 929eb3c..080aeea 100644
--- a/ClipForge/SettingsService.cs
+++ b/ClipForge/SettingsService.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IO;
using System.Text.Json;
@@ -9,7 +9,10 @@ namespace ClipForge
public int ClipLengthSeconds { get; set; } = 30;
public int VideoQuality { get; set; } = 70;
public int Framerate { get; set; } = 60;
- public string HotkeyDisplay { get; set; } = "Alt + F9";
+ /// Windows modifier flags: Alt=1, Ctrl=2, Shift=4, Win=8.
+ public int HotkeyModifiers { get; set; } = 1; // MOD_ALT
+ /// Windows virtual key code (e.g. VK_F9=0x78, VK_PRIOR=0x21 for PgUp).
+ public int HotkeyVirtualKey { get; set; } = 0x78; // VK_F9
}
public class SettingsService