如何正确使用WM_KEYDOWN

How to use WM_KEYDOWN properly ?

本文关键字:KEYDOWN WM 何正确      更新时间:2023-10-16

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

在框架对象中初始化我的输入类的实例时,我向它传递一个指向我的 Framwork 使用的 MSG 对象的指针。(我的函数中的 ESCAPE 参数也与 VK_ESCAPE 相同(

这是我的代码:
输入.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;
}

框架.cpp

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

有人知道为什么只有KeyRelease((函数有效而KeyPressed((不起作用?
提前致谢

好的,查看您的代码,问题似乎出在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()函数时队列中没有其他消息 - 然后处理最近检索到的消息,但不处理之前的其他消息。

要修复代码,您需要重构消息处理,以便处理每条消息,而不仅仅是任何特定批处理中的最后一条消息。

WM_KEYDOWN通过

翻译消息块,并会以WM_CHAR的形式到达您的块。

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