我正在尝试从全局WindowProc函数向GUI类发送消息。 消息定义如下:
#define WM_ENV_RESIZED (WM_APP + 0)
我的WindowProc功能如下所示
LRESULT CALLBACK windowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int res;
switch (message)
{
case WM_SIZE:
std::cout << "window resized" << std::endl;
res = PostMessage(hWnd, WM_ENV_RESIZED, 0, 0);
if ( res == 0 ) //<-- res is never 0
{
std::cout << "PostMessage failure!" << std::endl;
std::cout << "Error code: " << GetLastError() << std::endl;
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
然后在GUI类中接收消息,如下所示:
MSG msg;
while (running)
{
while ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
processWindowsMessage(&msg);
//DirectX render calls
}
现在我的问题是PeekMessage()从未收到过该消息。它只在窗口创建时收到一次。在此之后它从未收到过。
在PostMessage()之后直接调用GetLastError()总是返回错误代码6,它代表根据MSDN的ERROR_INVALID_HANDLE。但这没有任何意义,因为PostMessage()永远不会返回0,这意味着在发布过程中出现了问题。 我试图绕过消息队列并使用SendMessage()将消息直接发送到窗口,但总是返回0(具有相同的错误代码6 ..)。
我真的不知道我做错了什么。使用PeekMessage()时,如何确保始终收到已发布的消息?
修改 我已经更新了Remy建议的消息循环。下面是processWindowsMessage()
中的代码void Environment::processWindowsMessage( MSG *msg )
{
switch ( msg->message )
{
case WM_ENV_RESIZED:
std::cout << "WM_ENV_RESIZED caught" << std::endl;
break;
case WM_QUIT:
running = false;
break;
default:
TranslateMessage(msg);
DispatchMessage(msg);
break;
}
}
答案 0 :(得分:1)
由于您的消息被发布到正在调整大小的同一窗口,因此DispatchMessage()
会将消息发送到窗口的过程,就像任何其他针对该窗口的消息一样。所以:
1)处理windowProcedure()
:
LRESULT CALLBACK windowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
std::cout << "window resized" << std::endl;
if (!PostMessage(hWnd, WM_ENV_RESIZED, 0, 0))
{
std::cout << "PostMessage failure!" << std::endl;
std::cout << "Error code: " << GetLastError() << std::endl;
}
break;
case WM_ENV_RESIZED:
std::cout << "env resized" << std::endl;
//...
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
MSG msg;
while (running)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//DirectX render calls
}
2)如果您不想在窗口过程中处理自定义消息,请更改消息循环,将TranslateMessage()
和DispatchMessage()
调用移至processWindowsMessage()
并仅调用它们非自定义消息,不要翻译/发送自定义消息:
LRESULT CALLBACK windowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
std::cout << "window resized" << std::endl;
if (!PostMessage(hWnd, WM_ENV_RESIZED, 0, 0))
{
std::cout << "PostMessage failure!" << std::endl;
std::cout << "Error code: " << GetLastError() << std::endl;
}
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
MSG msg;
while (running)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
processWindowsMessage(&msg);
//DirectX render calls
}
void processWindowsMessage(MSG *msg)
{
switch (msg->message)
{
case WM_ENV_RESIZED:
std::cout << "env resized" << std::endl;
//...
break;
default:
TranslateMessage(msg);
DispatchMessage(msg);
break;
}
}