Windows:处理消息的两个线程?

时间:2012-01-13 01:41:55

标签: c winapi

我想有两个线程来处理Windows消息。一个用于客户区域中的键/鼠标输入(此线程也负责游戏逻辑),其余一个用于其余部分因为我正在制作游戏而一些消息导致DefWindowProc()阻塞(从而冻结游戏)。

我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:3)

与Cody写的相反,你绝对可以处理来自多个线程的消息。但是,这不是一个可定制的免费版。相反,Windows具有线程关联性:每个线程将接收发送或发布到该线程创建的窗口的消息。没有办法将任何窗口的消息传递给任何其他线程。

对于您的特定情况,为什么不创建具有自己的隐藏窗口和消息循环的工作线程?只要主窗口收到您不想在主线程中处理的消息,将其发布到另一个窗口,它就会排队并由工作线程处理。

答案 1 :(得分:1)

您应该只需要一个处理消息队列的线程,这是Windows已经提供的。如果你正在做任何计算量很大的事情,你应该通过创建一个带有CreateThread的新线程将它发送到一个单独的线程。如果您发现自己经常这样做,那么请将该线程永久保留在那里,但要求它在需要时发出信号。

答案 2 :(得分:1)

不,所有消息都需要在单个线程上处理。这个单线程通常称为UI线程,因为它是控制用户界面的线程。尝试在非UI线程上处理UI消息只会让您遇到麻烦。

但是,常见问题是应用程序执行长时间运行的计算密集型任务以响应特定消息。这样做效果不好,因为当代码在消息处理程序内部运行时,应用程序无法处理其他消息(线程一次只能做一件事),并且您的UI变为不响应。

解决方案是分离另一个线程(或两个或多个你需要的线程)并将长时间运行的计算密集型任务委托给该线程。您仍将处理单个UI线程上的消息,但在消息处理程序内部,您将把任务传递给帮助程序线程。您经常会听到这种情况称为“工作线程”或“后台线程”模式。

您可以使用CreateThread function创建其他主题。您可以找到示例here

在这种情况下,听起来QueueUserWorkItem function可能是一个更简单的选项。示例代码:

DWORD CALLBACK ThreadProc(LPVOID p)
{
    HWND hWnd = reinterpret_cast<HWND>(p);

    for (int i = 0; i < 100000; ++i)
    {
        // do whatever
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_KEYDOWN: // or whatever message you want to respond to
        {
            QueueUserWorkItem(ThreadProc, hWnd, WT_EXECUTELONGFUNCTION);
            return 0;
        }
        // process other messages...
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

Win32线程池的必读读数为here