Creating multiple MFC dialogs through COM, strange

2019-09-09 13:01发布

问题:

Updated: please see this other thread instead, all this COM stuff is not part of the problem.


One of our apps has a COM interface which will launch a dialog, e.g:

STDMETHODIMP CSomeClass::LaunchDialog(BSTR TextToDisplay)
{
  CDialog *pDlg = new CSomeDialog(TextToDisplay);
  pDlg->BringWindowToTop();
}

For some reason when the COM method is called several times at once by the server, we get odd behaviour:

  • We get multiple dialogs, but only one entry in the taskbar
  • Dialog Z-order is based on order created and can't be changed... the first dialog created is always shown under the 2nd one, 2nd under 3rd, etc, even when you drag them around
  • if N dialogs were created, closing one of them closes it and all the others created afterwards. e.g if 5 dialogsa re created and you close the 3rd one, #3,#4,#5 all get closed.

It's somehow like the dialogs are siblings but I don't see anything weird going on. Is it perhaps due to COM, or is this a weird MFC/Win32 issue?

EDIT: If the interface method is called several times separately, it works as expected. Only when the server component sends several through at once does it seem to mess up. Could threading/timings be to blame?

EDIT2: I put this logging in:

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());

It gave:

  • Dlg created. HWND = 0013014A, Parent = 00000000
  • Dlg created. HWND = 001B0390, Parent = 0013014A
  • Dlg created. HWND = 000B03B0, Parent = 001B0390

So clearly the problem is the dialogs are being made children of each other. But the question is, WHY?! It seems Windows is doing this automatically...

This question seems to be slightly away from the main issue of parenting, so I have tried to separate out the main issue into a new question.

回答1:

It sounds like the first dialog has been set as the owner of the second, and the second as the owner of the third. Can you change the dialog initialization to explicitly specify the owner window? Is there a window that makes sense to assign? Perhaps the Desktop window, if they're all intended to be top-level?

If you want to be able to access all three (or more), then they would need to be modeless. Try using Create(CSomeClass::IDD, CWnd::GetDesktopWindow()), and you ought to see sibling dialogs, all of which show up on the taskbar.



标签: c++ com mfc winapi