Search code examples
c++mfccdialog

How can I display a nested CDialog within another CDialog?


I have two CDialog classes that I have created. Let's call them MainDialog and ExtraDialog. I want ExtraDialog to be able to be displayed both through doModal and as a nested dialog within MainDialog.

I can already bring it up separately through a Button and doModal. However, I've been stuck about how to place it within MainDialog.

CWnd* m_pWndStatic = new CWnd;
m_pWndStatic->Create(_T("Something"), _T("Title"), WS_CHILD | WS_VISIBLE, CRect(x, y, xEnd, yEnd), this, idWnd);

CExtraDialog* dlg = new CExtraDialog;
dlg->Create(IDD_NEW_DIALOG, this); //Or second variable can be m_pWndStatic?
//dlg->SetWindowPos(m_pWndStatic, x, y, xEnd, yEnd, SWP_NOZORDER | SWP_NOACTIVATE);
//dlg->Invalidate();
//dlg->ShowWindow(SW_SHOW);
//m_pWndStatic->ShowWindow(SW_SHOW);

Above I shared some of the thigns I have tried. I was hoping to create a CWnd and put the dialog inside the CWnd but I feel like I am missing something and I couldn't really find anything helpful online.

Edit: I am basically trying to put multiple CWnds into one CDialog, and having the CWnd's run different functionalities from different classes. Kinda like putting lego blocks together.

Edit2: I found a question that is kinda similar? I hope to make it similar but I just don't want buttons and I want two of them get displayed at once. Embedding dialogs in main dialog and switching them with button click in MFC


Solution

  • I've been stuck about how to place it within MainDialog.

    At the minimum, remove WS_POPUP, WS_CAPTION and WS_SYSMENU styles. Add the WS_CHILD style.

    It is highly recommended to add the WS_EX_CONTROLPARENT extended style to enable keyboard navigation into and out of the embedded dialog.

    For example, in OnInitDialog() of the parent dialog you could add:

    // Note: Create member variable CExtraDialog, so there is no need for dynamic allocation!
    m_extraDlg.Create( IDD_NEW_DIALOG, this );
    
    // Adjust styles. 1st parameter removes, 2nd adds.
    m_extraDlg.ModifyStyle( WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME, WS_CHILD );
    
    // Adjust extended styles. 1st parameter removes, 2nd adds.
    m_extraDlg.ModifyStyleEx( WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE, WS_EX_CONTROLPARENT );
    
    // As we have changed the frame, we let Windows recalculate the non-client area
    // by passing the SWP_FRAMECHANGED flag to SetWindowPos().
    m_extraDlg.SetWindowPos( nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | 
         SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
    

    I was hoping to create a CWnd and put the dialog inside the CWnd

    I recommend to always use a CDialog-derived class as the parent of an embedded dialog. This ensures best compatibility with the Windows dialog manager for features like standard keyboard navigation. You will work with the system, not against it.

    More to read: