为什么win32消息循环在线程化时停止工作



我正在尝试创建一个WIN32(C++(程序,在该程序中,我必须同时处理消息并运行while循环。为了做到这一点,我想使用线程。

当我将消息循环移动到一个单独的过程(从函数WinMain调用(时,所有事情都很好。然而,当我使用下面的代码来线程化该过程时,而不是简单地从主进程调用它,窗口变得没有响应。

你知道为什么会这样吗?

在WinMain中,创建主窗口后,我删除了消息循环和返回值,添加了以下代码:

std::thread t1(message_loop);
t1.join();
return return_val;

return_val是一个全局变量,我将使用它来接收消息循环结束时WinMain应返回的值。

此外,函数message_loop如下所示:

void message_loop()
{
MSG messages;
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
return_val = messages.wParam;
}

根本原因是Windows有线程消息队列的概念。每个线程都有自己的消息队列。在线程中运行GetMessage是可以的,但它只会得到属于该线程的消息,例如您在该线程中创建的窗口的消息。属于任何其他线程的消息(无论该其他线程是如何创建的(在您的线程中都不可见。

如您所述,您的std::thread仅被创建为";在创建主窗口之后";。这意味着您有两个线程消息队列;一个来自创建主窗口的主线程,另一个队列用于std::thread。后一个队列将保持为空。

你可以在GetMessage的第二个自变量中看到这一点——传递HWND=0意味着";该线程的所有消息";。

理论上,可以为多个窗口提供多个线程,但这很快就会变得非常复杂。因此,在实践中,最常见的解决方案是使用main线程,唯一合理的选择是使用单个专用线程。

最新更新