Windows virtual key codes

前端 未结 2 1675
悲哀的现实
悲哀的现实 2020-12-15 01:42

How can I implement a function like std::string VirtualKeyCodeToStdString(UCHAR key) which returns virtual keys descriptions?

Example: input is VK

相关标签:
2条回答
  • 2020-12-15 02:23

    There is no full answer. Thank you everybody for helping. After more research I wrote complete function that converts virtualKey to std::string description.

    * std::basic_string < TCHAR > Version: *

    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;
    }
    
    0 讨论(0)
  • 2020-12-15 02:28

    A simple way to convert the VK code to a text representation of the key is to:

    1. Use MapVirtualKey to convert the VK code to a scan code.
    2. Do a bit shift to convert that value into a long where bits 16-23 are the scan code
    3. Use GetKeyNameText to obtain the name of the key.

    For example:

    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
    }
    

    If you're doing this in response to a WM_KEYDOWN or other message that passes the scan code in the LPARAM you can skip the first two steps, since those are just there to massage the VK code into a properly formatted input for GetKeyNameText. For more information about the function and the format of the first parameter to GetKeyNameText see the documentation at MSDN

    Note: I used the W variant on the API calls, so you'd actually need to use a std::wstring to pass the key name, but you can change it easily to use the A version. Also, if you need to pass a keyboard layout to get the proper scan code, you can use MapVirtualKeyEx.

    0 讨论(0)
提交回复
热议问题