c++ - 如何正确使用 WM_KEYDOWN?

标签 c++ winapi message-queue

我使用 WM_KEYDOWN/WM_KEYUP 定义了一些函数来处理输入,但似乎只有 WM_KEYUP 可以正常工作。当使用利用 WM_KEYDOWN 的函数时,什么也没有发生。 (不显示调试消息)

在我的框架对象中初始化我的输入类的一个实例时,我向它传递了一个指向我的框架使用的 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");
    }
}

有人知道为什么只有 KeyReleased() 函数起作用而 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()函数

当一条消息被处理时,它被分派(dispatch)到窗口并由您的 WndProc 处理,这实际上做的很少。您的大部分消息处理是在 Frame()Frame() 调用的函数中完成的,但是只有在不存在时才调用该函数t 队列中的一条消息。

这解释了为什么您看到的是 WM_KEYUP 而不是 WM_KEYDOWN。这两条消息通常会同时出现,至少在您以正常速度按下和释放按键时会出现这种情况。

第一次通过循环时,PeekMessage 将检索 WM_KEYDOWN 并将其分派(dispatch)给您的窗口过程,它不执行任何操作。

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

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

关于c++ - 如何正确使用 WM_KEYDOWN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20650470/

相关文章:

c++ - 如何使用已实现的代码更新 Qt-GUI 表单 View ?

c++ - 在 C 或 C++ 中以编程方式删除非空目录

message-queue - HornetQ 核心 API 和 JMS

ssl - 如何使用 MQ 的 ssl 证书打开 kdb 文件?

C++ std::set 自定义比较器

c++ - 将 c 枚举导入到 c++ 类定义

c++ - 视觉 C++ : Convert data type PCSTR to LPCWSTR

c++ - 查找给定输入的唯一路径名

c++ - 使用 Windows api 和 C++,我如何从硬盘驱动器加载一个 exe 并在它自己的线程中运行它?

delphi - Firemonkey - 消息处理