Windows虚拟密钥代码

时间:2016-06-29 13:12:23

标签: c++ winapi keyboard key

如何实现返回虚拟键描述的std::string VirtualKeyCodeToStdString(UCHAR key)等函数?

示例:输入为VK_CAPITAL,返回值为std::string("Caps Lock")

2 个答案:

答案 0 :(得分:5)

将VK代码转换为密钥的文本表示的简单方法是:

  1. 使用MapVirtualKey将VK代码转换为扫描代码。
  2. 进行一点移位以将该值转换为长度,其中16-23位是扫描码
  3. 使用GetKeyNameText获取密钥的名称。
  4. 例如:

    WCHAR name[1024];
    UINT scanCode = MapVirtualKeyW(VK_CAPITAL, MAPVK_VK_TO_VSC);
    LONG lParamValue = (scanCode << 16);
    int result = GetKeyNameTextW(lParamValue, name, 1024);
    if (result > 0)
    {
        std::wcout << name << endl; // Output: Caps Lock
    }
    

    如果您在WM_KEYDOWN或其他消息传递LPARAM中的扫描代码时执行此操作,则可以跳过前两个步骤,因为这些只是按摩将VK代码转换为GetKeyNameText的格式正确的输入。有关GetKeyNameText的第一个参数的函数和格式的详细信息,请参阅documentation at MSDN

    注意:我在API调用中使用了W变体,因此您实际上需要使用std::wstring来传递密钥名称,但您可以轻松地更改它以使用A版。此外,如果您需要传递键盘布局以获取正确的扫描代码,则可以使用MapVirtualKeyEx

答案 1 :(得分:4)

没有完整的答案。谢谢大家的帮助。经过更多的研究,我编写了完整的函数,将virtualKey转换为std::string描述。

* std :: basic_string&lt; TCHAR&gt;版本:*

typedef std::basic_string<TCHAR> tstring;

tstring VirtualKeyCodeToString(UCHAR virtualKey)
{
    UINT scanCode = MapVirtualKey(virtualKey, MAPVK_VK_TO_VSC);

    TCHAR szName[128];
    int result = 0;
    switch (virtualKey)
    {
        case VK_LEFT: case VK_UP: case VK_RIGHT: case VK_DOWN:
        case VK_RCONTROL: case VK_RMENU:
        case VK_LWIN: case VK_RWIN: case VK_APPS:
        case VK_PRIOR: case VK_NEXT:
        case VK_END: case VK_HOME:
        case VK_INSERT: case VK_DELETE:
        case VK_DIVIDE:
        case VK_NUMLOCK:
            scanCode |= KF_EXTENDED;
        default:
            result = GetKeyNameText(scanCode << 16, szName, 128);
    }
    if(result == 0)
        throw std::system_error(std::error_code(GetLastError(), std::system_category()),
                                "WinAPI Error occured.");
    return szName;
}

std :: string version:

std::string VirtualKeyCodeToString(UCHAR virtualKey)
{
    UINT scanCode = MapVirtualKey(virtualKey, MAPVK_VK_TO_VSC);

    CHAR szName[128];
    int result = 0;
    switch (virtualKey)
    {
        case VK_LEFT: case VK_UP: case VK_RIGHT: case VK_DOWN:
        case VK_RCONTROL: case VK_RMENU:
        case VK_LWIN: case VK_RWIN: case VK_APPS:
        case VK_PRIOR: case VK_NEXT:
        case VK_END: case VK_HOME:
        case VK_INSERT: case VK_DELETE:
        case VK_DIVIDE:
        case VK_NUMLOCK:
            scanCode |= KF_EXTENDED;
        default:
            result = GetKeyNameTextA(scanCode << 16, szName, 128);
    }
    if(result == 0)
        throw std::system_error(std::error_code(GetLastError(), std::system_category()),
                                "WinAPI Error occured.");
    return szName;
}