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
This commit is contained in:
Simon Lübeß
2021-03-14 17:59:13 +01:00
parent cfff2cb738
commit 2ad45edef5
3 changed files with 80 additions and 4 deletions
+1
View File
@@ -68,6 +68,7 @@ namespace GlitchyEngine
case Z = 90; // Z key case Z = 90; // Z key
case LeftSuper = 91; // Left Windows key(Microsoft® Natural® keyboard) case LeftSuper = 91; // Left Windows key(Microsoft® Natural® keyboard)
case RightSuper = 92; // Right Windows key(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 Numpad0 = 96; // Numeric keypad 0 key
case Numpad1 = 97; // Numeric keypad 1 key case Numpad1 = 97; // Numeric keypad 1 key
case Numpad2 = 98; // Numeric keypad 2 key case Numpad2 = 98; // Numeric keypad 2 key
@@ -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<char16>(&name, result));
}
/// Converts the given windows specific virtual key code to a GlitchyEngine Key.
[Inline]
internal static Key FromWindowsKeyCode(int32 vKeyCode)
{
return (.)vKeyCode;
}
}
}
@@ -11,6 +11,8 @@ using GlitchyEngine.Math;
using GlitchyEngine.Renderer; using GlitchyEngine.Renderer;
using static System.Windows; using static System.Windows;
using internal GlitchyEngine;
namespace GlitchyEngine namespace GlitchyEngine
{ {
/// The windows specific Window implementation /// The windows specific Window implementation
@@ -338,14 +340,16 @@ namespace GlitchyEngine
//// Keyboard input //// 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); 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); window._eventCallback(event);
} }
@@ -472,6 +476,29 @@ namespace GlitchyEngine
return DefWindowProcW(hwnd, uMsg, wParam, lParam); 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() public override void Update()
{ {
Message message = .(); Message message = .();