工作线程没有消息循环(MFC、windows)。我们可以让它接收消息吗?

Posted

技术标签:

【中文标题】工作线程没有消息循环(MFC、windows)。我们可以让它接收消息吗?【英文标题】:Worker thread doesn't have message loop (MFC, windows). Can we make it to receive messages? 【发布时间】:2011-07-12 08:52:09 【问题描述】:

Mfc 提供工作线程和 UI 线程。 UI 线程启用了消息接收功能(发送、发布)。是否可以让工作线程也接收消息。

【问题讨论】:

那为什么不使用 UI 线程呢?无论名称如何,您都不必包含任何 UI 内容。事实上,比我更了解的人建议将所有 UI 内容放在主线程中,因此 UI 线程将是“带有消息泵的辅助线程”。 【参考方案1】:

反复调用CWinThread::PumpMessage(),直到它返回WM_QUIT消息。

【讨论】:

你将如何发送消息? sendmessage/postmessage 需要窗口句柄。我相信 postthreadmessage 会做的事情。GetMessage 可以做的事情。 您可以将 CThread 对象的引用传递给 ::PostThreadMessage(),也可以调用 CThread::PostThreadMessage()。 SendMessage() 不能用于向另一个线程发送消息。 PostThreadMessage() 仅将消息放入队列中。您无法知道对应操作是如何或何时完成的,因为线程异步处理消息。 你会后悔尝试将消息发布到没有窗口的队列。创建一个隐藏窗口作为这些消息的接收者。 如果窗口句柄为NULL,消息不是通过它的message-map发送给CWinThread派生类的成员函数吗?为什么要寻址一个窗口? CWinThread 具有与 CWnd 相同的基类!尝试将 MSG 结构的 hwnd 字段设置为 NULL 的 CWinThread::PostMessage()。 在任何情况下,永远不要从另一个线程调用 CWnd::SendMessage() 到窗口。事情可能会因此而变得一团糟。 MFC 的 Debug 版本将 ASSERT。【参考方案2】:

看来您需要一个线程,它可以处理来自另一个线程的多条消息。另一个线程将向该线程的消息队列添加消息。好吧,在这种情况下,您可以使用PeekMessage 启动一个循环,最终会创建一个隐藏窗口,然后使用GetMessage 获取消息。其他线程将使用 PostThreadMessage 和线程 ID(具有 Peek/GetMessage 的那个)和消息代码 LPARAMWPARAM.

就像(语法不正确):

TheProcessor()

    MSG msg;
    PeekMessage(&msg,...);

    while(GetMessage(&msg...)
        /* switch case here */ 

线程将调用PostThreadMessage - 有关详细信息,请参阅 MSDN。 当您需要发送超过 LPARAM/WPARAM 可以容纳的数据时,您最终需要在堆上分配它们,然后在自定义消息循环中处理消息后删除。这将是麻烦和错误的。

但是...我建议您在std::queue/deque 或其他DS 之上拥有自己的课程,您可以在其中添加AddMessage/PushMessagePopMessage(或任何您喜欢的名称) .您需要使用SetEventWaitForSingleObject 来触发循环中的新消息(请参阅implementation here 之一。您可以将其设为一种数据类型的通用类,或将其设为模板类——这将支持任何数据——类型(您的底层 DS (queue) 将使用相同的数据类型)。您也不必担心堆和删除。这不太容易出错。但是,您可能必须处理 MT 问题。

使用 Windows 事件涉及内核模式转换(因为事件是命名/内核对象),您可能希望使用作为用户对象的条件变量。或者您可以直接使用 VC10 中可用的并发运行时库中的unbounded_buffer 类。见this article(跳转到unbounded_buffer)。

【讨论】:

【参考方案3】:

是的,您可以在工作线程上创建消息队列。您需要在该线程上运行消息泵。

【讨论】:

GetMessage 可以做的事情。

以上是关于工作线程没有消息循环(MFC、windows)。我们可以让它接收消息吗?的主要内容,如果未能解决你的问题,请参考以下文章

MFC非模态添加进程控件方法一(线程方法)

Windows下多线程编程

Windows下多线程编程

MFC体系结构

在 Windows C++ 应用程序中控制主线程

MFC_Thread