简体   繁体   中英

How to use WM_KEYDOWN properly ?

I defined a few functions to process Input using WM_KEYDOWN / WM_KEYUP, but only WM_KEYUP seems to work properly. When using the function that utilizes WM_KEYDOWN nothing happens. (Debug message isnt displayed)

When initializing an instance of my Input-class inside my Framework-object, I pass it a pointer to the MSG object that my Framwork uses. (Also the ESCAPE argument inside my function is same as VK_ESCAPE)

Here is my code:
//Input.cpp

bool Input::KeyPressed( Keys key )  
{
    if( InputMsg->message == WM_KEYDOWN )
    {
        if( InputMsg->wParam == key )
            return true;
    }

    return false;
}

bool Input::KeyReleased( Keys key )
{
    if( InputMsg->message == WM_KEYUP )
    {
        if( InputMsg->wParam == key )
        return true;
    }

    return false;
}

//Framework.cpp

bool Framework::Frame()
{
    ProcessInput();
    return true;
}

void Framework::ProcessInput()
{
    if( m_Input->KeyPressed( ESCAPE ) )
    {
        OutputDebugString("Escape was pressed!\n");
    }
}

Anyone got an idea why only the KeyReleased() function works but the KeyPressed() doesn't ?
Thanks in advance

Ok, looking at your code it seems like the problem is the message loop in your Run() function:

void Framework::Run()
{
    while( msg.message != WM_QUIT && m_result)
    {
        if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
        {
            m_result = Frame();
        }
    }
}

Look at what this is doing. Every loop iteration, the process is:

  • If a message is in the queue, process it
  • Otherwise, call the Frame() function

When a message is processed it's dispatched to the window and handled by your WndProc , which actually does very little. Most of your message processing is done in Frame() or the functions called by Frame() , but that function is only called if there isn't a message in the queue.

This explains why you are seeing WM_KEYUP but not WM_KEYDOWN . The two messages generally come together, at least if you press and release the key at normal speed.

The first time through the loop, PeekMessage will retrieve WM_KEYDOWN and dispatch it to your window procedure, which does nothing with it.

The loop then repeats, and retrieves WM_KEYUP . Again this is sent to the window procedure (which does nothing with it), but with no further messages in the queue the next time around your Frame() function is called - which then processes the most recently retrieved message but none of the other messages that came before it.

To fix your code you need to refactor your message handling so that every message is processed, not just the last in any particular batch.

WM_KEYDOWN goes through the TranslateMessage block and would reach your block as WM_CHAR.

So I think you must try WM_CHAR instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM