如何在工作线程(非UI线程)中创buildmodal dialog?

我写了一个示例MFC应用程序,其中有两个线程: – 主线程(UI线程) – 工作线程(非UI线程)

我有一个特定的要求,在非UI(工作线程)中创build一个Modal对话框。 当我创buildCDialog对象并调用DoModal时,它就可以工作。 对话框被创build并作为应用程序的模态。 (Win XP SP2机器)但是这在Windows 2003服务器机器上不起作用。 在2003服务器的行为是,modal dialog在应用程序主窗口后面,只有当我点击主窗口时,对话框才会被带到前面。 它不作为我的应用程序的modal dialog。

可能是什么问题 – 有什么想法?

如果在非UI线程中创buildUI控件是问题,那么是否有任何Win32 API将允许我将我的工作线程链接到主UI线程,使得DoModal在主线程中发生。 我试过AttachThreadInput,但它不工作。

Solutions Collecting From Web of "如何在工作线程(非UI线程)中创buildmodal dialog?"

首先,我想同意其他海报,最好在主UI线程上显示对话框。

但是,如果必须,您可以使用以下步骤在另一个线程模式上进行对话:

  1. 创建对话框时,将活动窗口作为所有者传递。
  2. 当显示对话框时,遍历其他窗口并执行EnableWindow(FALSE) 。 当对话框隐藏时,做相反的事情。 您可能必须记住Windows的启用状态,并恢复原始状态,而不仅仅是EnableWindow(TRUE)
  3. 确保在显示对话框时加速器和其他全局命令将被忽略。

请注意,(2)不应该是必要的,只要你(1),但你已经提到MFC,我不记得它是如何表现。 它有自己的模式对话框实现,可能不完全符合Win32。 如果你幸运的话,(1)和(3)就足够了。

没有可靠的方法来跨多个线程传播GUI模式。 每个窗口都由一个HWND引用的对象表示,而HWND又具有线程相关性。 这是从没有多线程的Windows的16位日子剩下的。 因此, HWND不受并发访问的保护。 Old New Thing在“用户界面对象的线程亲和性”(Part 1 2 3 Addendum )方面有很好的系列。

通过首先启用对话窗口然后禁用其父项来实现模态。 第一步是安全的,而第二步则尝试从不是窗口拥有线程的线程中禁用窗口。 由于en / /禁用窗口修改通过HWND引用的对象它代表竞争条件。

建议的解决方案是将GUI限制为单个线程,并从工作线程到GUI线程进行通信,以便代表工作线程执行用户交互。 最简单的方法是从工作线程调用SendMessage ,直到GUI线程的消息处理程序返回。 如果在显示对话框时工作线程应该继续运行,则可以使用PostMessage,并使用PostThreadMessage或通过信号发送同步对象(如事件对象)来传回工作线程。

虽然我不知道server 2003上的对话框处理的细节,但获取主线程的最简单的解决方法是使用自定义窗口消息do ::SendMessage()并在消息处理程序中显示对话框。

我建议你不要做什么问题的主题建议,并将所有的用户界面限制在一个线程。 如果您需要其他线程与用户进行通信,请创建一些消息传递机制,以便要求UI线程执行此操作,然后将结果传回。