gpt4 book ai didi

c++ - PostMessage 只能工作一次?

转载 作者:行者123 更新时间:2023-11-28 07:46:50 26 4
gpt4 key购买 nike

我正在尝试从全局 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() 时如何确保始终收到发布的消息?

编辑:我已经按照雷米的建议更新了消息循环。下面是 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;
}
}

最佳答案

由于您的消息被发布到正在调整大小的同一个窗口,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;
}
}

关于c++ - PostMessage 只能工作一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14762665/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com