如何正确使用WM_KEYDOWN?

时间:2013-12-18 05:41:42

标签: c++ winapi message-queue

我使用WM_KEYDOWN / WM_KEYUP定义了一些处理Input的函数,但只有WM_KEYUP似乎正常工作。当使用利用WM_KEYDOWN的功能时,没有任何反应。 (未显示调试消息)

在我的Framework-object中初始化我的Input-class实例时,我向它传递一个指向我的Framwork使用的MSG对象的指针。 (我的函数中的ESCAPE参数也与VK_ESCAPE相同)

这是我的代码:
//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");
    }
}

任何人都知道为什么只有KeyReleased()函数有效但KeyPressed()没有? 提前致谢

2 个答案:

答案 0 :(得分:1)

好的,查看您的代码似乎问题是Run()函数中的消息循环:

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();
        }
    }
}

看看这是做什么的。每次循环迭代,过程都是:

  • 如果消息在队列中,请对其进行处理
  • 否则,请致电Frame()函数

当处理消息时,它会被分派到窗口并由WndProc处理,这实际上做得很少。您的大多数邮件处理都是在Frame()Frame()调用的函数中完成的,但只有在队列中的消息时才会调用该函数

这解释了为什么您会看到WM_KEYUP而不是WM_KEYDOWN。这两条消息通常会聚在一起,至少在您以正常速度按下并释放按键时。

第一次循环,PeekMessage将检索WM_KEYDOWN并将其发送到您的窗口过程,该窗口过程无效。

然后循环重复,并检索WM_KEYUP。同样,这被发送到窗口过程(它不会对它做任何事情),但是下一次调用Frame()函数时队列中没有其他消息 - 然后处理最近检索到的消息< / em>但没有其他消息在它之前。

要修复您的代码,您需要重构邮件处理,以便处理每条邮件,而不仅仅是处理任何特定批次的邮件。

答案 1 :(得分:0)

WM_KEYDOWN遍历TranslateMessage块,并以WM_CHAR的形式到达您的块。

所以我认为你必须尝试WM_CHAR。