C++ 如何在工作线程(非UI线程)中创建模式对话框?

C++ 如何在工作线程(非UI线程)中创建模式对话框?,c++,windows,mfc,winapi,modal-dialog,C++,Windows,Mfc,Winapi,Modal Dialog,我编写了一个示例MFC应用程序,其中有两个线程: -主线程(UI线程) -工作线程(非UI线程) 我有一个特定的需求,需要在非UI(工作线程)中创建一个模态对话框。 当我创建CDialog对象并在同一个对象上调用DoModal时,它就工作了。对话框将被创建并充当应用程序的模态。(Win XP SP2计算机)但这在Windows 2003服务器计算机中不起作用。 2003服务器中的行为是,模式对话框位于应用程序主窗口的后面,只有当我单击主窗口时,对话框才会显示在前面。它不是我的应用程序的模态对话框

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

我有一个特定的需求,需要在非UI(工作线程)中创建一个
模态
对话框。 当我创建
CDialog
对象并在同一个对象上调用
DoModal
时,它就工作了。对话框将被创建并充当应用程序的模态。(Win XP SP2计算机)但这在Windows 2003服务器计算机中不起作用。 2003服务器中的行为是,模式对话框位于应用程序主窗口的后面,只有当我单击主窗口时,对话框才会显示在前面。它不是我的应用程序的模态对话框

有什么问题吗?有什么想法吗


如果在非UI线程中创建UI控件是一个问题,那么是否有任何Win32 API允许我将工作线程链接到主UI线程,以便在主线程中发生
DoModal
。我试过了,但它不起作用。

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

我建议您不要按照问题主题的建议,并将所有UI限制在一个线程中。如果您需要另一个线程与用户通信,请创建一些消息传递机制,要求UI线程执行此操作,并将结果传输回来。

首先,我同意其他人的看法,在主UI线程上显示对话框可能更好

但是,如果必须,可以通过以下步骤在另一个线程模式上创建对话框:

  • 创建对话框时,将活动窗口作为所有者传递
  • 当对话框显示时,迭代其他窗口并执行它们
    启用窗口(FALSE)
    。当对话框隐藏时,执行相反的操作。您可能需要记住windows的启用状态并恢复原始状态,而不仅仅是
    启用窗口(TRUE)
  • 确保在显示对话框时忽略加速器和其他全局命令

  • 请注意,如果您使用(1),则不需要使用(2),但您提到了MFC,我不记得它的具体行为。它有自己的模式对话框实现,可能与Win32不完全匹配。如果幸运的话,(1)和(3)就足够了。

    没有可靠的方法在多个线程之间传播GUI模式。每个窗口都由一个通过
    HWND
    引用的对象表示,该对象又具有线程关联性。这是16位Windows时代的遗留问题,当时没有多线程。因此,
    HWND
    s不受并发访问的保护。有一个关于“用户界面对象的线程关联性”(部分)的优秀系列

    模态是通过首先启用对话框窗口,然后禁用其父窗口来实现的。第一步是安全的,而第二步尝试从不是窗口所属线程的线程禁用窗口。由于en-/禁用windows会修改通过
    HWND
    引用的对象,因此它表示竞争条件

    建议的解决方案是将GUI限制在单个线程中,并从工作线程与GUI线程通信,以使其代表工作线程执行用户交互。实现这一点的最简单方法是从工作线程调用block,直到GUI线程的消息处理程序返回。如果在显示对话框时工作线程应该继续运行,您可以改为使用,并使用或发信号通知同步对象(如同步对象)与工作线程通信