How to convert UCHAR Virtual-Key Codes into std::s

2019-09-21 11:37发布

This question already has an answer here:

I'm working on a game option that change the keyboard setting. So, I want to display the key that player has changed. I have the issue to convert UCHAR key that contains a Virtual-Key Codes into std::string. Seem that GetKeyNameText() only cannot convert UCHAR into string as no string has been displayed on screen. How can I fix this issue? Thanks.

Get keyboard message

LRESULT Game::messageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (initialized)    // do not process messages if not initialized
    {
        switch (msg)
        {
         case WM_KEYDOWN: case WM_SYSKEYDOWN:       // key down
            input->keyDown(wParam);
            return 0;
        }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);    // let Windows handle it
}

Input class

UCHAR key;  

void Input::keyDown(WPARAM wParam)
{
    // make sure key code is within buffer range
    if (wParam < inputNS::KEYS_ARRAY_LEN)
    {
        keysDown[wParam] = true;    // update keysDown array
        // key has been "pressed, erased by clear()
        keysPressed[wParam] = true; // update keysPressed array
        key = wParam;
    }
}

UCHAR getKeyPressed() { return key; }

Game class

Note: Code detail has been skipped.

// Key control
UCHAR vkeyUp;
UCHAR vkeyDown;

void GameContent::update()
{
    if (buttonX == 220)
    {
        if (buttonY == 15)
        {
            if (input->anyKeyPressed()) {
                vkeyUp = input->getKeyPressed();
                buttonX = 10;
                buttonY = 15;
            }   
        }
        else if (buttonY == 65)
        {
            if (input->anyKeyPressed()) {
                vkeyDown = input->getKeyPressed();
                buttonX = 10;
                buttonY = 65;
            }
        }
    }

    button.setX(buttonX);
    button.setY(buttonY);
}


void GameContent::render()
{
    font.print("Move Up", 20, 20);      font.print(input->getKeyPressedString(vkeyUp), 300, 20);
    font.print("Move Down", 20, 70);    font.print(input->getKeyPressedString(vkeyDown), 300, 70);
}


std::string Input::getKeyPressedString(UCHAR vkey)
{
    std::string keyString;
    TCHAR *lpszName = new TCHAR[256];
    GetKeyNameText(vkey, lpszName, sizeof(lpszName));

    keyString = *lpszName;
    return keyString;
}

DirectX Font Class

int TextDX::print(const std::string &str, int x, int y)
{
    if (dxFont == NULL)
        return 0;
    // Set font position
    fontRect.top = y;
    fontRect.left = x;

    // Rotation center
    D3DXVECTOR2 rCenter = D3DXVECTOR2((float)x, (float)y);
    // Setup matrix to rotate text by angle
    D3DXMatrixTransformation2D(&matrix, NULL, 0.0f, NULL, &rCenter, angle, NULL);
    // Apply Matrix
    graphics->getSprite()->SetTransform(&matrix);
    return dxFont->DrawTextA(graphics->getSprite(), str.c_str(), -1, &fontRect, DT_LEFT, color);
}

1条回答
爷的心禁止访问
2楼-- · 2019-09-21 12:22

Three problems in getKeyPressedString:
1) You´re not deleting lpszName again.
Either make a delete lpszName; before returning,
or use a static buffer in the first place.

2) keyString = *lpszName; only assigns the first character, not the whole string.
Remove *.

3) GetKeyNameText can fail. Check the return value, and GetLastError too.
(side note: ERROR_INSUFFICIENT_BUFFER won´t happen with key names and 256).

Code:

std::string Input::getKeyPressedString(UCHAR vkey)
{
    TCHAR lpszName[256];
    if(!GetKeyNameText(vkey, lpszName, sizeof(lpszName)))
    {
        //maybe? Or throw std::systemerror(GetLastError(), std::system_category())
        return std::string("");
    }
    return std::string(lpszName);
}
查看更多
登录 后发表回答