我为WPF编写了一个热键控件,希望向用户显示友好的名称。为此,我使用GetKeyNameText
。
然而,例如,当使用Key.MediaNextTrack
作为输入时,GetKeyNameText
返回P
,这看起来似乎是错误的。有人能帮助我获得这些深奥的键的正确名称吗?
我的代码执行以下操作:
1.调用KeyInterop.VirtualKeyFromKey
以获取Win32虚拟密钥
1.通过调用MapVirtualKey
将虚拟键翻译为扫码
1.呼叫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);
}
}
2条答案
按热度按时间xsuvu9jc1#
这些媒体键的名称不包含在键盘布局dll中,因此无法通过Win32 API获得。
下面是我用C++编写的
GetKeyNameTextW
API的 Package 器:在RawInput API中,您可以通过这样的代码获得完整的扫描代码:
yfjy0ee72#
1.虚拟关键点不包含修改器,因此无需执行
&ffff
。