/// <summary> /// Updates key names according to the current keyboard layout. /// </summary> private void PopulateKeyNames() { var state = new byte[256]; // Initialize the key names array. _keyNames = new string[_scanCodes.Length]; for (var key = (int)Key.Space; key < (int)Key.Last; key++) { uint vk; int scanCode = _scanCodes[key]; if (scanCode == -1) { continue; } if (key >= (int)Key.Kp0 && key <= (int)Key.KpAdd) { uint[] vks = { (uint)VirtualKey.NUMPAD0, (uint)VirtualKey.NUMPAD1, (uint)VirtualKey.NUMPAD2, (uint)VirtualKey.NUMPAD3, (uint)VirtualKey.NUMPAD4, (uint)VirtualKey.NUMPAD5, (uint)VirtualKey.NUMPAD6, (uint)VirtualKey.NUMPAD7, (uint)VirtualKey.NUMPAD8, (uint)VirtualKey.NUMPAD9, (uint)VirtualKey.DECIMAL, (uint)VirtualKey.DIVIDE, (uint)VirtualKey.MULTIPLY, (uint)VirtualKey.SUBTRACT, (uint)VirtualKey.ADD }; vk = vks[key - (int)Key.Kp0]; } else { vk = User32.MapVirtualKey((uint)scanCode, VirtualKeyMapType.MAPVK_VSC_TO_VK); } var chars = new StringBuilder(16); int length = User32.ToUnicode(vk, (uint)scanCode, state, chars, chars.Capacity, 0); if (length == -1) { length = User32.ToUnicode(vk, (uint)scanCode, state, chars, chars.Capacity, 0); } if (length < 1) { continue; } var keyName = new char[5]; Kernel32.WideCharToMultiByte(CodePage.CpUtf8, 0, chars, 1, keyName, keyName.Length, IntPtr.Zero, out bool _); _keyNames[key] = NativeHelpers.StringFromNullTerminated(keyName); } }