diff --git a/src/Artemis.Core/Services/Input/Enums/KeyboardKey.cs b/src/Artemis.Core/Services/Input/Enums/KeyboardKey.cs index 75abc7db2..39bfbcbd2 100644 --- a/src/Artemis.Core/Services/Input/Enums/KeyboardKey.cs +++ b/src/Artemis.Core/Services/Input/Enums/KeyboardKey.cs @@ -532,5 +532,20 @@ public enum KeyboardKey DeadCharProcessed = 172, // 0x000000AC, /// The NumPad enter key - NumPadEnter + NumPadEnter, + + /// The NumPad divide key + NumPadDivide, + + /// The NumPad multiply key + NumPadMultiply, + + /// The NumPad subtract key + NumPadSubtract, + + /// The NumPad add key + NumPadAdd, + + /// The NumPad decimal key + NumPadDecimal, } \ No newline at end of file diff --git a/src/Artemis.Core/Services/Input/InputKeyLedIdMap.cs b/src/Artemis.Core/Services/Input/InputKeyLedIdMap.cs index d04f217dc..b240c7f51 100644 --- a/src/Artemis.Core/Services/Input/InputKeyLedIdMap.cs +++ b/src/Artemis.Core/Services/Input/InputKeyLedIdMap.cs @@ -166,7 +166,7 @@ public static class InputKeyUtilities {KeyboardKey.OemPipe, LedId.Keyboard_Backslash}, {KeyboardKey.OemCloseBrackets, LedId.Keyboard_BracketRight}, {KeyboardKey.OemQuotes, LedId.Keyboard_ApostropheAndDoubleQuote}, - {KeyboardKey.OemBackslash, LedId.Keyboard_Custom42}, // unverified + {KeyboardKey.OemBackslash, LedId.Keyboard_NonUsBackslash}, {KeyboardKey.ImeProcessed, LedId.Keyboard_Custom43}, {KeyboardKey.System, LedId.Keyboard_Custom44}, {KeyboardKey.OemAttn, LedId.Keyboard_Custom45}, @@ -185,7 +185,12 @@ public static class InputKeyUtilities {KeyboardKey.Pa1, LedId.Keyboard_Custom57}, {KeyboardKey.OemClear, LedId.Keyboard_Custom58}, {KeyboardKey.DeadCharProcessed, LedId.Keyboard_Custom59}, - {KeyboardKey.NumPadEnter, LedId.Keyboard_NumEnter} + {KeyboardKey.NumPadEnter, LedId.Keyboard_NumEnter}, + {KeyboardKey.NumPadDecimal, LedId.Keyboard_NumPeriodAndDelete}, + {KeyboardKey.NumPadDivide, LedId.Keyboard_NumSlash}, + {KeyboardKey.NumPadMultiply, LedId.Keyboard_NumAsterisk}, + {KeyboardKey.NumPadSubtract, LedId.Keyboard_NumMinus}, + {KeyboardKey.NumPadAdd, LedId.Keyboard_NumPlus}, }; /// diff --git a/src/Artemis.Core/Services/Input/InputService.cs b/src/Artemis.Core/Services/Input/InputService.cs index 48ae607f6..fa6c983f4 100644 --- a/src/Artemis.Core/Services/Input/InputService.cs +++ b/src/Artemis.Core/Services/Input/InputService.cs @@ -269,6 +269,13 @@ internal class InputService : IInputService // Get the LED bool foundLedId = InputKeyUtilities.KeyboardKeyLedIdMap.TryGetValue(e.Key, out LedId ledId); + // If we find a backslash but the keyboard is ISO, we need to use the non-US backslash. + // The scancode is the same, but the LED ID is different + if (ledId == LedId.Keyboard_Backslash && e.Device?.PhysicalLayout == KeyboardLayoutType.ISO) + { + ledId = LedId.Keyboard_NonUsTilde; + } + ArtemisLed? led = null; if (foundLedId && e.Device != null) led = e.Device.GetLed(ledId, true); diff --git a/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs b/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs index ef8f168ec..c50a626df 100644 --- a/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs +++ b/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Timers; @@ -98,7 +98,7 @@ public class WindowsInputProvider : InputProvider private void HandleKeyboardData(RawInputData data, RawInputKeyboardData keyboardData) { - KeyboardKey key = InputUtilities.KeyFromVirtualKey(keyboardData.Keyboard.VirutalKey); + KeyboardKey key = InputUtilities.CorrectVirtualKeyAndScanCode((uint)keyboardData.Keyboard.VirutalKey, (uint)keyboardData.Keyboard.ScanCode, (uint)keyboardData.Keyboard.Flags); // Debug.WriteLine($"VK: {key} ({keyboardData.Keyboard.VirutalKey}), Flags: {keyboardData.Keyboard.Flags}, Scan code: {keyboardData.Keyboard.ScanCode}"); // Sometimes we get double hits and they resolve to None, ignore those diff --git a/src/Artemis.UI.Windows/Utilities/InputUtilities.cs b/src/Artemis.UI.Windows/Utilities/InputUtilities.cs index f18ff88cc..3a06fccf4 100644 --- a/src/Artemis.UI.Windows/Utilities/InputUtilities.cs +++ b/src/Artemis.UI.Windows/Utilities/InputUtilities.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.InteropServices; +using System.Text; using Artemis.Core.Services; using Microsoft.Win32; @@ -11,6 +12,135 @@ namespace Artemis.UI.Windows.Utilities; /// public static class InputUtilities { + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + private static extern short GetKeyState(int keyCode); + + [DllImport("user32.dll")] + private static extern uint MapVirtualKey(uint uCode, MapVirtualKeyMapTypes uMapType); + + [Flags] + private enum KeyStates + { + None = 0, + Down = 1, + Toggled = 2 + } + + /// + /// The set of valid MapTypes used in MapVirtualKey + /// + private enum MapVirtualKeyMapTypes : uint + { + /// + /// uCode is a virtual-key code and is translated into a scan code. + /// If it is a virtual-key code that does not distinguish between left- and + /// right-hand keys, the left-hand scan code is returned. + /// If there is no translation, the function returns 0. + /// + MAPVK_VK_TO_VSC = 0x00, + + /// + /// uCode is a scan code and is translated into a virtual-key code that + /// does not distinguish between left- and right-hand keys. If there is no + /// translation, the function returns 0. + /// + MAPVK_VSC_TO_VK = 0x01, + + /// + /// uCode is a virtual-key code and is translated into an unshifted + /// character value in the low-order word of the return value. Dead keys (diacritics) + /// are indicated by setting the top bit of the return value. If there is no + /// translation, the function returns 0. + /// + MAPVK_VK_TO_CHAR = 0x02, + + /// + /// Windows NT/2000/XP: uCode is a scan code and is translated into a + /// virtual-key code that distinguishes between left- and right-hand keys. If + /// there is no translation, the function returns 0. + /// + MAPVK_VSC_TO_VK_EX = 0x03, + + /// + /// Not currently documented + /// + MAPVK_VK_TO_VSC_EX = 0x04 + } + + /// + /// https://blog.molecular-matters.com/2011/09/05/properly-handling-keyboard-input/ + /// + public static KeyboardKey CorrectVirtualKeyAndScanCode(uint virtualKey, uint scanCode, uint flags) + { + if (virtualKey == 255) + { + // discard "fake keys" which are part of an escaped sequence + return KeyboardKey.None; + } + + if (virtualKey == NativeMethods.VK_CONTROL && scanCode == 0x38) + { + //fake altgr ctrl + return KeyboardKey.None; + } + + if (virtualKey == NativeMethods.VK_SHIFT) + { + // correct left-hand / right-hand SHIFT + virtualKey = MapVirtualKey(scanCode, MapVirtualKeyMapTypes.MAPVK_VSC_TO_VK); + } + else if (virtualKey == NativeMethods.VK_NUMLOCK) + { + // correct PAUSE/BREAK and NUM LOCK silliness, and set the extended bit + scanCode = MapVirtualKey(virtualKey, MapVirtualKeyMapTypes.MAPVK_VK_TO_VSC) | 0x100; + } + + const byte RI_KEY_E0 = 0x02; + const byte RI_KEY_E1 = 0x04; + bool isE0 = (flags & RI_KEY_E0) != 0; + bool isE1 = (flags & RI_KEY_E1) != 0; + + if (isE1) + { + if (virtualKey == NativeMethods.VK_PAUSE) + { + scanCode = 0x45; + } + else + { + scanCode = MapVirtualKey(virtualKey, MapVirtualKeyMapTypes.MAPVK_VK_TO_VSC); + } + } + KeyboardKey key = (short)virtualKey switch + { + NativeMethods.VK_CONTROL => isE0 ? KeyboardKey.RightCtrl : KeyboardKey.LeftCtrl, + NativeMethods.VK_MENU => isE0 ? KeyboardKey.RightAlt : KeyboardKey.LeftAlt, + NativeMethods.VK_RETURN => isE0 ? KeyboardKey.NumPadEnter : KeyboardKey.Enter, + NativeMethods.VK_INSERT => !isE0 ? KeyboardKey.NumPad0 : KeyboardKey.Insert, + NativeMethods.VK_DELETE => !isE0 ? KeyboardKey.NumPadDecimal : KeyboardKey.Delete, + NativeMethods.VK_HOME => !isE0 ? KeyboardKey.NumPad7 : KeyboardKey.Home, + NativeMethods.VK_END => !isE0 ? KeyboardKey.NumPad1 : KeyboardKey.End, + NativeMethods.VK_PRIOR => !isE0 ? KeyboardKey.NumPad9 : KeyboardKey.PageUp, + NativeMethods.VK_NEXT => !isE0 ? KeyboardKey.NumPad3 : KeyboardKey.PageDown, + NativeMethods.VK_LEFT => !isE0 ? KeyboardKey.NumPad4 : KeyboardKey.Left, + NativeMethods.VK_RIGHT => !isE0 ? KeyboardKey.NumPad6 : KeyboardKey.Right, + NativeMethods.VK_UP => !isE0 ? KeyboardKey.NumPad8 : KeyboardKey.Up, + NativeMethods.VK_DOWN => !isE0 ? KeyboardKey.NumPad2 : KeyboardKey.Down, + NativeMethods.VK_CLEAR => !isE0 ? KeyboardKey.NumPad5 : KeyboardKey.Clear, + NativeMethods.VK_DIVIDE => isE0 ? KeyboardKey.NumPadDivide : KeyboardKey.Divide, + NativeMethods.VK_MULTIPLY => isE0 ? KeyboardKey.NumPadMultiply : KeyboardKey.Multiply, + _ => KeyboardKey.None + }; + if (key != KeyboardKey.None) + return key; + + key = KeyFromScanCode(scanCode); + if (key != KeyboardKey.None) + return key; + + return KeyFromVirtualKey((int)virtualKey); + + } public static bool IsKeyDown(KeyboardKey key) { return KeyStates.Down == (GetKeyState(key) & KeyStates.Down); @@ -21,1355 +151,6 @@ public static class InputUtilities return KeyStates.Toggled == (GetKeyState(key) & KeyStates.Toggled); } - /// - /// Convert a Win32 VirtualKey into our Key enum. - /// - public static KeyboardKey KeyFromVirtualKey(int virtualKey) - { - KeyboardKey key = KeyboardKey.None; - - switch (virtualKey) - { - case NativeMethods.VK_CANCEL: - key = KeyboardKey.Cancel; - break; - - case NativeMethods.VK_BACK: - key = KeyboardKey.Back; - break; - - case NativeMethods.VK_TAB: - key = KeyboardKey.Tab; - break; - - case NativeMethods.VK_CLEAR: - key = KeyboardKey.Clear; - break; - - case NativeMethods.VK_RETURN: - key = KeyboardKey.Return; - break; - - case NativeMethods.VK_PAUSE: - key = KeyboardKey.Pause; - break; - - case NativeMethods.VK_CAPSLOCK: - key = KeyboardKey.CapsLock; - break; - - case NativeMethods.VK_JUNJA: - key = KeyboardKey.JunjaMode; - break; - - case NativeMethods.VK_FINAL: - key = KeyboardKey.FinalMode; - break; - - case NativeMethods.VK_ESCAPE: - key = KeyboardKey.Escape; - break; - - case NativeMethods.VK_CONVERT: - key = KeyboardKey.ImeConvert; - break; - - case NativeMethods.VK_NONCONVERT: - key = KeyboardKey.ImeNonConvert; - break; - - case NativeMethods.VK_ACCEPT: - key = KeyboardKey.ImeAccept; - break; - - case NativeMethods.VK_MODECHANGE: - key = KeyboardKey.ImeModeChange; - break; - - case NativeMethods.VK_SPACE: - key = KeyboardKey.Space; - break; - - case NativeMethods.VK_PRIOR: - key = KeyboardKey.Prior; - break; - - case NativeMethods.VK_NEXT: - key = KeyboardKey.Next; - break; - - case NativeMethods.VK_END: - key = KeyboardKey.End; - break; - - case NativeMethods.VK_HOME: - key = KeyboardKey.Home; - break; - - case NativeMethods.VK_LEFT: - key = KeyboardKey.Left; - break; - - case NativeMethods.VK_UP: - key = KeyboardKey.Up; - break; - - case NativeMethods.VK_RIGHT: - key = KeyboardKey.Right; - break; - - case NativeMethods.VK_DOWN: - key = KeyboardKey.Down; - break; - - case NativeMethods.VK_SELECT: - key = KeyboardKey.Select; - break; - - case NativeMethods.VK_PRINT: - key = KeyboardKey.Print; - break; - - case NativeMethods.VK_EXECUTE: - key = KeyboardKey.Execute; - break; - - case NativeMethods.VK_INSERT: - key = KeyboardKey.Insert; - break; - - case NativeMethods.VK_DELETE: - key = KeyboardKey.Delete; - break; - - case NativeMethods.VK_HELP: - key = KeyboardKey.Help; - break; - - case NativeMethods.VK_0: - key = KeyboardKey.D0; - break; - - case NativeMethods.VK_1: - key = KeyboardKey.D1; - break; - - case NativeMethods.VK_2: - key = KeyboardKey.D2; - break; - - case NativeMethods.VK_3: - key = KeyboardKey.D3; - break; - - case NativeMethods.VK_4: - key = KeyboardKey.D4; - break; - - case NativeMethods.VK_5: - key = KeyboardKey.D5; - break; - - case NativeMethods.VK_6: - key = KeyboardKey.D6; - break; - - case NativeMethods.VK_7: - key = KeyboardKey.D7; - break; - - case NativeMethods.VK_8: - key = KeyboardKey.D8; - break; - - case NativeMethods.VK_9: - key = KeyboardKey.D9; - break; - - case NativeMethods.VK_A: - key = KeyboardKey.A; - break; - - case NativeMethods.VK_B: - key = KeyboardKey.B; - break; - - case NativeMethods.VK_C: - key = KeyboardKey.C; - break; - - case NativeMethods.VK_D: - key = KeyboardKey.D; - break; - - case NativeMethods.VK_E: - key = KeyboardKey.E; - break; - - case NativeMethods.VK_F: - key = KeyboardKey.F; - break; - - case NativeMethods.VK_G: - key = KeyboardKey.G; - break; - - case NativeMethods.VK_H: - key = KeyboardKey.H; - break; - - case NativeMethods.VK_I: - key = KeyboardKey.I; - break; - - case NativeMethods.VK_J: - key = KeyboardKey.J; - break; - - case NativeMethods.VK_K: - key = KeyboardKey.K; - break; - - case NativeMethods.VK_L: - key = KeyboardKey.L; - break; - - case NativeMethods.VK_M: - key = KeyboardKey.M; - break; - - case NativeMethods.VK_N: - key = KeyboardKey.N; - break; - - case NativeMethods.VK_O: - key = KeyboardKey.O; - break; - - case NativeMethods.VK_P: - key = KeyboardKey.P; - break; - - case NativeMethods.VK_Q: - key = KeyboardKey.Q; - break; - - case NativeMethods.VK_R: - key = KeyboardKey.R; - break; - - case NativeMethods.VK_S: - key = KeyboardKey.S; - break; - - case NativeMethods.VK_T: - key = KeyboardKey.T; - break; - - case NativeMethods.VK_U: - key = KeyboardKey.U; - break; - - case NativeMethods.VK_V: - key = KeyboardKey.V; - break; - - case NativeMethods.VK_W: - key = KeyboardKey.W; - break; - - case NativeMethods.VK_X: - key = KeyboardKey.X; - break; - - case NativeMethods.VK_Y: - key = KeyboardKey.Y; - break; - - case NativeMethods.VK_Z: - key = KeyboardKey.Z; - break; - - case NativeMethods.VK_LWIN: - key = KeyboardKey.LWin; - break; - - case NativeMethods.VK_RWIN: - key = KeyboardKey.RWin; - break; - - case NativeMethods.VK_APPS: - key = KeyboardKey.Apps; - break; - - case NativeMethods.VK_SLEEP: - key = KeyboardKey.Sleep; - break; - - case NativeMethods.VK_NUMPAD0: - key = KeyboardKey.NumPad0; - break; - - case NativeMethods.VK_NUMPAD1: - key = KeyboardKey.NumPad1; - break; - - case NativeMethods.VK_NUMPAD2: - key = KeyboardKey.NumPad2; - break; - - case NativeMethods.VK_NUMPAD3: - key = KeyboardKey.NumPad3; - break; - - case NativeMethods.VK_NUMPAD4: - key = KeyboardKey.NumPad4; - break; - - case NativeMethods.VK_NUMPAD5: - key = KeyboardKey.NumPad5; - break; - - case NativeMethods.VK_NUMPAD6: - key = KeyboardKey.NumPad6; - break; - - case NativeMethods.VK_NUMPAD7: - key = KeyboardKey.NumPad7; - break; - - case NativeMethods.VK_NUMPAD8: - key = KeyboardKey.NumPad8; - break; - - case NativeMethods.VK_NUMPAD9: - key = KeyboardKey.NumPad9; - break; - - case NativeMethods.VK_MULTIPLY: - key = KeyboardKey.Multiply; - break; - - case NativeMethods.VK_ADD: - key = KeyboardKey.Add; - break; - - case NativeMethods.VK_SEPARATOR: - key = KeyboardKey.Separator; - break; - - case NativeMethods.VK_SUBTRACT: - key = KeyboardKey.Subtract; - break; - - case NativeMethods.VK_DECIMAL: - key = KeyboardKey.Decimal; - break; - - case NativeMethods.VK_DIVIDE: - key = KeyboardKey.Divide; - break; - - case NativeMethods.VK_F1: - key = KeyboardKey.F1; - break; - - case NativeMethods.VK_F2: - key = KeyboardKey.F2; - break; - - case NativeMethods.VK_F3: - key = KeyboardKey.F3; - break; - - case NativeMethods.VK_F4: - key = KeyboardKey.F4; - break; - - case NativeMethods.VK_F5: - key = KeyboardKey.F5; - break; - - case NativeMethods.VK_F6: - key = KeyboardKey.F6; - break; - - case NativeMethods.VK_F7: - key = KeyboardKey.F7; - break; - - case NativeMethods.VK_F8: - key = KeyboardKey.F8; - break; - - case NativeMethods.VK_F9: - key = KeyboardKey.F9; - break; - - case NativeMethods.VK_F10: - key = KeyboardKey.F10; - break; - - case NativeMethods.VK_F11: - key = KeyboardKey.F11; - break; - - case NativeMethods.VK_F12: - key = KeyboardKey.F12; - break; - - case NativeMethods.VK_F13: - key = KeyboardKey.F13; - break; - - case NativeMethods.VK_F14: - key = KeyboardKey.F14; - break; - - case NativeMethods.VK_F15: - key = KeyboardKey.F15; - break; - - case NativeMethods.VK_F16: - key = KeyboardKey.F16; - break; - - case NativeMethods.VK_F17: - key = KeyboardKey.F17; - break; - - case NativeMethods.VK_F18: - key = KeyboardKey.F18; - break; - - case NativeMethods.VK_F19: - key = KeyboardKey.F19; - break; - - case NativeMethods.VK_F20: - key = KeyboardKey.F20; - break; - - case NativeMethods.VK_F21: - key = KeyboardKey.F21; - break; - - case NativeMethods.VK_F22: - key = KeyboardKey.F22; - break; - - case NativeMethods.VK_F23: - key = KeyboardKey.F23; - break; - - case NativeMethods.VK_F24: - key = KeyboardKey.F24; - break; - - case NativeMethods.VK_NUMLOCK: - key = KeyboardKey.NumLock; - break; - - case NativeMethods.VK_SCROLL: - key = KeyboardKey.Scroll; - break; - - case NativeMethods.VK_SHIFT: - case NativeMethods.VK_LSHIFT: - key = KeyboardKey.LeftShift; - break; - - case NativeMethods.VK_RSHIFT: - key = KeyboardKey.RightShift; - break; - - case NativeMethods.VK_CONTROL: - case NativeMethods.VK_LCONTROL: - key = KeyboardKey.LeftCtrl; - break; - - case NativeMethods.VK_RCONTROL: - key = KeyboardKey.RightCtrl; - break; - - case NativeMethods.VK_MENU: - case NativeMethods.VK_LMENU: - key = KeyboardKey.LeftAlt; - break; - - case NativeMethods.VK_RMENU: - key = KeyboardKey.RightAlt; - break; - - case NativeMethods.VK_BROWSER_BACK: - key = KeyboardKey.BrowserBack; - break; - - case NativeMethods.VK_BROWSER_FORWARD: - key = KeyboardKey.BrowserForward; - break; - - case NativeMethods.VK_BROWSER_REFRESH: - key = KeyboardKey.BrowserRefresh; - break; - - case NativeMethods.VK_BROWSER_STOP: - key = KeyboardKey.BrowserStop; - break; - - case NativeMethods.VK_BROWSER_SEARCH: - key = KeyboardKey.BrowserSearch; - break; - - case NativeMethods.VK_BROWSER_FAVORITES: - key = KeyboardKey.BrowserFavorites; - break; - - case NativeMethods.VK_BROWSER_HOME: - key = KeyboardKey.BrowserHome; - break; - - case NativeMethods.VK_VOLUME_MUTE: - key = KeyboardKey.VolumeMute; - break; - - case NativeMethods.VK_VOLUME_DOWN: - key = KeyboardKey.VolumeDown; - break; - - case NativeMethods.VK_VOLUME_UP: - key = KeyboardKey.VolumeUp; - break; - - case NativeMethods.VK_MEDIA_NEXT_TRACK: - key = KeyboardKey.MediaNextTrack; - break; - - case NativeMethods.VK_MEDIA_PREV_TRACK: - key = KeyboardKey.MediaPreviousTrack; - break; - - case NativeMethods.VK_MEDIA_STOP: - key = KeyboardKey.MediaStop; - break; - - case NativeMethods.VK_MEDIA_PLAY_PAUSE: - key = KeyboardKey.MediaPlayPause; - break; - - case NativeMethods.VK_LAUNCH_MAIL: - key = KeyboardKey.LaunchMail; - break; - - case NativeMethods.VK_LAUNCH_MEDIA_SELECT: - key = KeyboardKey.SelectMedia; - break; - - case NativeMethods.VK_LAUNCH_APP1: - key = KeyboardKey.LaunchApplication1; - break; - - case NativeMethods.VK_LAUNCH_APP2: - key = KeyboardKey.LaunchApplication2; - break; - - case NativeMethods.VK_OEM_1: - key = KeyboardKey.OemSemicolon; - break; - - case NativeMethods.VK_OEM_PLUS: - key = KeyboardKey.OemPlus; - break; - - case NativeMethods.VK_OEM_COMMA: - key = KeyboardKey.OemComma; - break; - - case NativeMethods.VK_OEM_MINUS: - key = KeyboardKey.OemMinus; - break; - - case NativeMethods.VK_OEM_PERIOD: - key = KeyboardKey.OemPeriod; - break; - - case NativeMethods.VK_OEM_2: - key = KeyboardKey.OemQuestion; - break; - - case NativeMethods.VK_OEM_3: - key = KeyboardKey.OemTilde; - break; - - - case NativeMethods.VK_OEM_4: - key = KeyboardKey.OemOpenBrackets; - break; - - case NativeMethods.VK_OEM_5: - key = KeyboardKey.OemPipe; - break; - - case NativeMethods.VK_OEM_6: - key = KeyboardKey.OemCloseBrackets; - break; - - case NativeMethods.VK_OEM_7: - key = KeyboardKey.OemQuotes; - break; - - case NativeMethods.VK_OEM_102: - key = KeyboardKey.OemBackslash; - break; - - case NativeMethods.VK_PROCESSKEY: - key = KeyboardKey.ImeProcessed; - break; - - case NativeMethods.VK_OEM_ATTN: // VK_DBE_ALPHANUMERIC - key = KeyboardKey.OemAttn; // DbeAlphanumeric - break; - - case NativeMethods.VK_OEM_FINISH: // VK_DBE_KATAKANA - key = KeyboardKey.OemFinish; // DbeKatakana - break; - - case NativeMethods.VK_OEM_COPY: // VK_DBE_HIRAGANA - key = KeyboardKey.OemCopy; // DbeHiragana - break; - - case NativeMethods.VK_OEM_AUTO: // VK_DBE_SBCSCHAR - key = KeyboardKey.OemAuto; // DbeSbcsChar - break; - - case NativeMethods.VK_OEM_ENLW: // VK_DBE_DBCSCHAR - key = KeyboardKey.OemEnlw; // DbeDbcsChar - break; - - case NativeMethods.VK_OEM_BACKTAB: // VK_DBE_ROMAN - key = KeyboardKey.OemBackTab; // DbeRoman - break; - - case NativeMethods.VK_ATTN: // VK_DBE_NOROMAN - key = KeyboardKey.Attn; // DbeNoRoman - break; - - case NativeMethods.VK_CRSEL: // VK_DBE_ENTERWORDREGISTERMODE - key = KeyboardKey.CrSel; // DbeEnterWordRegisterMode - break; - - case NativeMethods.VK_EXSEL: // VK_DBE_ENTERIMECONFIGMODE - key = KeyboardKey.ExSel; // DbeEnterImeConfigMode - break; - - case NativeMethods.VK_EREOF: // VK_DBE_FLUSHSTRING - key = KeyboardKey.EraseEof; // DbeFlushString - break; - - case NativeMethods.VK_PLAY: // VK_DBE_CODEINPUT - key = KeyboardKey.Play; // DbeCodeInput - break; - - case NativeMethods.VK_ZOOM: // VK_DBE_NOCODEINPUT - key = KeyboardKey.Zoom; // DbeNoCodeInput - break; - - case NativeMethods.VK_NONAME: // VK_DBE_DETERMINESTRING - key = KeyboardKey.NoName; // DbeDetermineString - break; - - case NativeMethods.VK_PA1: // VK_DBE_ENTERDLGCONVERSIONMODE - key = KeyboardKey.Pa1; // DbeEnterDlgConversionMode - break; - - case NativeMethods.VK_OEM_CLEAR: - key = KeyboardKey.OemClear; - break; - - default: - key = KeyboardKey.None; - break; - } - - return key; - } - - /// - /// Convert our Key enum into a Win32 VirtualKeyboardKey. - /// - public static int VirtualKeyFromKey(KeyboardKey key) - { - int virtualKey = 0; - - switch (key) - { - case KeyboardKey.Cancel: - virtualKey = NativeMethods.VK_CANCEL; - break; - - case KeyboardKey.Back: - virtualKey = NativeMethods.VK_BACK; - break; - - case KeyboardKey.Tab: - virtualKey = NativeMethods.VK_TAB; - break; - - case KeyboardKey.Clear: - virtualKey = NativeMethods.VK_CLEAR; - break; - - case KeyboardKey.Return: - virtualKey = NativeMethods.VK_RETURN; - break; - - case KeyboardKey.Pause: - virtualKey = NativeMethods.VK_PAUSE; - break; - - case KeyboardKey.CapsLock: - virtualKey = NativeMethods.VK_CAPSLOCK; - break; - - case KeyboardKey.JunjaMode: - virtualKey = NativeMethods.VK_JUNJA; - break; - - case KeyboardKey.FinalMode: - virtualKey = NativeMethods.VK_FINAL; - break; - - case KeyboardKey.Escape: - virtualKey = NativeMethods.VK_ESCAPE; - break; - - case KeyboardKey.ImeConvert: - virtualKey = NativeMethods.VK_CONVERT; - break; - - case KeyboardKey.ImeNonConvert: - virtualKey = NativeMethods.VK_NONCONVERT; - break; - - case KeyboardKey.ImeAccept: - virtualKey = NativeMethods.VK_ACCEPT; - break; - - case KeyboardKey.ImeModeChange: - virtualKey = NativeMethods.VK_MODECHANGE; - break; - - case KeyboardKey.Space: - virtualKey = NativeMethods.VK_SPACE; - break; - - case KeyboardKey.Prior: - virtualKey = NativeMethods.VK_PRIOR; - break; - - case KeyboardKey.Next: - virtualKey = NativeMethods.VK_NEXT; - break; - - case KeyboardKey.End: - virtualKey = NativeMethods.VK_END; - break; - - case KeyboardKey.Home: - virtualKey = NativeMethods.VK_HOME; - break; - - case KeyboardKey.Left: - virtualKey = NativeMethods.VK_LEFT; - break; - - case KeyboardKey.Up: - virtualKey = NativeMethods.VK_UP; - break; - - case KeyboardKey.Right: - virtualKey = NativeMethods.VK_RIGHT; - break; - - case KeyboardKey.Down: - virtualKey = NativeMethods.VK_DOWN; - break; - - case KeyboardKey.Select: - virtualKey = NativeMethods.VK_SELECT; - break; - - case KeyboardKey.Print: - virtualKey = NativeMethods.VK_PRINT; - break; - - case KeyboardKey.Execute: - virtualKey = NativeMethods.VK_EXECUTE; - break; - - case KeyboardKey.Insert: - virtualKey = NativeMethods.VK_INSERT; - break; - - case KeyboardKey.Delete: - virtualKey = NativeMethods.VK_DELETE; - break; - - case KeyboardKey.Help: - virtualKey = NativeMethods.VK_HELP; - break; - - case KeyboardKey.D0: - virtualKey = NativeMethods.VK_0; - break; - - case KeyboardKey.D1: - virtualKey = NativeMethods.VK_1; - break; - - case KeyboardKey.D2: - virtualKey = NativeMethods.VK_2; - break; - - case KeyboardKey.D3: - virtualKey = NativeMethods.VK_3; - break; - - case KeyboardKey.D4: - virtualKey = NativeMethods.VK_4; - break; - - case KeyboardKey.D5: - virtualKey = NativeMethods.VK_5; - break; - - case KeyboardKey.D6: - virtualKey = NativeMethods.VK_6; - break; - - case KeyboardKey.D7: - virtualKey = NativeMethods.VK_7; - break; - - case KeyboardKey.D8: - virtualKey = NativeMethods.VK_8; - break; - - case KeyboardKey.D9: - virtualKey = NativeMethods.VK_9; - break; - - case KeyboardKey.A: - virtualKey = NativeMethods.VK_A; - break; - - case KeyboardKey.B: - virtualKey = NativeMethods.VK_B; - break; - - case KeyboardKey.C: - virtualKey = NativeMethods.VK_C; - break; - - case KeyboardKey.D: - virtualKey = NativeMethods.VK_D; - break; - - case KeyboardKey.E: - virtualKey = NativeMethods.VK_E; - break; - - case KeyboardKey.F: - virtualKey = NativeMethods.VK_F; - break; - - case KeyboardKey.G: - virtualKey = NativeMethods.VK_G; - break; - - case KeyboardKey.H: - virtualKey = NativeMethods.VK_H; - break; - - case KeyboardKey.I: - virtualKey = NativeMethods.VK_I; - break; - - case KeyboardKey.J: - virtualKey = NativeMethods.VK_J; - break; - - case KeyboardKey.K: - virtualKey = NativeMethods.VK_K; - break; - - case KeyboardKey.L: - virtualKey = NativeMethods.VK_L; - break; - - case KeyboardKey.M: - virtualKey = NativeMethods.VK_M; - break; - - case KeyboardKey.N: - virtualKey = NativeMethods.VK_N; - break; - - case KeyboardKey.O: - virtualKey = NativeMethods.VK_O; - break; - - case KeyboardKey.P: - virtualKey = NativeMethods.VK_P; - break; - - case KeyboardKey.Q: - virtualKey = NativeMethods.VK_Q; - break; - - case KeyboardKey.R: - virtualKey = NativeMethods.VK_R; - break; - - case KeyboardKey.S: - virtualKey = NativeMethods.VK_S; - break; - - case KeyboardKey.T: - virtualKey = NativeMethods.VK_T; - break; - - case KeyboardKey.U: - virtualKey = NativeMethods.VK_U; - break; - - case KeyboardKey.V: - virtualKey = NativeMethods.VK_V; - break; - - case KeyboardKey.W: - virtualKey = NativeMethods.VK_W; - break; - - case KeyboardKey.X: - virtualKey = NativeMethods.VK_X; - break; - - case KeyboardKey.Y: - virtualKey = NativeMethods.VK_Y; - break; - - case KeyboardKey.Z: - virtualKey = NativeMethods.VK_Z; - break; - - case KeyboardKey.LWin: - virtualKey = NativeMethods.VK_LWIN; - break; - - case KeyboardKey.RWin: - virtualKey = NativeMethods.VK_RWIN; - break; - - case KeyboardKey.Apps: - virtualKey = NativeMethods.VK_APPS; - break; - - case KeyboardKey.Sleep: - virtualKey = NativeMethods.VK_SLEEP; - break; - - case KeyboardKey.NumPad0: - virtualKey = NativeMethods.VK_NUMPAD0; - break; - - case KeyboardKey.NumPad1: - virtualKey = NativeMethods.VK_NUMPAD1; - break; - - case KeyboardKey.NumPad2: - virtualKey = NativeMethods.VK_NUMPAD2; - break; - - case KeyboardKey.NumPad3: - virtualKey = NativeMethods.VK_NUMPAD3; - break; - - case KeyboardKey.NumPad4: - virtualKey = NativeMethods.VK_NUMPAD4; - break; - - case KeyboardKey.NumPad5: - virtualKey = NativeMethods.VK_NUMPAD5; - break; - - case KeyboardKey.NumPad6: - virtualKey = NativeMethods.VK_NUMPAD6; - break; - - case KeyboardKey.NumPad7: - virtualKey = NativeMethods.VK_NUMPAD7; - break; - - case KeyboardKey.NumPad8: - virtualKey = NativeMethods.VK_NUMPAD8; - break; - - case KeyboardKey.NumPad9: - virtualKey = NativeMethods.VK_NUMPAD9; - break; - - case KeyboardKey.Multiply: - virtualKey = NativeMethods.VK_MULTIPLY; - break; - - case KeyboardKey.Add: - virtualKey = NativeMethods.VK_ADD; - break; - - case KeyboardKey.Separator: - virtualKey = NativeMethods.VK_SEPARATOR; - break; - - case KeyboardKey.Subtract: - virtualKey = NativeMethods.VK_SUBTRACT; - break; - - case KeyboardKey.Decimal: - virtualKey = NativeMethods.VK_DECIMAL; - break; - - case KeyboardKey.Divide: - virtualKey = NativeMethods.VK_DIVIDE; - break; - - case KeyboardKey.F1: - virtualKey = NativeMethods.VK_F1; - break; - - case KeyboardKey.F2: - virtualKey = NativeMethods.VK_F2; - break; - - case KeyboardKey.F3: - virtualKey = NativeMethods.VK_F3; - break; - - case KeyboardKey.F4: - virtualKey = NativeMethods.VK_F4; - break; - - case KeyboardKey.F5: - virtualKey = NativeMethods.VK_F5; - break; - - case KeyboardKey.F6: - virtualKey = NativeMethods.VK_F6; - break; - - case KeyboardKey.F7: - virtualKey = NativeMethods.VK_F7; - break; - - case KeyboardKey.F8: - virtualKey = NativeMethods.VK_F8; - break; - - case KeyboardKey.F9: - virtualKey = NativeMethods.VK_F9; - break; - - case KeyboardKey.F10: - virtualKey = NativeMethods.VK_F10; - break; - - case KeyboardKey.F11: - virtualKey = NativeMethods.VK_F11; - break; - - case KeyboardKey.F12: - virtualKey = NativeMethods.VK_F12; - break; - - case KeyboardKey.F13: - virtualKey = NativeMethods.VK_F13; - break; - - case KeyboardKey.F14: - virtualKey = NativeMethods.VK_F14; - break; - - case KeyboardKey.F15: - virtualKey = NativeMethods.VK_F15; - break; - - case KeyboardKey.F16: - virtualKey = NativeMethods.VK_F16; - break; - - case KeyboardKey.F17: - virtualKey = NativeMethods.VK_F17; - break; - - case KeyboardKey.F18: - virtualKey = NativeMethods.VK_F18; - break; - - case KeyboardKey.F19: - virtualKey = NativeMethods.VK_F19; - break; - - case KeyboardKey.F20: - virtualKey = NativeMethods.VK_F20; - break; - - case KeyboardKey.F21: - virtualKey = NativeMethods.VK_F21; - break; - - case KeyboardKey.F22: - virtualKey = NativeMethods.VK_F22; - break; - - case KeyboardKey.F23: - virtualKey = NativeMethods.VK_F23; - break; - - case KeyboardKey.F24: - virtualKey = NativeMethods.VK_F24; - break; - - case KeyboardKey.NumLock: - virtualKey = NativeMethods.VK_NUMLOCK; - break; - - case KeyboardKey.Scroll: - virtualKey = NativeMethods.VK_SCROLL; - break; - - case KeyboardKey.LeftShift: - virtualKey = NativeMethods.VK_LSHIFT; - break; - - case KeyboardKey.RightShift: - virtualKey = NativeMethods.VK_RSHIFT; - break; - - case KeyboardKey.LeftCtrl: - virtualKey = NativeMethods.VK_LCONTROL; - break; - - case KeyboardKey.RightCtrl: - virtualKey = NativeMethods.VK_RCONTROL; - break; - - case KeyboardKey.LeftAlt: - virtualKey = NativeMethods.VK_LMENU; - break; - - case KeyboardKey.RightAlt: - virtualKey = NativeMethods.VK_RMENU; - break; - - case KeyboardKey.BrowserBack: - virtualKey = NativeMethods.VK_BROWSER_BACK; - break; - - case KeyboardKey.BrowserForward: - virtualKey = NativeMethods.VK_BROWSER_FORWARD; - break; - - case KeyboardKey.BrowserRefresh: - virtualKey = NativeMethods.VK_BROWSER_REFRESH; - break; - - case KeyboardKey.BrowserStop: - virtualKey = NativeMethods.VK_BROWSER_STOP; - break; - - case KeyboardKey.BrowserSearch: - virtualKey = NativeMethods.VK_BROWSER_SEARCH; - break; - - case KeyboardKey.BrowserFavorites: - virtualKey = NativeMethods.VK_BROWSER_FAVORITES; - break; - - case KeyboardKey.BrowserHome: - virtualKey = NativeMethods.VK_BROWSER_HOME; - break; - - case KeyboardKey.VolumeMute: - virtualKey = NativeMethods.VK_VOLUME_MUTE; - break; - - case KeyboardKey.VolumeDown: - virtualKey = NativeMethods.VK_VOLUME_DOWN; - break; - - case KeyboardKey.VolumeUp: - virtualKey = NativeMethods.VK_VOLUME_UP; - break; - - case KeyboardKey.MediaNextTrack: - virtualKey = NativeMethods.VK_MEDIA_NEXT_TRACK; - break; - - case KeyboardKey.MediaPreviousTrack: - virtualKey = NativeMethods.VK_MEDIA_PREV_TRACK; - break; - - case KeyboardKey.MediaStop: - virtualKey = NativeMethods.VK_MEDIA_STOP; - break; - - case KeyboardKey.MediaPlayPause: - virtualKey = NativeMethods.VK_MEDIA_PLAY_PAUSE; - break; - - case KeyboardKey.LaunchMail: - virtualKey = NativeMethods.VK_LAUNCH_MAIL; - break; - - case KeyboardKey.SelectMedia: - virtualKey = NativeMethods.VK_LAUNCH_MEDIA_SELECT; - break; - - case KeyboardKey.LaunchApplication1: - virtualKey = NativeMethods.VK_LAUNCH_APP1; - break; - - case KeyboardKey.LaunchApplication2: - virtualKey = NativeMethods.VK_LAUNCH_APP2; - break; - - case KeyboardKey.OemSemicolon: - virtualKey = NativeMethods.VK_OEM_1; - break; - - case KeyboardKey.OemPlus: - virtualKey = NativeMethods.VK_OEM_PLUS; - break; - - case KeyboardKey.OemComma: - virtualKey = NativeMethods.VK_OEM_COMMA; - break; - - case KeyboardKey.OemMinus: - virtualKey = NativeMethods.VK_OEM_MINUS; - break; - - case KeyboardKey.OemPeriod: - virtualKey = NativeMethods.VK_OEM_PERIOD; - break; - - case KeyboardKey.OemQuestion: - virtualKey = NativeMethods.VK_OEM_2; - break; - - case KeyboardKey.OemTilde: - virtualKey = NativeMethods.VK_OEM_3; - break; - - case KeyboardKey.OemOpenBrackets: - virtualKey = NativeMethods.VK_OEM_4; - break; - - case KeyboardKey.OemPipe: - virtualKey = NativeMethods.VK_OEM_5; - break; - - case KeyboardKey.OemCloseBrackets: - virtualKey = NativeMethods.VK_OEM_6; - break; - - case KeyboardKey.OemQuotes: - virtualKey = NativeMethods.VK_OEM_7; - break; - - case KeyboardKey.OemBackslash: - virtualKey = NativeMethods.VK_OEM_102; - break; - - case KeyboardKey.ImeProcessed: - virtualKey = NativeMethods.VK_PROCESSKEY; - break; - - case KeyboardKey.OemAttn: // DbeAlphanumeric - virtualKey = NativeMethods.VK_OEM_ATTN; // VK_DBE_ALPHANUMERIC - break; - - case KeyboardKey.OemFinish: // DbeKatakana - virtualKey = NativeMethods.VK_OEM_FINISH; // VK_DBE_KATAKANA - break; - - case KeyboardKey.OemCopy: // DbeHiragana - virtualKey = NativeMethods.VK_OEM_COPY; // VK_DBE_HIRAGANA - break; - - case KeyboardKey.OemAuto: // DbeSbcsChar - virtualKey = NativeMethods.VK_OEM_AUTO; // VK_DBE_SBCSCHAR - break; - - case KeyboardKey.OemEnlw: // DbeDbcsChar - virtualKey = NativeMethods.VK_OEM_ENLW; // VK_DBE_DBCSCHAR - break; - - case KeyboardKey.OemBackTab: // DbeRoman - virtualKey = NativeMethods.VK_OEM_BACKTAB; // VK_DBE_ROMAN - break; - - case KeyboardKey.Attn: // DbeNoRoman - virtualKey = NativeMethods.VK_ATTN; // VK_DBE_NOROMAN - break; - - case KeyboardKey.CrSel: // DbeEnterWordRegisterMode - virtualKey = NativeMethods.VK_CRSEL; // VK_DBE_ENTERWORDREGISTERMODE - break; - - case KeyboardKey.ExSel: // EnterImeConfigureMode - virtualKey = NativeMethods.VK_EXSEL; // VK_DBE_ENTERIMECONFIGMODE - break; - - case KeyboardKey.EraseEof: // DbeFlushString - virtualKey = NativeMethods.VK_EREOF; // VK_DBE_FLUSHSTRING - break; - - case KeyboardKey.Play: // DbeCodeInput - virtualKey = NativeMethods.VK_PLAY; // VK_DBE_CODEINPUT - break; - - case KeyboardKey.Zoom: // DbeNoCodeInput - virtualKey = NativeMethods.VK_ZOOM; // VK_DBE_NOCODEINPUT - break; - - case KeyboardKey.NoName: // DbeDetermineString - virtualKey = NativeMethods.VK_NONAME; // VK_DBE_DETERMINESTRING - break; - - case KeyboardKey.Pa1: // DbeEnterDlgConversionMode - virtualKey = NativeMethods.VK_PA1; // VK_ENTERDLGCONVERSIONMODE - break; - - case KeyboardKey.OemClear: - virtualKey = NativeMethods.VK_OEM_CLEAR; - break; - - case KeyboardKey.DeadCharProcessed: //This is usused. It's just here for completeness. - virtualKey = 0; //There is no Win32 VKey for this. - break; - - default: - virtualKey = 0; - break; - } - - return virtualKey; - } - - [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] - private static extern short GetKeyState(int keyCode); - private static KeyStates GetKeyState(KeyboardKey key) { KeyStates state = KeyStates.None; @@ -1388,11 +169,472 @@ public static class InputUtilities return state; } - [Flags] - private enum KeyStates + /// + /// Convert a Win32 VirtualKey into our Key enum. + /// + public static KeyboardKey KeyFromVirtualKey(int virtualKey) { - None = 0, - Down = 1, - Toggled = 2 + return virtualKey switch + { + NativeMethods.VK_CANCEL => KeyboardKey.Cancel, + NativeMethods.VK_BACK => KeyboardKey.Back, + NativeMethods.VK_TAB => KeyboardKey.Tab, + NativeMethods.VK_CLEAR => KeyboardKey.Clear, + NativeMethods.VK_RETURN => KeyboardKey.Return, + NativeMethods.VK_PAUSE => KeyboardKey.Pause, + NativeMethods.VK_CAPSLOCK => KeyboardKey.CapsLock, + NativeMethods.VK_JUNJA => KeyboardKey.JunjaMode, + NativeMethods.VK_FINAL => KeyboardKey.FinalMode, + NativeMethods.VK_ESCAPE => KeyboardKey.Escape, + NativeMethods.VK_CONVERT => KeyboardKey.ImeConvert, + NativeMethods.VK_NONCONVERT => KeyboardKey.ImeNonConvert, + NativeMethods.VK_ACCEPT => KeyboardKey.ImeAccept, + NativeMethods.VK_MODECHANGE => KeyboardKey.ImeModeChange, + NativeMethods.VK_SPACE => KeyboardKey.Space, + NativeMethods.VK_PRIOR => KeyboardKey.PageUp, + NativeMethods.VK_NEXT => KeyboardKey.PageDown, + NativeMethods.VK_END => KeyboardKey.End, + NativeMethods.VK_HOME => KeyboardKey.Home, + NativeMethods.VK_LEFT => KeyboardKey.Left, + NativeMethods.VK_UP => KeyboardKey.Up, + NativeMethods.VK_RIGHT => KeyboardKey.Right, + NativeMethods.VK_DOWN => KeyboardKey.Down, + NativeMethods.VK_SELECT => KeyboardKey.Select, + NativeMethods.VK_PRINT => KeyboardKey.Print, + NativeMethods.VK_EXECUTE => KeyboardKey.Execute, + NativeMethods.VK_INSERT => KeyboardKey.Insert, + NativeMethods.VK_DELETE => KeyboardKey.Delete, + NativeMethods.VK_HELP => KeyboardKey.Help, + NativeMethods.VK_0 => KeyboardKey.D0, + NativeMethods.VK_1 => KeyboardKey.D1, + NativeMethods.VK_2 => KeyboardKey.D2, + NativeMethods.VK_3 => KeyboardKey.D3, + NativeMethods.VK_4 => KeyboardKey.D4, + NativeMethods.VK_5 => KeyboardKey.D5, + NativeMethods.VK_6 => KeyboardKey.D6, + NativeMethods.VK_7 => KeyboardKey.D7, + NativeMethods.VK_8 => KeyboardKey.D8, + NativeMethods.VK_9 => KeyboardKey.D9, + NativeMethods.VK_A => KeyboardKey.A, + NativeMethods.VK_B => KeyboardKey.B, + NativeMethods.VK_C => KeyboardKey.C, + NativeMethods.VK_D => KeyboardKey.D, + NativeMethods.VK_E => KeyboardKey.E, + NativeMethods.VK_F => KeyboardKey.F, + NativeMethods.VK_G => KeyboardKey.G, + NativeMethods.VK_H => KeyboardKey.H, + NativeMethods.VK_I => KeyboardKey.I, + NativeMethods.VK_J => KeyboardKey.J, + NativeMethods.VK_K => KeyboardKey.K, + NativeMethods.VK_L => KeyboardKey.L, + NativeMethods.VK_M => KeyboardKey.M, + NativeMethods.VK_N => KeyboardKey.N, + NativeMethods.VK_O => KeyboardKey.O, + NativeMethods.VK_P => KeyboardKey.P, + NativeMethods.VK_Q => KeyboardKey.Q, + NativeMethods.VK_R => KeyboardKey.R, + NativeMethods.VK_S => KeyboardKey.S, + NativeMethods.VK_T => KeyboardKey.T, + NativeMethods.VK_U => KeyboardKey.U, + NativeMethods.VK_V => KeyboardKey.V, + NativeMethods.VK_W => KeyboardKey.W, + NativeMethods.VK_X => KeyboardKey.X, + NativeMethods.VK_Y => KeyboardKey.Y, + NativeMethods.VK_Z => KeyboardKey.Z, + NativeMethods.VK_LWIN => KeyboardKey.LWin, + NativeMethods.VK_RWIN => KeyboardKey.RWin, + NativeMethods.VK_APPS => KeyboardKey.Apps, + NativeMethods.VK_SLEEP => KeyboardKey.Sleep, + NativeMethods.VK_NUMPAD0 => KeyboardKey.NumPad0, + NativeMethods.VK_NUMPAD1 => KeyboardKey.NumPad1, + NativeMethods.VK_NUMPAD2 => KeyboardKey.NumPad2, + NativeMethods.VK_NUMPAD3 => KeyboardKey.NumPad3, + NativeMethods.VK_NUMPAD4 => KeyboardKey.NumPad4, + NativeMethods.VK_NUMPAD5 => KeyboardKey.NumPad5, + NativeMethods.VK_NUMPAD6 => KeyboardKey.NumPad6, + NativeMethods.VK_NUMPAD7 => KeyboardKey.NumPad7, + NativeMethods.VK_NUMPAD8 => KeyboardKey.NumPad8, + NativeMethods.VK_NUMPAD9 => KeyboardKey.NumPad9, + NativeMethods.VK_MULTIPLY => KeyboardKey.Multiply, + NativeMethods.VK_ADD => KeyboardKey.Add, + NativeMethods.VK_SEPARATOR => KeyboardKey.Separator, + NativeMethods.VK_SUBTRACT => KeyboardKey.Subtract, + NativeMethods.VK_DECIMAL => KeyboardKey.Decimal, + NativeMethods.VK_DIVIDE => KeyboardKey.Divide, + NativeMethods.VK_F1 => KeyboardKey.F1, + NativeMethods.VK_F2 => KeyboardKey.F2, + NativeMethods.VK_F3 => KeyboardKey.F3, + NativeMethods.VK_F4 => KeyboardKey.F4, + NativeMethods.VK_F5 => KeyboardKey.F5, + NativeMethods.VK_F6 => KeyboardKey.F6, + NativeMethods.VK_F7 => KeyboardKey.F7, + NativeMethods.VK_F8 => KeyboardKey.F8, + NativeMethods.VK_F9 => KeyboardKey.F9, + NativeMethods.VK_F10 => KeyboardKey.F10, + NativeMethods.VK_F11 => KeyboardKey.F11, + NativeMethods.VK_F12 => KeyboardKey.F12, + NativeMethods.VK_F13 => KeyboardKey.F13, + NativeMethods.VK_F14 => KeyboardKey.F14, + NativeMethods.VK_F15 => KeyboardKey.F15, + NativeMethods.VK_F16 => KeyboardKey.F16, + NativeMethods.VK_F17 => KeyboardKey.F17, + NativeMethods.VK_F18 => KeyboardKey.F18, + NativeMethods.VK_F19 => KeyboardKey.F19, + NativeMethods.VK_F20 => KeyboardKey.F20, + NativeMethods.VK_F21 => KeyboardKey.F21, + NativeMethods.VK_F22 => KeyboardKey.F22, + NativeMethods.VK_F23 => KeyboardKey.F23, + NativeMethods.VK_F24 => KeyboardKey.F24, + NativeMethods.VK_NUMLOCK => KeyboardKey.NumLock, + NativeMethods.VK_SCROLL => KeyboardKey.Scroll, + NativeMethods.VK_SHIFT => KeyboardKey.LeftShift, + NativeMethods.VK_LSHIFT => KeyboardKey.LeftShift, + NativeMethods.VK_RSHIFT => KeyboardKey.RightShift, + NativeMethods.VK_CONTROL => KeyboardKey.LeftCtrl, + NativeMethods.VK_LCONTROL => KeyboardKey.LeftCtrl, + NativeMethods.VK_RCONTROL => KeyboardKey.RightCtrl, + NativeMethods.VK_MENU => KeyboardKey.LeftAlt, + NativeMethods.VK_LMENU => KeyboardKey.LeftAlt, + NativeMethods.VK_RMENU => KeyboardKey.RightAlt, + NativeMethods.VK_BROWSER_BACK => KeyboardKey.BrowserBack, + NativeMethods.VK_BROWSER_FORWARD => KeyboardKey.BrowserForward, + NativeMethods.VK_BROWSER_REFRESH => KeyboardKey.BrowserRefresh, + NativeMethods.VK_BROWSER_STOP => KeyboardKey.BrowserStop, + NativeMethods.VK_BROWSER_SEARCH => KeyboardKey.BrowserSearch, + NativeMethods.VK_BROWSER_FAVORITES => KeyboardKey.BrowserFavorites, + NativeMethods.VK_BROWSER_HOME => KeyboardKey.BrowserHome, + NativeMethods.VK_VOLUME_MUTE => KeyboardKey.VolumeMute, + NativeMethods.VK_VOLUME_DOWN => KeyboardKey.VolumeDown, + NativeMethods.VK_VOLUME_UP => KeyboardKey.VolumeUp, + NativeMethods.VK_MEDIA_NEXT_TRACK => KeyboardKey.MediaNextTrack, + NativeMethods.VK_MEDIA_PREV_TRACK => KeyboardKey.MediaPreviousTrack, + NativeMethods.VK_MEDIA_STOP => KeyboardKey.MediaStop, + NativeMethods.VK_MEDIA_PLAY_PAUSE => KeyboardKey.MediaPlayPause, + NativeMethods.VK_LAUNCH_MAIL => KeyboardKey.LaunchMail, + NativeMethods.VK_LAUNCH_MEDIA_SELECT => KeyboardKey.SelectMedia, + NativeMethods.VK_LAUNCH_APP1 => KeyboardKey.LaunchApplication1, + NativeMethods.VK_LAUNCH_APP2 => KeyboardKey.LaunchApplication2, + NativeMethods.VK_OEM_1 => KeyboardKey.OemSemicolon, + NativeMethods.VK_OEM_PLUS => KeyboardKey.OemPlus, + NativeMethods.VK_OEM_COMMA => KeyboardKey.OemComma, + NativeMethods.VK_OEM_MINUS => KeyboardKey.OemMinus, + NativeMethods.VK_OEM_PERIOD => KeyboardKey.OemPeriod, + NativeMethods.VK_OEM_2 => KeyboardKey.OemQuestion, + NativeMethods.VK_OEM_3 => KeyboardKey.OemTilde, + NativeMethods.VK_OEM_4 => KeyboardKey.OemOpenBrackets, + NativeMethods.VK_OEM_5 => KeyboardKey.OemPipe, + NativeMethods.VK_OEM_6 => KeyboardKey.OemCloseBrackets, + NativeMethods.VK_OEM_7 => KeyboardKey.OemQuotes, + NativeMethods.VK_OEM_102 => KeyboardKey.OemBackslash, + NativeMethods.VK_PROCESSKEY => KeyboardKey.ImeProcessed, + NativeMethods.VK_OEM_ATTN => KeyboardKey.Attn, + NativeMethods.VK_OEM_FINISH => KeyboardKey.OemFinish, + NativeMethods.VK_OEM_COPY => KeyboardKey.OemCopy, + NativeMethods.VK_OEM_AUTO => KeyboardKey.OemAuto, + NativeMethods.VK_OEM_ENLW => KeyboardKey.OemEnlw, + NativeMethods.VK_OEM_BACKTAB => KeyboardKey.OemBackTab, + NativeMethods.VK_ATTN => KeyboardKey.Attn, + NativeMethods.VK_CRSEL => KeyboardKey.CrSel, + NativeMethods.VK_EXSEL => KeyboardKey.ExSel, + NativeMethods.VK_EREOF => KeyboardKey.EraseEof, + NativeMethods.VK_PLAY => KeyboardKey.Play, + NativeMethods.VK_ZOOM => KeyboardKey.Zoom, + NativeMethods.VK_NONAME => KeyboardKey.NoName, + NativeMethods.VK_PA1 => KeyboardKey.Pa1, + NativeMethods.VK_OEM_CLEAR => KeyboardKey.OemClear, + _ => KeyboardKey.None + }; + } + + /// + /// Convert our Key enum into a Win32 VirtualKeyboardKey. + /// + public static int VirtualKeyFromKey(KeyboardKey key) + { + return key switch + { + KeyboardKey.Cancel => NativeMethods.VK_CANCEL, + KeyboardKey.Back => NativeMethods.VK_BACK, + KeyboardKey.Tab => NativeMethods.VK_TAB, + KeyboardKey.Clear => NativeMethods.VK_CLEAR, + KeyboardKey.Return => NativeMethods.VK_RETURN, + KeyboardKey.Pause => NativeMethods.VK_PAUSE, + KeyboardKey.CapsLock => NativeMethods.VK_CAPITAL, + KeyboardKey.JunjaMode => NativeMethods.VK_JUNJA, + KeyboardKey.FinalMode => NativeMethods.VK_FINAL, + KeyboardKey.Escape => NativeMethods.VK_ESCAPE, + KeyboardKey.ImeConvert => NativeMethods.VK_CONVERT, + KeyboardKey.ImeNonConvert => NativeMethods.VK_NONCONVERT, + KeyboardKey.ImeAccept => NativeMethods.VK_ACCEPT, + KeyboardKey.ImeModeChange => NativeMethods.VK_MODECHANGE, + KeyboardKey.Space => NativeMethods.VK_SPACE, + KeyboardKey.Prior => NativeMethods.VK_PRIOR, + KeyboardKey.Next => NativeMethods.VK_NEXT, + KeyboardKey.End => NativeMethods.VK_END, + KeyboardKey.Home => NativeMethods.VK_HOME, + KeyboardKey.Left => NativeMethods.VK_LEFT, + KeyboardKey.Up => NativeMethods.VK_UP, + KeyboardKey.Right => NativeMethods.VK_RIGHT, + KeyboardKey.Down => NativeMethods.VK_DOWN, + KeyboardKey.Select => NativeMethods.VK_SELECT, + KeyboardKey.Print => NativeMethods.VK_PRINT, + KeyboardKey.Execute => NativeMethods.VK_EXECUTE, + KeyboardKey.Insert => NativeMethods.VK_INSERT, + KeyboardKey.Delete => NativeMethods.VK_DELETE, + KeyboardKey.Help => NativeMethods.VK_HELP, + KeyboardKey.D0 => NativeMethods.VK_0, + KeyboardKey.D1 => NativeMethods.VK_1, + KeyboardKey.D2 => NativeMethods.VK_2, + KeyboardKey.D3 => NativeMethods.VK_3, + KeyboardKey.D4 => NativeMethods.VK_4, + KeyboardKey.D5 => NativeMethods.VK_5, + KeyboardKey.D6 => NativeMethods.VK_6, + KeyboardKey.D7 => NativeMethods.VK_7, + KeyboardKey.D8 => NativeMethods.VK_8, + KeyboardKey.D9 => NativeMethods.VK_9, + KeyboardKey.A => NativeMethods.VK_A, + KeyboardKey.B => NativeMethods.VK_B, + KeyboardKey.C => NativeMethods.VK_C, + KeyboardKey.D => NativeMethods.VK_D, + KeyboardKey.E => NativeMethods.VK_E, + KeyboardKey.F => NativeMethods.VK_F, + KeyboardKey.G => NativeMethods.VK_G, + KeyboardKey.H => NativeMethods.VK_H, + KeyboardKey.I => NativeMethods.VK_I, + KeyboardKey.J => NativeMethods.VK_J, + KeyboardKey.K => NativeMethods.VK_K, + KeyboardKey.L => NativeMethods.VK_L, + KeyboardKey.M => NativeMethods.VK_M, + KeyboardKey.N => NativeMethods.VK_N, + KeyboardKey.O => NativeMethods.VK_O, + KeyboardKey.P => NativeMethods.VK_P, + KeyboardKey.Q => NativeMethods.VK_Q, + KeyboardKey.R => NativeMethods.VK_R, + KeyboardKey.S => NativeMethods.VK_S, + KeyboardKey.T => NativeMethods.VK_T, + KeyboardKey.U => NativeMethods.VK_U, + KeyboardKey.V => NativeMethods.VK_V, + KeyboardKey.W => NativeMethods.VK_W, + KeyboardKey.X => NativeMethods.VK_X, + KeyboardKey.Y => NativeMethods.VK_Y, + KeyboardKey.Z => NativeMethods.VK_Z, + KeyboardKey.LWin => NativeMethods.VK_LWIN, + KeyboardKey.RWin => NativeMethods.VK_RWIN, + KeyboardKey.Apps => NativeMethods.VK_APPS, + KeyboardKey.Sleep => NativeMethods.VK_SLEEP, + KeyboardKey.NumPad0 => NativeMethods.VK_NUMPAD0, + KeyboardKey.NumPad1 => NativeMethods.VK_NUMPAD1, + KeyboardKey.NumPad2 => NativeMethods.VK_NUMPAD2, + KeyboardKey.NumPad3 => NativeMethods.VK_NUMPAD3, + KeyboardKey.NumPad4 => NativeMethods.VK_NUMPAD4, + KeyboardKey.NumPad5 => NativeMethods.VK_NUMPAD5, + KeyboardKey.NumPad6 => NativeMethods.VK_NUMPAD6, + KeyboardKey.NumPad7 => NativeMethods.VK_NUMPAD7, + KeyboardKey.NumPad8 => NativeMethods.VK_NUMPAD8, + KeyboardKey.NumPad9 => NativeMethods.VK_NUMPAD9, + KeyboardKey.Multiply => NativeMethods.VK_MULTIPLY, + KeyboardKey.Add => NativeMethods.VK_ADD, + KeyboardKey.Separator => NativeMethods.VK_SEPARATOR, + KeyboardKey.Subtract => NativeMethods.VK_SUBTRACT, + KeyboardKey.Decimal => NativeMethods.VK_DECIMAL, + KeyboardKey.Divide => NativeMethods.VK_DIVIDE, + KeyboardKey.F1 => NativeMethods.VK_F1, + KeyboardKey.F2 => NativeMethods.VK_F2, + KeyboardKey.F3 => NativeMethods.VK_F3, + KeyboardKey.F4 => NativeMethods.VK_F4, + KeyboardKey.F5 => NativeMethods.VK_F5, + KeyboardKey.F6 => NativeMethods.VK_F6, + KeyboardKey.F7 => NativeMethods.VK_F7, + KeyboardKey.F8 => NativeMethods.VK_F8, + KeyboardKey.F9 => NativeMethods.VK_F9, + KeyboardKey.F10 => NativeMethods.VK_F10, + KeyboardKey.F11 => NativeMethods.VK_F11, + KeyboardKey.F12 => NativeMethods.VK_F12, + KeyboardKey.F13 => NativeMethods.VK_F13, + KeyboardKey.F14 => NativeMethods.VK_F14, + KeyboardKey.F15 => NativeMethods.VK_F15, + KeyboardKey.F16 => NativeMethods.VK_F16, + KeyboardKey.F17 => NativeMethods.VK_F17, + KeyboardKey.F18 => NativeMethods.VK_F18, + KeyboardKey.F19 => NativeMethods.VK_F19, + KeyboardKey.F20 => NativeMethods.VK_F20, + KeyboardKey.F21 => NativeMethods.VK_F21, + KeyboardKey.F22 => NativeMethods.VK_F22, + KeyboardKey.F23 => NativeMethods.VK_F23, + KeyboardKey.F24 => NativeMethods.VK_F24, + KeyboardKey.NumLock => NativeMethods.VK_NUMLOCK, + KeyboardKey.Scroll => NativeMethods.VK_SCROLL, + KeyboardKey.LeftShift => NativeMethods.VK_LSHIFT, + KeyboardKey.RightShift => NativeMethods.VK_RSHIFT, + KeyboardKey.LeftCtrl => NativeMethods.VK_LCONTROL, + KeyboardKey.RightCtrl => NativeMethods.VK_RCONTROL, + KeyboardKey.LeftAlt => NativeMethods.VK_LMENU, + KeyboardKey.RightAlt => NativeMethods.VK_RMENU, + KeyboardKey.BrowserBack => NativeMethods.VK_BROWSER_BACK, + KeyboardKey.BrowserForward => NativeMethods.VK_BROWSER_FORWARD, + KeyboardKey.BrowserRefresh => NativeMethods.VK_BROWSER_REFRESH, + KeyboardKey.BrowserStop => NativeMethods.VK_BROWSER_STOP, + KeyboardKey.BrowserSearch => NativeMethods.VK_BROWSER_SEARCH, + KeyboardKey.BrowserFavorites => NativeMethods.VK_BROWSER_FAVORITES, + KeyboardKey.BrowserHome => NativeMethods.VK_BROWSER_HOME, + KeyboardKey.VolumeMute => NativeMethods.VK_VOLUME_MUTE, + KeyboardKey.VolumeDown => NativeMethods.VK_VOLUME_DOWN, + KeyboardKey.VolumeUp => NativeMethods.VK_VOLUME_UP, + KeyboardKey.MediaNextTrack => NativeMethods.VK_MEDIA_NEXT_TRACK, + KeyboardKey.MediaPreviousTrack => NativeMethods.VK_MEDIA_PREV_TRACK, + KeyboardKey.MediaStop => NativeMethods.VK_MEDIA_STOP, + KeyboardKey.MediaPlayPause => NativeMethods.VK_MEDIA_PLAY_PAUSE, + KeyboardKey.LaunchMail => NativeMethods.VK_LAUNCH_MAIL, + KeyboardKey.SelectMedia => NativeMethods.VK_LAUNCH_MEDIA_SELECT, + KeyboardKey.LaunchApplication1 => NativeMethods.VK_LAUNCH_APP1, + KeyboardKey.LaunchApplication2 => NativeMethods.VK_LAUNCH_APP2, + KeyboardKey.OemSemicolon => NativeMethods.VK_OEM_1, + KeyboardKey.OemPlus => NativeMethods.VK_OEM_PLUS, + KeyboardKey.OemComma => NativeMethods.VK_OEM_COMMA, + KeyboardKey.OemMinus => NativeMethods.VK_OEM_MINUS, + KeyboardKey.OemPeriod => NativeMethods.VK_OEM_PERIOD, + KeyboardKey.OemQuestion => NativeMethods.VK_OEM_2, + KeyboardKey.OemTilde => NativeMethods.VK_OEM_3, + KeyboardKey.OemOpenBrackets => NativeMethods.VK_OEM_4, + KeyboardKey.OemPipe => NativeMethods.VK_OEM_5, + KeyboardKey.OemCloseBrackets => NativeMethods.VK_OEM_6, + KeyboardKey.OemQuotes => NativeMethods.VK_OEM_7, + KeyboardKey.OemBackslash => NativeMethods.VK_OEM_102, + KeyboardKey.ImeProcessed => NativeMethods.VK_PROCESSKEY, + KeyboardKey.OemAttn => NativeMethods.VK_ATTN, + KeyboardKey.OemFinish => NativeMethods.VK_OEM_FINISH, + KeyboardKey.OemCopy => NativeMethods.VK_OEM_COPY, + KeyboardKey.OemAuto => NativeMethods.VK_OEM_AUTO, + KeyboardKey.OemEnlw => NativeMethods.VK_OEM_ENLW, + KeyboardKey.OemBackTab => NativeMethods.VK_OEM_BACKTAB, + KeyboardKey.Attn => NativeMethods.VK_ATTN, + KeyboardKey.CrSel => NativeMethods.VK_CRSEL, + KeyboardKey.ExSel => NativeMethods.VK_EXSEL, + KeyboardKey.EraseEof => NativeMethods.VK_EREOF, + KeyboardKey.Play => NativeMethods.VK_PLAY, + KeyboardKey.Zoom => NativeMethods.VK_ZOOM, + KeyboardKey.NoName => NativeMethods.VK_NONAME, + KeyboardKey.Pa1 => NativeMethods.VK_PA1, + KeyboardKey.OemClear => NativeMethods.VK_OEM_CLEAR, + KeyboardKey.DeadCharProcessed => 0, + _ => 0 + }; + } + + /// + /// Convert a scan code to a key, following US keyboard layout. + /// This is useful because we don't care about the keyboard layout, just the key location for effects. + /// + public static KeyboardKey KeyFromScanCode(uint scanCode) + { + return scanCode switch + { + 0x01 => KeyboardKey.Escape, + 0x02 => KeyboardKey.D1, + 0x03 => KeyboardKey.D2, + 0x04 => KeyboardKey.D3, + 0x05 => KeyboardKey.D4, + 0x06 => KeyboardKey.D5, + 0x07 => KeyboardKey.D6, + 0x08 => KeyboardKey.D7, + 0x09 => KeyboardKey.D8, + 0x0A => KeyboardKey.D9, + 0x0B => KeyboardKey.D0, + 0x0C => KeyboardKey.OemMinus, + 0x0D => KeyboardKey.OemPlus, + 0x0E => KeyboardKey.Back, + 0x0F => KeyboardKey.Tab, + 0x10 => KeyboardKey.Q, + 0x11 => KeyboardKey.W, + 0x12 => KeyboardKey.E, + 0x13 => KeyboardKey.R, + 0x14 => KeyboardKey.T, + 0x15 => KeyboardKey.Y, + 0x16 => KeyboardKey.U, + 0x17 => KeyboardKey.I, + 0x18 => KeyboardKey.O, + 0x19 => KeyboardKey.P, + 0x1A => KeyboardKey.OemOpenBrackets, + 0x1B => KeyboardKey.OemCloseBrackets, + 0x1C => KeyboardKey.Enter, + 0x1D => KeyboardKey.LeftCtrl, + 0x1E => KeyboardKey.A, + 0x1F => KeyboardKey.S, + 0x20 => KeyboardKey.D, + 0x21 => KeyboardKey.F, + 0x22 => KeyboardKey.G, + 0x23 => KeyboardKey.H, + 0x24 => KeyboardKey.J, + 0x25 => KeyboardKey.K, + 0x26 => KeyboardKey.L, + 0x27 => KeyboardKey.OemSemicolon, + 0x28 => KeyboardKey.OemQuotes, + 0x29 => KeyboardKey.OemTilde, + 0x2A => KeyboardKey.LeftShift, + 0x2B => KeyboardKey.OemPipe, + 0x2C => KeyboardKey.Z, + 0x2D => KeyboardKey.X, + 0x2E => KeyboardKey.C, + 0x2F => KeyboardKey.V, + 0x30 => KeyboardKey.B, + 0x31 => KeyboardKey.N, + 0x32 => KeyboardKey.M, + 0x33 => KeyboardKey.OemComma, + 0x34 => KeyboardKey.OemPeriod, + 0x35 => KeyboardKey.OemQuestion, + 0x36 => KeyboardKey.RightShift, + 0x37 => KeyboardKey.PrintScreen, + 0x38 => KeyboardKey.LeftAlt, + 0x39 => KeyboardKey.Space, + 0x3A => KeyboardKey.CapsLock, + 0x3B => KeyboardKey.F1, + 0x3C => KeyboardKey.F2, + 0x3D => KeyboardKey.F3, + 0x3E => KeyboardKey.F4, + 0x3F => KeyboardKey.F5, + 0x40 => KeyboardKey.F6, + 0x41 => KeyboardKey.F7, + 0x42 => KeyboardKey.F8, + 0x43 => KeyboardKey.F9, + 0x44 => KeyboardKey.F10, + 0x45 => KeyboardKey.Pause, + 0x46 => KeyboardKey.Scroll, + 0x47 => KeyboardKey.NumPad7, + 0x48 => KeyboardKey.NumPad8, + 0x49 => KeyboardKey.NumPad9, + 0x4A => KeyboardKey.Subtract, + 0x4B => KeyboardKey.NumPad4, + 0x4C => KeyboardKey.NumPad5, + 0x4D => KeyboardKey.NumPad6, + 0x4E => KeyboardKey.Add, + 0x4F => KeyboardKey.NumPad1, + 0x50 => KeyboardKey.NumPad2, + 0x51 => KeyboardKey.NumPad3, + 0x52 => KeyboardKey.NumPad0, + 0x53 => KeyboardKey.Decimal, + 0x56 => KeyboardKey.OemBackslash, + 0x57 => KeyboardKey.F11, + 0x58 => KeyboardKey.F12, + 0x5C => KeyboardKey.RWin, + 0x64 => KeyboardKey.F13, + 0x65 => KeyboardKey.F14, + 0x66 => KeyboardKey.F15, + //0x70 => KeyboardKey.kana, + 0x73 => KeyboardKey.AbntC1, + //0x79 => KeyboardKey.Convert, + //0x7B => KeyboardKey.NoConvert, + //0x7D => KeyboardKey.Yen, + 0x7E => KeyboardKey.AbntC2, + // 0x8D => KeyboardKey.NumPadEquals, + // 0x90 => KeyboardKey.PreviousTrack, + // 0x91 => KeyboardKey.At, + // 0x92 => KeyboardKey.Colon, + // 0x93 => KeyboardKey.Underline, + // 0x94 => KeyboardKey.Kanji, + // 0x95 => KeyboardKey.Stop, + // 0x96 => KeyboardKey.Ax, + 0x145 => KeyboardKey.NumLock, + _ => KeyboardKey.None + }; } } \ No newline at end of file