You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xlib转WinApi实现:如何检测物理按键的按下状态

使用WinAPI遍历并检测所有物理按键的按下状态

在Windows平台上,你可以通过两种核心方式实现类似Linux下X11的按键状态检测:

方法一:一次性获取所有按键状态(类似XQueryKeymap)

使用GetKeyboardState函数,它能一次性获取所有256个虚拟键的当前状态,返回的数组中每个字节的最高位(0x80)表示对应按键是否被按下。

代码示例

#include <Windows.h>
#include <iostream>

int main()
{
    BYTE keyStates[256];
    // 获取所有按键的实时状态
    if (GetKeyboardState(keyStates))
    {
        // 遍历所有虚拟键码(0到255覆盖所有按键)
        for (int vkCode = 0; vkCode < 256; ++vkCode)
        {
            bool isPressed = (keyStates[vkCode] & 0x80) != 0;
            if (isPressed)
            {
                std::cout << "虚拟键码 " << vkCode << " 处于按下状态" << std::endl;
            }
        }
    }
    else
    {
        std::cerr << "获取键盘状态失败,错误码:" << GetLastError() << std::endl;
    }

    return 0;
}

方法二:遍历虚拟键调用GetAsyncKeyState

如果你更倾向于使用GetAsyncKeyState,可以遍历虚拟键码的有效范围(从VK_LBUTTON(0x01)到VK_OEM_CLEAR(0xFE)),逐个检查按键状态。该函数返回的SHORT值中,最高位(0x8000)表示当前按键是否按下,最低位(0x0001)表示自上次调用以来按键是否被按下过。

代码示例

#include <Windows.h>
#include <iostream>

int main()
{
    // 遍历所有标准虚拟键码
    for (int vkCode = VK_LBUTTON; vkCode <= VK_OEM_CLEAR; ++vkCode)
    {
        SHORT keyState = GetAsyncKeyState(vkCode);
        bool isCurrentlyPressed = (keyState & 0x8000) != 0;

        if (isCurrentlyPressed)
        {
            std::cout << "虚拟键码 " << vkCode << " 当前被按下" << std::endl;
        }
    }

    return 0;
}

额外说明

  • 虚拟键码(VK_*常量)覆盖了所有物理按键,包括鼠标按钮、功能键、字母数字键及特殊按键
  • 若需要将虚拟键码转换为更贴近物理键的扫描码,可以使用MapVirtualKey函数,例如:DWORD scanCode = MapVirtualKey(vkCode, MAPVK_VK_TO_VSC);
  • GetKeyboardState依赖系统消息队列,在GUI程序中需确保消息循环正常运行;控制台程序中可直接调用,但状态为调用瞬间的快照

内容的提问来源于stack exchange,提问作者Irbis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 15:42:41