Fix GetKeyName to support WPF's Key as base type.

This commit is contained in:
Peter Kirmeier 2023-05-26 20:51:42 +02:00
parent 1c22c86d3e
commit 60329d524f
2 changed files with 40 additions and 35 deletions

View file

@ -176,19 +176,21 @@ namespace SystemTrayMenu.Helpers
return hotkeyString.ToString() + GetKeyName(key); return hotkeyString.ToString() + GetKeyName(key);
} }
private static string GetKeyName(Key givenKey) private static string GetKeyName(Key key)
{ {
StringBuilder keyName = new(); const uint MAPVK_VK_TO_VSC = 0;
const uint numpad = 55; const uint KF_EXTENDED = 0x100;
const uint SCANCODE_SIMULATED = 0x200;
const uint scanCodeNumPad = 0x37;
const uint scanCodePause = 0x45;
Key virtualKey = givenKey; StringBuilder keyName = new(100);
string keyString = string.Empty; string keyString = string.Empty;
// Make VC's to real keys switch (key)
switch (virtualKey)
{ {
case Key.Multiply: case Key.Multiply:
if (NativeMethods.User32GetKeyNameText(numpad << 16, keyName, 100) > 0) if (NativeMethods.User32GetKeyNameText(scanCodeNumPad << 16, keyName, keyName.Capacity) > 0)
{ {
keyString = keyName.ToString().Replace("*", string.Empty, StringComparison.InvariantCulture).Trim().ToLowerInvariant(); keyString = keyName.ToString().Replace("*", string.Empty, StringComparison.InvariantCulture).Trim().ToLowerInvariant();
if (keyString.Contains('(')) if (keyString.Contains('('))
@ -201,7 +203,7 @@ namespace SystemTrayMenu.Helpers
return keyString + " *"; return keyString + " *";
case Key.Divide: case Key.Divide:
if (NativeMethods.User32GetKeyNameText(numpad << 16, keyName, 100) > 0) if (NativeMethods.User32GetKeyNameText(scanCodeNumPad << 16, keyName, keyName.Capacity) > 0)
{ {
keyString = keyName.ToString().Replace("*", string.Empty, StringComparison.InvariantCulture).Trim().ToLowerInvariant(); keyString = keyName.ToString().Replace("*", string.Empty, StringComparison.InvariantCulture).Trim().ToLowerInvariant();
if (keyString.Contains('(')) if (keyString.Contains('('))
@ -215,11 +217,15 @@ namespace SystemTrayMenu.Helpers
return keyString + " /"; return keyString + " /";
} }
const uint MAPVK_VK_TO_VSC = 0; // Converting Windows Input Key Enums into Virtual-Key Codes into Scan Codes into Text
uint scanCode = NativeMethods.User32MapVirtualKey((uint)virtualKey, MAPVK_VK_TO_VSC); // - Windows Input Key Enums: https://learn.microsoft.com/en-us/dotnet/api/system.windows.input.key?view=windowsdesktop-7.0
// - Virtual-Key Codes: https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
// - Scan Codes: https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#scan-codes
uint virtualKeyCode = (uint)KeyInterop.VirtualKeyFromKey(key);
uint scanCode = NativeMethods.User32MapVirtualKey(virtualKeyCode, MAPVK_VK_TO_VSC);
// because MapVirtualKey strips the extended bit for some keys // Handle names of some special keys
switch (virtualKey) switch (key)
{ {
case Key.Left: case Key.Left:
case Key.Up: case Key.Up:
@ -232,18 +238,18 @@ namespace SystemTrayMenu.Helpers
case Key.Insert: case Key.Insert:
case Key.Delete: case Key.Delete:
case Key.NumLock: case Key.NumLock:
scanCode |= 0x100; // set extended bit scanCode |= KF_EXTENDED; // set extended bit (simulate origin from enhanced 101/102-key keyboard)
break; break;
case Key.PrintScreen: // PrintScreen case Key.PrintScreen:
scanCode = 311; scanCode = KF_EXTENDED | scanCodeNumPad;
break; break;
case Key.Pause: // PrintScreen case Key.Pause:
scanCode = 69; scanCode = scanCodePause;
break; break;
} }
scanCode |= 0x200; scanCode |= SCANCODE_SIMULATED;
if (NativeMethods.User32GetKeyNameText(scanCode << 16, keyName, 100) != 0) if (NativeMethods.User32GetKeyNameText(scanCode << 16, keyName, keyName.Capacity) != 0)
{ {
string visibleName = keyName.ToString(); string visibleName = keyName.ToString();
if (visibleName.Length > 1) if (visibleName.Length > 1)
@ -255,7 +261,7 @@ namespace SystemTrayMenu.Helpers
} }
else else
{ {
return givenKey.ToString(); return key.ToString();
} }
} }
} }

View file

@ -137,6 +137,19 @@ namespace SystemTrayMenu.UserInterface
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
public override string ToString() => HotkeyToString(modifiers, hotkey);
/// <summary>
/// Used to get/set the hotkey (e.g. Key.A).
/// </summary>
/// <param name="hotkey">hotkey.</param>
public void SetHotkey(string hotkey)
{
this.hotkey = GlobalHotkeys.KeyFromString(hotkey);
modifiers = GlobalHotkeys.ModifierKeysFromString(hotkey);
Redraw(true);
}
/// <summary> /// <summary>
/// Register a hotkey. /// Register a hotkey.
/// </summary> /// </summary>
@ -151,7 +164,6 @@ namespace SystemTrayMenu.UserInterface
return 0; return 0;
} }
try try
{ {
hook.RegisterHotKey(modifiers, key); hook.RegisterHotKey(modifiers, key);
@ -185,26 +197,13 @@ namespace SystemTrayMenu.UserInterface
/// <summary> /// <summary>
/// Clears the current hotkey and resets the TextBox. /// Clears the current hotkey and resets the TextBox.
/// </summary> /// </summary>
public void ResetHotkey() private void ResetHotkey()
{ {
hotkey = Key.None; hotkey = Key.None;
modifiers = ModifierKeys.None; modifiers = ModifierKeys.None;
Redraw(false); Redraw(false);
} }
/// <summary>
/// Used to get/set the hotkey (e.g. Key.A).
/// </summary>
/// <param name="hotkey">hotkey.</param>
public void SetHotkey(string hotkey)
{
this.hotkey = GlobalHotkeys.KeyFromString(hotkey);
modifiers = GlobalHotkeys.ModifierKeysFromString(hotkey);
Redraw(true);
}
public override string ToString() => HotkeyToString(modifiers, hotkey);
private void HandlePreviewKeyDown(object sender, KeyEventArgs e) private void HandlePreviewKeyDown(object sender, KeyEventArgs e)
{ {
// Handle some misc keys, such as Delete and Shift+Insert // Handle some misc keys, such as Delete and Shift+Insert