How to convert UCHAR Virtual-Key Codes into std::string [duplicate]
Asked Answered
H

1

-1

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);
}
Hildick answered 22/2, 2014 at 19:52 Comment(5)
Did only check getKeyPressedString until now, but: a) Why * at keyString = *lpszName; This will copy only one char... b) You don´t free lpszName. c) You don´t check the return valaue of GetKeyNameTextSlavish
a) Change to keyString = lpszName; ? b) use free(lpszName); ? c) How to check the return valaue of GetKeyNameText?Hildick
a) Yes. b) Use delete lpszName; rather than free, because you´re using new instead of malloc.Slavish
c) How to check the return valaue of GetKeyNameText?Hildick
Use google. msdn.microsoft.com/en-us/library/windows/desktop/… describes what the value will be in case of an error. ... i´ll make an answer with all...Slavish
S
0

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);
}
Slavish answered 22/2, 2014 at 20:36 Comment(5)
It still doesn't work.Hildick
Compiler error (message?), runtime crash (message? line, found per debugging?), unwanted behaviour (what do you expect and what is happening instead), ...?Slavish
The program runs fine without any problem but I cannot get the key displays on the screen.Hildick
Then how is the program running fine? :facepalm: ... Sorry, i can´t help you without knowing what´s going onSlavish
Before that, I define the return string one by one it works. i453.photobucket.com/albums/qq253/ulti-killer/… but after I applied ur codes, it does not display the key anymore. i453.photobucket.com/albums/qq253/ulti-killer/… Now, I added directx font for display text.Hildick

© 2022 - 2024 — McMap. All rights reserved.