c++cwinapiwndproc

How to handle key_down and key_up of char in WndProc?


I'm trying to handle key up and key down messages for arrow keys and A, W, S, D characters.

I can handle arrow keys' up and down behavior using WM_KEYUPand WM_KEYDOWN.

But when I try to handle above characters' up and down behavior, it doesn't work properly.

I tried WM_KEYUPand WM_KEYDOWN to handle chracters. But after I changed them to WM_CHAR and WM_DEADCHAR. But it still doesn't work.

For characters I can handle first few key down and up messages, then program doesn't handle these. But for arrow keys, program works properly.

I'm new in this, didn't found how to handle character's up and down behaviors.

Below is the last code (Just WndProc function)I tried.

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg)
    {
    case WM_CREATE:
        Hmainbmp = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE | SS_BITMAP | WS_THICKFRAME, 1, 23, WINDOW_WIDTH, WINDOW_HEIGHT, hWnd, nullptr, hInst, nullptr);
        start_game();
        break;

    case WM_CHAR:
        PRESSED_KEY = (int)wParam;
        if (PRESSED_KEY == 'A' or PRESSED_KEY == 'a') { players[1]->moves.left = true; }
        else if (PRESSED_KEY == 'D' or PRESSED_KEY == 'd') { players[1]->moves.right = true; }
        else if (PRESSED_KEY == 'W' or PRESSED_KEY == 'w') { players[1]->moves.up = true; }
        else if (PRESSED_KEY == 'S' or PRESSED_KEY == 's') { players[1]->moves.down = true; }
        break;

    case WM_DEADCHAR:
        PRESSED_KEY = (int)wParam;
        if (PRESSED_KEY == 'A' or PRESSED_KEY == 'a') { players[1]->moves.left = false; }
        else if (PRESSED_KEY == 'D' or PRESSED_KEY == 'd') { players[1]->moves.right = false; }
        else if (PRESSED_KEY == 'W' or PRESSED_KEY == 'w') { players[1]->moves.up = false; }
        else if (PRESSED_KEY == 'S' or PRESSED_KEY == 's') { players[1]->moves.down = false; }
        break;

    case WM_KEYDOWN:
        PRESSED_KEY = (int)wParam;
        if      (PRESSED_KEY == VK_LEFT)    { players[0]->moves.left    = true; }
        else if (PRESSED_KEY == VK_RIGHT)   { players[0]->moves.right   = true; }
        else if (PRESSED_KEY == VK_UP)      { players[0]->moves.up      = true; }
        else if (PRESSED_KEY == VK_DOWN)    { players[0]->moves.down    = true; }
        break;
    case WM_KEYUP:
        RELEASED_KEY = (int)wParam;
        if      (RELEASED_KEY == VK_LEFT)   { players[0]->moves.left    = false; }
        else if (RELEASED_KEY == VK_RIGHT)  { players[0]->moves.right   = false; }
        else if (RELEASED_KEY == VK_UP)     { players[0]->moves.up      = false; }
        else if (RELEASED_KEY == VK_DOWN)   { players[0]->moves.down    = false; }
        break;
    
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return(DefWindowProc(hWnd, uMsg, wParam, lParam));
    }

    return(0L);
}

start_game() is my main function, I'm using key's up and down messages in that function.

My question is, how can I handle key down and key up behaviors of characters such as A, D?


After I press to A or W program can't handle key up behavior of these characters and any other character's key down behavior like S and D. But at the same time program can handle arrow keys' up and down behavior.


FULL CODE (Vs2019)


Solution

  • According to WM_DEADCHAR:

    WM_DEADCHAR specifies a character code generated by a dead key. A dead key is a key that generates a character, such as the umlaut (double-dot), that is combined with another character to form a composite character.

    So the WM_DEADCHAR message is not what you think corresponds to the WM_CHAR message.

    You can also use WM_KEYDOWN/WM_KEYUP messages to handle character keys:

    case WM_KEYDOWN:
        PRESSED_KEY = (int)wParam;
        if      (PRESSED_KEY == VK_LEFT)    { players[0]->moves.left    = true; }
        else if (PRESSED_KEY == VK_RIGHT)   { players[0]->moves.right   = true; }
        else if (PRESSED_KEY == VK_UP)      { players[0]->moves.up      = true; }
        else if (PRESSED_KEY == VK_DOWN)    { players[0]->moves.down    = true; }
        if (PRESSED_KEY == 'A' or PRESSED_KEY == 'a') { players[1]->moves.left = true; }
        else if (PRESSED_KEY == 'D' or PRESSED_KEY == 'd') { players[1]->moves.right = true; }
        else if (PRESSED_KEY == 'W' or PRESSED_KEY == 'w') { players[1]->moves.up = true; }
        else if (PRESSED_KEY == 'S' or PRESSED_KEY == 's') { players[1]->moves.down = true; }
        break;
    case WM_KEYUP:
        RELEASED_KEY = (int)wParam;
        if      (RELEASED_KEY == VK_LEFT)   { players[0]->moves.left    = false; }
        else if (RELEASED_KEY == VK_RIGHT)  { players[0]->moves.right   = false; }
        else if (RELEASED_KEY == VK_UP)     { players[0]->moves.up      = false; }
        else if (RELEASED_KEY == VK_DOWN)   { players[0]->moves.down    = false; }
        if (RELEASED_KEY == 'A' or RELEASED_KEY == 'a') { players[1]->moves.left = false; }
        else if (RELEASED_KEY == 'D' or RELEASED_KEY == 'd') { players[1]->moves.right = false; }
        else if (RELEASED_KEY == 'W' or RELEASED_KEY == 'w') { players[1]->moves.up = false; }
        else if (RELEASED_KEY == 'S' or RELEASED_KEY == 's') { players[1]->moves.down = false; }
        break;