tags:

views:

41

answers:

1

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.

A: 

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.

jwismar
There is no owner window, it's a COM .EXE which creates dialogs as instructed through COM requests. All dialogs created are passed NULL as parent HWND. I agree it looks like a parenting problem, but when I make separate individual calls into the COM interface, all works as expected... only when several are received together does it mess up.
John
That does sound odd. Can you explicitly re-parent them in `OnInitDialog()`?
jwismar
Passing CWnd::GetDesktopWindow() to the constructor makes no difference. I'll try re-parenting.
John