通过COM创建多个MFC对话框,奇怪的行为

Posted

技术标签:

【中文标题】通过COM创建多个MFC对话框,奇怪的行为【英文标题】:Creating multiple MFC dialogs through COM, strange behaviour 【发布时间】:2011-02-13 08:03:20 【问题描述】:

更新:请参阅this other thread,所有这些 COM 内容都不是问题的一部分。


我们的一个应用程序有一个 COM 接口,它将启动一个对话框,例如:

STDMETHODIMP CSomeClass::LaunchDialog(BSTR TextToDisplay)

  CDialog *pDlg = new CSomeDialog(TextToDisplay);
  pDlg->BringWindowToTop();

由于某种原因,当服务器一次多次调用 COM 方法时,我们会得到奇怪的行为:

我们得到多个对话框,但任务栏中只有一个条目 对话框 Z 顺序基于创建的顺序且无法更改...创建的第一个对话框始终显示在第 2 个对话框下方,第 2 个对话框在第 3 个对话框下方,依此类推,即使您拖动它们也是如此 如果创建了 N 个对话框,关闭其中一个将关闭它,然后创建所有其他对话框。例如,如果创建了 5 个对话框并关闭了第 3 个对话框,则 #3、#4、#5 都将关闭。

这就像对话框是兄弟姐妹,但我没有看到任何奇怪的事情发生。可能是因为 COM,还是这是一个奇怪的 MFC/Win32 问题?

编辑:如果接口方法被分别调用多次,它会按预期工作。只有当服务器组件一次发送多个时,它才会看起来混乱。线程/计时是否应该受到责备?

编辑2: 我把这个登录:

std::stringstream ss;
HWND self = dlg->m_hWnd;
HWND parent = dlg->GetParent() ? dlg->GetParent()->m_hWnd : 0;
ss<<"Dlg created'. HWND = "<<self<<", Parent = "<<parent<<std::endl;
OutputDebugString(ss.str().c_str());

它给了:

Dlg 已创建。 HWND = 0013014A,父级 = 00000000 Dlg 已创建。 HWND = 001B0390,父级 = 0013014A Dlg 已创建。 HWND = 000B03B0,父级 = 001B0390

很明显,问题是对话正在成为彼此的孩子。但问题是,为什么?!似乎 Windows 会自动执行此操作...

这个问题似乎与育儿的主要问题有点距离,所以我尝试将主要问题分离为new question。

【问题讨论】:

【参考方案1】:

听起来第一个对话框已设置为第二个对话框的所有者,第二个对话框已设置为第三个对话框的所有者。您可以更改对话框初始化以显式指定所有者窗口吗?是否有一个有意义的窗口?也许桌面窗口,如果它们都打算是***的?

如果您希望能够访问所有三个(或更多),那么它们需要是无模式的。尝试使用Create(CSomeClass::IDD, CWnd::GetDesktopWindow()),您应该会看到同级对话框,所有这些都显示在任务栏上。

【讨论】:

没有所有者窗口,它是一个 COM .EXE,它根据 COM 请求的指示创建对话框。创建的所有对话框都作为父 HWND 传递 NULL。我同意这看起来像一个育儿问题,但是当我对 COM 接口进行单独的单独调用时,一切都按预期工作......只有当几个一起接收时才会搞砸。 这听起来很奇怪。您可以在OnInitDialog() 中明确地重新设置它们的父级吗? 将 CWnd::GetDesktopWindow() 传递给构造函数没有区别。我会尝试重新育儿。

以上是关于通过COM创建多个MFC对话框,奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

MFC:子对话框行为

MFC,文件新建对话框提示参数和多个文档类型?

mfc 单文档 多文档 对话框 区别

仅启动一个基于 MFC 对话框的应用程序实例

自定义 MFC 窗口/对话框可以是类模板实例化吗?

为啥我的编辑控件在没有使用 MFC 的 win32 c++ 应用程序中看起来很奇怪?