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; // Built in static ctor with TryAdd so duplicate VirtualKey enum values (e.g. Kana/Hangul = 0x15) don't throw. private static readonly Dictionary KeyNames = new(); static HotkeyHelper() { TryAdd(VirtualKey.LeftButton, "LMB"); TryAdd(VirtualKey.RightButton, "RMB"); TryAdd(VirtualKey.Cancel, "Cancel"); TryAdd(VirtualKey.Back, "Backspace"); TryAdd(VirtualKey.Tab, "Tab"); TryAdd(VirtualKey.Clear, "Clear"); TryAdd(VirtualKey.Enter, "Enter"); TryAdd(VirtualKey.Shift, "Shift"); TryAdd(VirtualKey.Control, "Ctrl"); TryAdd(VirtualKey.Menu, "Alt"); TryAdd(VirtualKey.Pause, "Pause"); TryAdd(VirtualKey.CapitalLock, "Caps Lock"); TryAdd(VirtualKey.Kana, "Kana"); TryAdd(VirtualKey.Hangul, "Hangul"); // same value as Kana on some SDKs; TryAdd skips duplicate TryAdd(VirtualKey.Junja, "Junja"); TryAdd(VirtualKey.Final, "Final"); TryAdd(VirtualKey.Hanja, "Hanja"); TryAdd(VirtualKey.Kanji, "Kanji"); TryAdd(VirtualKey.Escape, "Escape"); TryAdd(VirtualKey.Convert, "Convert"); TryAdd(VirtualKey.NonConvert, "NonConvert"); TryAdd(VirtualKey.Accept, "Accept"); TryAdd(VirtualKey.ModeChange, "ModeChange"); TryAdd(VirtualKey.Space, "Space"); TryAdd(VirtualKey.PageUp, "PgUp"); TryAdd(VirtualKey.PageDown, "PgDn"); TryAdd(VirtualKey.End, "End"); TryAdd(VirtualKey.Home, "Home"); TryAdd(VirtualKey.Left, "Left"); TryAdd(VirtualKey.Up, "Up"); TryAdd(VirtualKey.Right, "Right"); TryAdd(VirtualKey.Down, "Down"); TryAdd(VirtualKey.Select, "Select"); TryAdd(VirtualKey.Print, "Print"); TryAdd(VirtualKey.Execute, "Execute"); TryAdd(VirtualKey.Snapshot, "Print Screen"); TryAdd(VirtualKey.Insert, "Insert"); TryAdd(VirtualKey.Delete, "Delete"); TryAdd(VirtualKey.Help, "Help"); TryAdd(VirtualKey.Number0, "0"); TryAdd(VirtualKey.Number1, "1"); TryAdd(VirtualKey.Number2, "2"); TryAdd(VirtualKey.Number3, "3"); TryAdd(VirtualKey.Number4, "4"); TryAdd(VirtualKey.Number5, "5"); TryAdd(VirtualKey.Number6, "6"); TryAdd(VirtualKey.Number7, "7"); TryAdd(VirtualKey.Number8, "8"); TryAdd(VirtualKey.Number9, "9"); TryAdd(VirtualKey.A, "A"); TryAdd(VirtualKey.B, "B"); TryAdd(VirtualKey.C, "C"); TryAdd(VirtualKey.D, "D"); TryAdd(VirtualKey.E, "E"); TryAdd(VirtualKey.F, "F"); TryAdd(VirtualKey.G, "G"); TryAdd(VirtualKey.H, "H"); TryAdd(VirtualKey.I, "I"); TryAdd(VirtualKey.J, "J"); TryAdd(VirtualKey.K, "K"); TryAdd(VirtualKey.L, "L"); TryAdd(VirtualKey.M, "M"); TryAdd(VirtualKey.N, "N"); TryAdd(VirtualKey.O, "O"); TryAdd(VirtualKey.P, "P"); TryAdd(VirtualKey.Q, "Q"); TryAdd(VirtualKey.R, "R"); TryAdd(VirtualKey.S, "S"); TryAdd(VirtualKey.T, "T"); TryAdd(VirtualKey.U, "U"); TryAdd(VirtualKey.V, "V"); TryAdd(VirtualKey.W, "W"); TryAdd(VirtualKey.X, "X"); TryAdd(VirtualKey.Y, "Y"); TryAdd(VirtualKey.Z, "Z"); TryAdd(VirtualKey.LeftWindows, "Win"); TryAdd(VirtualKey.RightWindows, "Win"); TryAdd(VirtualKey.Application, "App"); TryAdd(VirtualKey.Sleep, "Sleep"); TryAdd(VirtualKey.NumberPad0, "Num 0"); TryAdd(VirtualKey.NumberPad1, "Num 1"); TryAdd(VirtualKey.NumberPad2, "Num 2"); TryAdd(VirtualKey.NumberPad3, "Num 3"); TryAdd(VirtualKey.NumberPad4, "Num 4"); TryAdd(VirtualKey.NumberPad5, "Num 5"); TryAdd(VirtualKey.NumberPad6, "Num 6"); TryAdd(VirtualKey.NumberPad7, "Num 7"); TryAdd(VirtualKey.NumberPad8, "Num 8"); TryAdd(VirtualKey.NumberPad9, "Num 9"); TryAdd(VirtualKey.Multiply, "Num *"); TryAdd(VirtualKey.Add, "Num +"); TryAdd(VirtualKey.Separator, "Num ,"); TryAdd(VirtualKey.Subtract, "Num -"); TryAdd(VirtualKey.Decimal, "Num ."); TryAdd(VirtualKey.Divide, "Num /"); TryAdd(VirtualKey.F1, "F1"); TryAdd(VirtualKey.F2, "F2"); TryAdd(VirtualKey.F3, "F3"); TryAdd(VirtualKey.F4, "F4"); TryAdd(VirtualKey.F5, "F5"); TryAdd(VirtualKey.F6, "F6"); TryAdd(VirtualKey.F7, "F7"); TryAdd(VirtualKey.F8, "F8"); TryAdd(VirtualKey.F9, "F9"); TryAdd(VirtualKey.F10, "F10"); TryAdd(VirtualKey.F11, "F11"); TryAdd(VirtualKey.F12, "F12"); TryAdd(VirtualKey.F13, "F13"); TryAdd(VirtualKey.F14, "F14"); TryAdd(VirtualKey.F15, "F15"); TryAdd(VirtualKey.F16, "F16"); TryAdd(VirtualKey.F17, "F17"); TryAdd(VirtualKey.F18, "F18"); TryAdd(VirtualKey.F19, "F19"); TryAdd(VirtualKey.F20, "F20"); TryAdd(VirtualKey.F21, "F21"); TryAdd(VirtualKey.F22, "F22"); TryAdd(VirtualKey.F23, "F23"); TryAdd(VirtualKey.F24, "F24"); TryAdd(VirtualKey.NumberKeyLock, "NumLock"); TryAdd(VirtualKey.Scroll, "Scroll Lock"); TryAdd(VirtualKey.LeftShift, "Shift"); TryAdd(VirtualKey.RightShift, "Shift"); TryAdd(VirtualKey.LeftControl, "Ctrl"); TryAdd(VirtualKey.RightControl, "Ctrl"); TryAdd(VirtualKey.LeftMenu, "Alt"); TryAdd(VirtualKey.RightMenu, "Alt"); } private static void TryAdd(VirtualKey key, string name) { KeyNames.TryAdd(key, name); } /// 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; } } }