如何正确使用WM_KEYDOWN
How to use WM_KEYDOWN properly ?
我定义了一些函数来使用 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_CHAR的形式到达您的块。
所以我认为你必须尝试WM_CHAR。
- "WM" C++是什么意思?
- 什么是窗口最大化/最小化/恢复的WM Windows消息
- 请求X11在C或C++中合成WM的图像
- SDL 2 Space keydown未检测到,但Space keyup工作正常
- 删除密钥未触发 KeyUp 和 KeyDown 事件
- C++(煤渣):无法在 keyDown 函数中更新对象的属性
- Visual C++ Forms: Global Keydown
- 如何在C++中将keydown事件发送到非活动窗口
- 如果在WM/CE平台中用于卸载,DMProcessConfigXML将关闭正在运行的应用程序
- 在C或c++ (mac OSX)中有KeyDown事件
- 模拟跳跃与keyDown过剩c++不是100%
- VB.NET:未知的KeyDown事件问题
- UWP Windows 10 Direct3D 12 应用程序C++ KeyDown 延迟