Modeless child dialog in a Main Dialog with corrected tab order

This article was written to help the programmer put a modeless child dialog "into" another dialog and maintain the proper tab order for the new combination.

 

Normally when a modeless child dialog is created and placed in a parent dialog, the tab order follows the parent dialog. This is illustrated in the in the following picture. The first tab item (5) of the child dialog follows the last tab item of the parent (4)

 

What we would like to have is the first child tab item following the control of choice in the main dialog:

 

To perform this feat is fairly simple but if you dont know how to do it you may spend quite a few hours coding pretranslate messages and setting focus to controls.

 

Step 1: Create the Main dialog and the child dialog using the dialog editor. Create classes for the dialogs using the class wizard. Then change some properties of the child dialog:

The child dialog will have the "child dialog" and the "control" style. Note: I have set the border to thin, but in this example the border will not show up because of the control style.

Using the dialog editors properties dialog, set the CHILD dialog styles as follows:

 

You will also have click on the More Styles tab and set the "control" style:

 

To make the child dialog show up exactly where is designed to show up on the main dialog, the X,Y locations in the general tab can be set. The child dialog will show up in this application at X = 23 and Y = 36.

 

 

Step 2:

The program will compile now and it will run, but the child dialog will not show up on the main dialog. You will have to place an instance of the child dialog in the main dialog class. Include the header file for the child dialogs class and create a member variable for the child dialog:

#include "ChildDialog.h"

class CDlgSampleDlg : public CDialog
{
   CChildDialog m_child;

 

Since the child dialog will need a CWnd pointer in the constructor you will have to place the m_child variable in the constructor for the main dialog.

CDlgSampleDlg::CDlgSampleDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgSampleDlg::IDD, pParent),
	m_child( this )
{
	// Dialog constructor code
}

The next coding you will perform is a call to Create via the child dialog member variable in the OnInitDialog function of the main dialog. Dont forget to show the window after you create the child dialog

BOOL CDlgSampleDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

   m_child.Create( IDD_CHILD_DIALOG, this );
   m_child.ShowWindow( TRUE );

 

At this point the project should compile and run. However the tab order will not be what we originally set out to correct. To fix the tab order the following code will have to be inserted at the end of the OnInitDialog function:

	// TODO: Add extra initialization here

   CWnd * pWnd = GetDlgItem( IDC_CONTROL_1 );
   UINT nFlags = SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE;

   ::SetWindowPos( m_child.m_hWnd, pWnd->m_hWnd, 0, 0, 0, 0, nFlags );
   return TRUE;
}

 

The ID "IDC_CONTROL_1" is the control in the main dialog that will be just before the first tab order item in the child dialog.

 

Compile the program, run it and tab through the controls the child dialogs controls will follow the correct tabbing order as expected.

Download demo project - 5 KB

Download source - 12 KB



