1

So I have my main dialog that calls modeless dialogs through this function (this is the legacy code on the project):

void MyClass::ShowDialog(CDialog* dialog)
{
    if (!IsWindow(dialog->m_hWnd))
    {
        return;
    }

    int nCmdshow1 = dialog->IsWindowVisible() ? SW_HIDE : SW_SHOW;
    dialog->ShowWindow( nCmdshow1 );
}

Problem: all sub dialogs stay on top of my main dialog.
Desired behavior: whichever's focused (they are all modeless), be it the main dialog, or sub dialogs, I want it to be the topmost dialog. Thank you!

Note: I already tried on my main dialog's OnInitDialog() these but didn't work:
1. SetWindowPos(&this->wndTop,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
2.SetWindowPos(&this->wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);

EDIT
Also, sub dialogs are created this way:
m_subDlg1->Create( SubDlg1::IDD, this );

1 Answers1

0

As long as there is an owner relation between two windows. the owner of a window can never be on top of the owned window.

Windows in an owner, parent, child relation always behave the same. The owned/child window is always on top of the parent/owner.

If you want to break this, you have to break the owner/child relation. Let all dialog windows have no owner... than they may float freely.

But: I will expect the you program doesn't behave better. Even worse. User might search windows that are deep below covered under other windows. And they will never get in front, when your program gets active.

See the description about parent/child/owned windows here. Also this article might be helpful.

Edit: The problem is that internally the MFC sets the main window as an owner if no parent is given. Only the call to BOOL Wnd::CreateDlgIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd* pParentWnd, HINSTANCE hInst) allows to leave pParentWnd NULL.

So you may create the window as normal, but use SetParent(NULL) after it was created. Again the MFC ASSERTs this. SO you may use the API function and the handle of your dialog.

xMRi
  • 14,982
  • 3
  • 26
  • 59
  • Thanks for the answer. It's just that, I came from C#, particularly WinForms, and it's the default behavior. I wonder what good will MFC do in our team's projects in a long-term context. Anyways, how should I break the owner/child relationship? Is my way of showing/creating dialogs incorrect if I want the said behavior? – Alan Gorsuch Sep 26 '17 at 07:15
  • Don't pass the parent window handle to the create call. – xMRi Sep 26 '17 at 07:39
  • I'm afraid it still behaves the same after removing 'this' in the Create call. It is the case on the current project and a newly created test project, meaning source code is as I have shown in the question: calling `ShowDialog()` and call to `Dialog.Create()`. – Alan Gorsuch Sep 26 '17 at 08:05
  • OK. The problem is that internally the MFC sets main window as an owner if no parent is given. Only the call to BOOL Wnd::CreateDlgIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd* pParentWnd, HINSTANCE hInst) allows to leave pParentWnd NULL. I changed my answer. – xMRi Sep 26 '17 at 08:59
  • Debug into the Create code and you see the behavior. – xMRi Sep 26 '17 at 09:05
  • The OP is familiar with the Winforms designer. So the *real* question is almost surely "how do I use the dialog resource editor to create a normal window". – Hans Passant Sep 26 '17 at 09:21
  • So I did try it and it worked as expected. I just want to confirm something: it seems to me that `GetParent()` is the partner getter method of `SetParent()`, and we use `GetParent()` in the subdialogs. So far it does not produce any errors, but is it really safe that I have `SetParent(NULL)` and at the same time `(MyParentDialog*)GetParent()` ? – Alan Gorsuch Sep 28 '17 at 07:34
  • No. If you use SetParent NULL you can't relay on GetParent return something of worth. But you are free to use your own separate pointer in a data member, to the main dialog class, that has not such a function like the "parent-window". – xMRi Sep 28 '17 at 08:57