سؤال

Is there a way of detecting keyboard input within the message loop. Here is something I've tried below:

LRESULT D3DApp::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch( msg )
    {     
    // WM_DESTROY is sent when the window is being destroyed.
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_KEYDOWN:
        BYTE keyboardState[256];

        if (keyboardState[DIK_W]) {
            OutputDebugStringW(L"W Button Pressed\n");
        }  

        if (keyboardState[DIK_A]) {
            OutputDebugStringW(L"A Button Pressed\n");
        } 

        if (keyboardState[DIK_S]) {
            OutputDebugStringW(L"S Button Pressed\n");
        } 

        if (keyboardState[DIK_D]) {
            OutputDebugStringW(L"D Button Pressed\n");
        }
        return 0;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

The problem is the it seems to return all of the keyboard states: Output is as follows...

W Button Pressed
A Button Pressed
S Button Pressed
D Button Pressed

How can I implement this so it just detects the key input pressed. I'm new so this might be a stupid implementation :)

هل كانت مفيدة؟

المحلول

You never set the elements when a key is pressed.

You are also using the keyboardState array as a local variable. You must make it global or static, because each time the MsgProc function is called the keyboardState is allocated on the stack, and there is no guarantee of its contents, which may have been modified by previous function calls using the same memory space.

In your code basically each element of keyboardState has 255/256 chance of being non-zero, and you are detecting that instead of real key presses.

If you are not accessing keyboard states from outside, don't bother with the array - just use the wParam argument of the MsgProc function:

 case WM_KEYDOWN:

    if (wParam == DIK_W) {
        OutputDebugStringW(L"W Button Pressed\n");
    }  

    if (wParam == DIK_A) {
        OutputDebugStringW(L"A Button Pressed\n");
    } 

    if (wParam == DIK_S) {
        OutputDebugStringW(L"S Button Pressed\n");
    } 

    if (wParam == DIK_D) {
        OutputDebugStringW(L"D Button Pressed\n");
    }
    return 0;

(Assuming your DIK_ key values are the same as WinAPI's VK_ key codes)

نصائح أخرى

You are not initializing keyboardState before using it:

case WM_KEYDOWN:
{
    BYTE keyboardState[256];
    ::GetKeyboardState(keyboardState); // <-- ADD THIS!
    ...
    return 0;
}

Alternatively, use Get(Async)KeyState() instead:

case WM_KEYDOWN:
{
    if (GetKeyState('W') & 0x8000) {
        OutputDebugStringW(L"W Button is Down\n");
    }  

    if (GetKeyState('A') & 0x8000) {
        OutputDebugStringW(L"A Button is Down\n");
    } 

    if (GetKeyState('S') & 0x8000) {
        OutputDebugStringW(L"S Button is Down\n");
    } 

    if (GetKeyState('D') & 0x8000) {
        OutputDebugStringW(L"D Button is Down\n");
    }

    return 0;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top