有没有一种程序化的方法可以找出计算机使用的键盘类型(即按键位置在哪里,以及哪些额外键位于哪些位置)?
如果键盘非常不标准,则允许存在一些小错误,但通常情况下,重点是构建一个类似于屏幕键盘的应用程序,可以在屏幕上动态绘制键盘布局,并且高度精确。
有没有一种程序化的方法可以找出计算机使用的键盘类型(即按键位置在哪里,以及哪些额外键位于哪些位置)?
如果键盘非常不标准,则允许存在一些小错误,但通常情况下,重点是构建一个类似于屏幕键盘的应用程序,可以在屏幕上动态绘制键盘布局,并且高度精确。
MapVirtualKeyEx()
函数允许您在扫描码、虚拟键和字符之间进行转换。它还应该能够告诉您某个键是否不存在。GetKeyboardLayout()
一起使用,可以在任何时候告诉您哪个键盘处于活动状态(不同运行应用程序的键盘布局可能不同),这应该可以帮助您构建一个相当精确的键盘映射。MSDN的键盘输入部分
。键盘无法告诉Windows它的物理布局。在屏幕键盘osk.exe的Windows版本中很容易看到这一点。它似乎能够猜测机器的形态因素(笔记本电脑与台式机),但在我的笔记本电脑上,它的布局与键盘不匹配。
使用osk.exe布局作为模板,这样就不会有人抱怨你的布局不匹配。
2023年更新
在Windows 10中新增了一个名为KEYBOARD_EXTENDED_ATTRIBUTES的结构体和IOCTL_KEYBOARD_QUERY_EXTENDED_ATTRIBUTES IOCTL,可以返回额外的键盘信息。
请参阅最新的HID使用表规范中的"15.18描述性控制"。这些内容来自于2013年采纳的HID使用表审查请求42:消费者页面键盘辅助控制。
bool QueryInfo(const ScopedHandle& interfaceHandle)
{
// https://docs.microsoft.com/windows/win32/api/ntddkbd/ns-ntddkbd-keyboard_extended_attributes
KEYBOARD_EXTENDED_ATTRIBUTES extended_attributes{ KEYBOARD_EXTENDED_ATTRIBUTES_STRUCT_VERSION_1 };
DWORD len = 0;
if (!DeviceIoControl(interfaceHandle.get(), IOCTL_KEYBOARD_QUERY_EXTENDED_ATTRIBUTES, nullptr, 0, &extended_attributes, sizeof(extended_attributes), &len, nullptr))
return false;
DCHECK_EQ(len, sizeof(extended_attributes));
FormFactor = extended_attributes.FormFactor;
KeyType = extended_attributes.IETFLanguageTagIndex;
PhysicalLayout = extended_attributes.PhysicalLayout;
VendorSpecificPhysicalLayout = extended_attributes.VendorSpecificPhysicalLayout;
IETFLanguageTagIndex = extended_attributes.IETFLanguageTagIndex;
ImplementedInputAssistControls = extended_attributes.ImplementedInputAssistControls;
return true;
}