Comments

  • How can i create a window without the move property from system menu

    Posted by Legacy on 01/27/2004 12:00am

    Originally posted by: hector

    I need to know how can i create a window whith:
    - when i click on the caption the window do not move

    Reply
  • Help, I cant see the dialogs

    Posted by Legacy on 11/15/2001 12:00am

    Originally posted by: AMW

    It seems straightforward enough, maybe I should consider a different hobby or something.
    I'm trying to do this in a dialog bar of an SDI application.
    I've gotton everything typed in and compiling allright, but when I execute the program, I don't see the child dialogs in the static control.
    I'm still kind of new to MFC and any help would really be appreciated.
    Thanks in advance

    Reply
  • Dialog isn't shown in Propertypages

    Posted by Legacy on 08/10/2001 12:00am

    Originally posted by: Thomas Faust

    This Sample is very good and i used it in same Dialogs.
    BUT.. In tried to use a dialog in a Propertypage. I wrote a function move the "inlay"-dialog when the Propertysheet is moved. If the "inlay"-dialog is initialisiert with the Propertypage (or the Propertysheet) and declared as childdialog the SetWindowPos-function will fail.
    Can anybody help?

    Reply
  • tab order does not work correctly with msflexgrid control in child dialog

    Posted by Legacy on 06/14/2001 12:00am

    Originally posted by: varsha

    Tab order does not work correctly with msflexgrid(activex control) control in child dialog. The only difference is the window style(WS_OVERLAPPED). 
    

    Reply
  • Modeless Dialog box using ATL

    Posted by Legacy on 06/14/1999 12:00am

    Originally posted by: paripally

    How can i do it with ATL. I have problem in putting correct tab order.
    thanks,
    Gopal

    Reply
  • this is not needed.

    Posted by Legacy on 06/12/1999 12:00am

    Originally posted by: jingwu

    m_child.Create( IDD_CHILD_DIALOG,this);

    the above sentence can be
    m_child.Create( IDD_CHILD_DIALOG); this is better in c++

    Reply
  • How to do this in 16 bit

    Posted by Legacy on 06/09/1999 12:00am

    Originally posted by: Hans Straub

    In 16 bit (MSVC 1.52), there is no "control" check box in the resources so some work-around is
    necessary.
    
    

    As suggested by Paul McKenzie in the dialog forum, it can be done by overriding the PreTranslateMessage() function.
    The following code sketches implement the functionality for the TAB key. An extension that copes with the SHIFT-TAB key should be easy.


    I define the following member variables in CChildDialog:

    class CChildDialog : public CDialog
    {

    ....

    CWnd* m_pFirstCtrl; // First control of child dialog
    CWnd* m_pLastCtrl; // Last control of child dialog
    CWnd* m_pParentPrevCtrl; // Last control before child dialog in parent dialog
    CWnd* m_pParentNextCtrl; // Next control after child dialog in parent dialog

    ...

    }

    The m_pFirstCtrl and m_pLastCtrl pointers are set to the appropriate dialog items in CChildDialog::OnInitDialog(),
    the m_pParentPrevCtrl and m_pParentNextCtrl pointers in the parent dialog's OnInitDialog() function (via calls to GetDlgItem()).

    I then derive the PreTranslateMessage() routines in the following way:


    BOOL CChildDialog::PreTranslateMessage(MSG* pMsg)
    {
    if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB)
    {
    // If focus is on m_pLastCtrl: set focus to parent
    if ( pMsg->hwnd == m_pLastCtrl->m_hWnd )
    {
    GetParent()->SetFocus();
    ((CDialog*)GetParent())->GotoDlgCtrl(m_pParentNextCtrl); // Or GetParent()->NextDlgCtrl() XXX

    return TRUE; // No more processing
    }
    }

    return CDialog::PreTranslateMessage(pMsg);
    }


    and


    BOOL CDlgSampleDlg::PreTranslateMessage(MSG* pMsg)
    {
    if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB)
    {
    // If focus on last item before subdlg:
    // go to subdlg
    if ( pMsg->hwnd == m_child.m_pParentPrevCtrl->m_hWnd )
    {
    m_child.m_hWnd .SetFocus();
    m_child.GotoDlgCtrl(m_child.m_pFirstCtrl);
    return TRUE; // No more processing
    }
    }

    return CDialog::PreTranslateMessage(pMsg);
    }

    Reply
  • Child Dialog do not get focus

    Posted by Legacy on 05/12/1999 12:00am

    Originally posted by: nrusinh

    If dialog style is "child" & dialog is created with Create() & displayed using
    ShowWindow(), this dialog does not get focus. All message of this dialog are sent to parent. How to solve
    this problem. Please E-Mail - nrusinh@hotmail.com
    

    Reply
  • The child dialog does not process the enter key correctly when focus is on a button

    Posted by Legacy on 12/11/1998 12:00am

    Originally posted by: Qing Dong

    If there are buttons on the child dialog, the ENTER key is 
    
    not processed correctly when one of the buttons has focus.

    I got around this problem by the following code:

    BOOL CChildDialog::PreTranslateMessage(MSG* pMsg)
    {
    // TODO: Add your specialized code here and/or call the base class
    if (pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN){
    CWnd* pWnd=GetFocus();
    if (pWnd && IsChild(pWnd)){
    LONG lStyle = ::GetWindowLong(pWnd->m_hWnd, GWL_STYLE);
    // if the focus is one a button and ENTER key is pressed
    // click the button
    if (lStyle & BS_DEFPUSHBUTTON)
    return SendMessage(WM_COMMAND, pWnd->GetDlgCtrlID(),
    BN_CLICKED);
    }
    }

    return CDialog::PreTranslateMessage(pMsg);
    }

    Is this the right way to solve this problem? I keeping thinking
    there should be a much easier way. Thanks.

    Reply
  • HOWTO:Stop warning during a compile

    Posted by Legacy on 11/11/1998 12:00am

    Originally posted by: Jeremy Davis

    Using

    CDlgSampleDlg::CDlgSampleDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CDlgSampleDlg::IDD, pParent),
    m_child( this )

    causes the following warning...

    warning C4355: 'this' : used in base member initializer list

    To cure this instead use

    CDlgSampleDlg::CDlgSampleDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CDlgSampleDlg::IDD, pParent),
    m_child( pParent )


    Great expanation by the way...

    Jeremy

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date