Я написал элемент управления горячими клавишами для WPF и хочу отобразить дружественное имя для пользователя. Для этого я использую GetKeyNameText
.Использование GetKeyNameText со специальными ключами
Однако, например, при использовании Key.MediaNextTrack
в качестве входных данных GetKeyNameText
возвращает P
, что, по-видимому, выглядит неправильно. Может ли кто-нибудь помочь мне получить правильное имя для таких эзотерических ключей?
Мой код делает следующее:
- вызов
KeyInterop.VirtualKeyFromKey
получить Win32 виртуальный ключ - Перевести виртуальную клавишу для сканирования кода, вызвав
MapVirtualKey
- Вызов
GetKeyNameText
Полный код это (вам необходимо обратиться к WindowsBase):
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Input;
namespace ConsoleApplication1 {
class Program {
static void Main() {
var key = Key.MediaNextTrack;
var virtualKeyFromKey = KeyInterop.VirtualKeyFromKey(key);
var displayString = GetLocalizedKeyStringUnsafe(virtualKeyFromKey);
Console.WriteLine($"{key}: {displayString}");
}
private static string GetLocalizedKeyStringUnsafe(int key) {
// strip any modifier keys
long keyCode = key & 0xffff;
var sb = new StringBuilder(256);
long scanCode = MapVirtualKey((uint) keyCode, MAPVK_VK_TO_VSC);
// shift the scancode to the high word
scanCode = (scanCode << 16); // | (1 << 24);
if (keyCode == 45 ||
keyCode == 46 ||
keyCode == 144 ||
(33 <= keyCode && keyCode <= 40)) {
// add the extended key flag
scanCode |= 0x1000000;
}
GetKeyNameText((int) scanCode, sb, 256);
return sb.ToString();
}
private const uint MAPVK_VK_TO_VSC = 0x00;
[DllImport("user32.dll")]
private static extern int MapVirtualKey(uint uCode, uint uMapType);
[DllImport("user32.dll", EntryPoint = "GetKeyNameTextW", CharSet = CharSet.Unicode)]
private static extern int GetKeyNameText(int lParam, [MarshalAs(UnmanagedType.LPWStr), Out] StringBuilder str, int size);
}
}