From 2ad45edef5cf00b81a96228a4603552772e5481f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Sun, 14 Mar 2021 17:59:13 +0100 Subject: [PATCH] Improved Windows keyboard input - added handling of syskey-messages (alt-Key now generates Key events) - right and left variants of keys now generate seperate events (e.g. left shift and right shift are seperate keys now instead of simply being "shift") - added method to get the localized name of a Key --- GlitchyEngine/src/Key.bf | 1 + .../src/Platform/Windows/WindowsKey.bf | 48 +++++++++++++++++++ .../src/Platform/Windows/WindowsWindow.bf | 35 ++++++++++++-- 3 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 GlitchyEngine/src/Platform/Windows/WindowsKey.bf diff --git a/GlitchyEngine/src/Key.bf b/GlitchyEngine/src/Key.bf index acee36b..f975b00 100644 --- a/GlitchyEngine/src/Key.bf +++ b/GlitchyEngine/src/Key.bf @@ -68,6 +68,7 @@ namespace GlitchyEngine case Z = 90; // Z key case LeftSuper = 91; // Left Windows key(Microsoft® Natural® keyboard) case RightSuper = 92; // Right Windows key(Natural keyboard) + case ContextMenu = 93; // Context Menu key (VK_APPS) case Numpad0 = 96; // Numeric keypad 0 key case Numpad1 = 97; // Numeric keypad 1 key case Numpad2 = 98; // Numeric keypad 2 key diff --git a/GlitchyEngine/src/Platform/Windows/WindowsKey.bf b/GlitchyEngine/src/Platform/Windows/WindowsKey.bf new file mode 100644 index 0000000..54e546d --- /dev/null +++ b/GlitchyEngine/src/Platform/Windows/WindowsKey.bf @@ -0,0 +1,48 @@ +using System; +using DirectX.Windows.Winuser; +using DirectX.Common; + +namespace GlitchyEngine +{ + extension Key + { + // Todo: make overriding method + public void GetKeyName(String strBuffer) + { + var scanCode = MapVirtualKeyW((.)this, MAPVK_VK_TO_VSC); + + char16[128] name = ?; + int result; + + switch (this) + { + case .Left, .Up, .Right, .Down, .RightControl, .RightAlt, + .LeftSuper, .RightSuper, ContextMenu, + .Prior, .Next, .End, .Home, .Insert, .Delete, .Divide, .Numlock: + // set extended flag + scanCode |= 0x0100; + fallthrough; + default: + result = GetKeyNameTextW((.)(scanCode << 16), &name, name.Count); + } + + if(result == 0) + { + HResult error = (.)DirectX.Windows.Kernel32.GetLastError(); + + Log.EngineLogger.Error($"Failed to convert keycode {(int)this}({this}) to string. WinAPI error({(int)error}): {error}"); + + return; + } + + strBuffer.Append(Span(&name, result)); + } + + /// Converts the given windows specific virtual key code to a GlitchyEngine Key. + [Inline] + internal static Key FromWindowsKeyCode(int32 vKeyCode) + { + return (.)vKeyCode; + } + } +} diff --git a/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf b/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf index 50f73f3..77cd3b8 100644 --- a/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf +++ b/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf @@ -11,6 +11,8 @@ using GlitchyEngine.Math; using GlitchyEngine.Renderer; using static System.Windows; +using internal GlitchyEngine; + namespace GlitchyEngine { /// The windows specific Window implementation @@ -338,14 +340,16 @@ namespace GlitchyEngine //// Keyboard input //// - case WM_KEYDOWN: + case WM_KEYDOWN, WM_SYSKEYDOWN: { - var event = scope KeyPressedEvent((Key)wParam, (int32)lParam & 0xFFFF); + Key key = WindowMessageToKey(wParam, lParam); + var event = scope KeyPressedEvent(key, (int32)lParam & 0xFFFF); window._eventCallback(event); } - case WM_KEYUP: + case WM_KEYUP, WM_SYSKEYUP: { - var event = scope KeyReleasedEvent((Key)wParam); + Key key = WindowMessageToKey(wParam, lParam); + var event = scope KeyReleasedEvent(key); window._eventCallback(event); } @@ -472,6 +476,29 @@ namespace GlitchyEngine return DefWindowProcW(hwnd, uMsg, wParam, lParam); } + /** + * Converts the wParam and lParam of a WM_KEYDOWN or WM_KEYUP message to the corresponding engine keycode. + */ + static Key WindowMessageToKey(WPARAM wParam, LPARAM lParam) + { + Key key = Key.FromWindowsKeyCode((.)wParam); + + var scancode = (lParam & 0x00ff0000) >> 16; + bool isExtended = (lParam & 0x01000000) > 0; + + switch(key) + { + case .Shift: + return Key.FromWindowsKeyCode((.)MapVirtualKeyW((.)scancode, MAPVK_VSC_TO_VK_EX)); + case .Control: + return isExtended ? .RightControl : .LeftControl; + case .Alt: + return isExtended ? .RightAlt : .LeftAlt; + default: + return key; + } + } + public override void Update() { Message message = .();