以编程方式获取物理键盘布局

发布于 2024-10-12 08:55:03 字数 133 浏览 7 评论 0原文

有没有一种方法可以以编程方式找出计算机的键盘类型(即按键的位置,以及哪些位置存在哪些额外的按键)?

如果键盘非常不标准,那么一点点错误是可以接受的,但总的来说,重点是构建一个类似屏幕键盘的应用程序,可以在屏幕上以高精度动态绘制键盘布局。

Is there a way to programmatically find out what kind of keyboard a computer has (i.e. where keys are located, and what extra keys are present in which locations)?

A little error is acceptable, if the keyboard is very non-standard, but in general, the point is to construct an on-screen keyboard-like application that can dynamically draw the keyboard layout on the screen, with high accuracy.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

乱世争霸 2024-10-19 08:55:03

当连接到计算机时,键盘会向操作系统发送“扫描代码”。在 Windows 上,扫描代码随后被转换为虚拟键(与硬件无关的键盘映射),然后转换为真实字符。

MapVirtualKeyEx() Windows API的功能允许您在扫描码、虚拟键和字符之间进行转换。它还应该能够告诉您密钥是否不存在。

GetKeyboardLayout() 它会告诉您哪个键盘在任何时间点处于活动状态(不同运行的应用程序的键盘布局可能不同),它应该允许您构建相当准确的键盘映射。

不管怎样,看看键盘MSDN 的输入部分

我将补充一点,所有键盘都具有几乎相同的布局。虽然无法知道按键的物理位置,但您可以通过扫描代码和您自己的键盘的基本知识来猜测。

when connected to a computer, keyboards sends "scan codes" to the operating system. on windows, scan codes are then converted into virtual keys (a hardware independent mapping of the keyboard) then to real characters.

the MapVirtualKeyEx() function of the windows API allows you to translate between scan codes, virtual keys and characters. it should also be able to tell you if a key is non-existing.

together with GetKeyboardLayout() which tells you which keybaord is active at any point in time (keyboard layout can be different for different running applications), it should allow you to build a pretty accurate map of the keyboard.

anyway, have a look at the keyboard input section of the MSDN

i will add that all keyboards have almost the same layout. although there is no way to know where a key is physically located, you can probably guess from the scan code and basic knowledge of your own keyboards.

一抹苦笑 2024-10-19 08:55:03

键盘没有任何机制可以告诉 Windows 其物理布局是什么样的。使用 Windows 版本的屏幕键盘 osk.exe 可以轻松查看。它似乎能够猜测机器的外形(笔记本电脑与台式机),但在我的笔记本电脑上,它与键盘的布局不匹配。

使用 osk.exe 布局作为模板,这样就没有人会抱怨您的布局不匹配。

There is no mechanism by which a keyboard can tell Windows what its physical layout looks like. Easy to see with the Windows version of an on-screen keyboard, osk.exe. It seems to be able to guess the form-factor of the machine (laptop vs desktop) but on my laptop it doesn't match the layout of the keyboard.

Use the osk.exe layout as a template so nobody can complain that yours doesn't match well.

绝情姑娘 2024-10-19 08:55:03

2023 年更新

有一个新的 KEYBOARD_EXTENDED_ATTRIBUTES 结构和 IOCTL_KEYBOARD_QUERY_EXTENDED_ATTRIBUTES Windows 10 中添加的 IOCTL 可以返回其他键盘信息。

请参阅最新 HID 使用表规范中的“15.18 描述性控制”。这些内容来自采用的HID 使用表审核请求 42:消费者页面键盘辅助控件从 2013 年开始。

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;
}

但供应商似乎没有采用这些,而且我的现代 Logitech MX Keys 键盘在这些字段中返回零值。

Update from 2023

There is a new KEYBOARD_EXTENDED_ATTRIBUTES struct and IOCTL_KEYBOARD_QUERY_EXTENDED_ATTRIBUTES IOCTL added in Windows 10 that can return additional keyboard info.

See "15.18 Descriptive Controls" in the recent HID Usage Tables spec. These was from adopted HID Usage Table Review Request 42: Consumer Page Keyboard Assist Controls from 2013.

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;
}

But seems these is not adopted by vendors and my modern Logitech MX Keys keyboard returns zero values in these fields..

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文