Solved

How to create well a Modelles Dialog with MFC?

Posted on 2008-10-11
4
567 Views
Last Modified: 2013-11-20
I have a simplest sample to test Modelless Dialog, but Modelless Dialog allways disappear after created

CMainDlg: is main dialog
CModellesDialog : is other dialog

OnButton1: call a CModellesDialog , but CModellesDialog disappear after created!


- This is my simple sample source

void CMainDlg::OnButton1()
{
      // TODO: Add your control notification handler code here
            CModellesDialog dlg;
            dlg.Create(IDD_DIALOG1,NULL);
            dlg.ShowWindow(1);

            AfxMessageBox(".... if remove this AfxmessageBox, dlg modelles will also close");

}

How to keep CModellesDialog concurrent with MainDialog?
0
Comment
Question by:star6868
4 Comments
 
LVL 55

Accepted Solution

by:
Jaime Olivares earned 125 total points
ID: 22696394
this is a typical problem:

void CMainDlg::OnButton1()
{
            CModellesDialog dlg;     // Dialog object is constructed
            dlg.Create(IDD_DIALOG1,NULL);     // Dialog object is created
            dlg.ShowWindow(1);  // dialog is shown
}  // Dialog object is destroyed

The problem is that you are instantiating directly the dialog objects at the OnButton1 event.
You can a couple of choices, like:

void CMainDlg::OnButton1()
{
            CModellesDialog  *dlg = new CModellesDialog();     // Dialog object is dynamically constructed
            dlg->Create(IDD_DIALOG1,NULL);     // Dialog object is created
            dlg->ShowWindow(1);   //  dialog is shown
}  // dialog not destroyed

or, put CModelles dlg as a class' member and crete at the OnButton1() event:

void CMainDlg::OnButton1()
{
            /////// CModellesDialog dlg;     // Dialog set as a class member
            dlg.Create(IDD_DIALOG1,NULL);     // Dialog object is created
            dlg.ShowWindow(1);   // dialog is shown
}  // Dialog object is not destroyed


0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 125 total points
ID: 22704908
You should have a class member *pointer* to the modeless dialog.

Otherwise you could create it only once.  

void MyFirstDlg::OnClickedButtonStartModeless()
{
       // don't create the modeless twice
       if (m_pDlgModeLess != NULL) return;

       m_pDlgModeLess = new MyModelessDlg();
       m_pDlgModeLess->Create(IDD_DLG_MODELESS, this);
       m_pDlgModeLess->ShowWindow(SW_SHOW);
 }  

In the destructor of the first dialog you should send a WM_CLOSE message to the modeless dialog in case it is still active. Then you could have a handler for WM_NCDESTROY of the modeless dialog which looks like

void MyModelessDlg::OnNCDestroy()
{
      CWnd* pParent;
      if ((pParent = GetParent()) != NULL)
      {
           // set the member pointer of the parent to NULL
           ((MyFirstDlg*)pParent)->m_pDlgModeLess = NULL;
           // then delete own instance. It is safe cause that is the very last
           // statement for that CWnd instance
           delete this;
      }
}

With the above the user could actively terminate the modeless dialog or it is terminated with the parent dialog:

MyFirstDlg::~MyFirstDlg
{
     if (m_pModelessDlg != NULL)
     {
           m_pModelessDlg->SendMessage(WM_CLOSE);
           Sleep(500);  // wait a little while in case the WM_NCDESTROY
                                // was sent asynchronously
     }
     
}

The Sleep is only for safety. With newer compilers (later than VC6) it shouldn't be necessary.


       
delete the dialog pointer in case it is not already deleted.


0
 
LVL 1

Expert Comment

by:muttley3141
ID: 22715442
You have put your modeless dialog as a local variable inside the handler. This means that when the handler exits (pressing OK on your message box), the local variable goes out of existence, so the dialog's destructor is called.

You need to construct/create your modeless dialog outside your handler, so that it continues to exist when the handler exits.

The way I usually do it is to have a private membervariable of CMainDialog being a pointer to your CModellesDialog.

class CMainDialog
{
..
..
private:
  CModellesDialog *pmd;
..
}

In your constructor, have:
CMainDialog::CMainDialog(...)
{
..
pmd = new CModellesDialog(...)
..
}

In your CMainDialog::OnInitDialog()
CMainDialog::OnInitDialog()
{
  pmd->Create(...);
  pmd->ShowWindow(SW_SHOW);
}

That will give you a modeless dialog that exists for the lifetime of the program.

However, that's probably not what you want. Instead, take out the ShowWindow() line above and put it in as a response to your button-press handler.

You will naturally need two buttons: one to show the dialog and another to hide it.

Doing it this way means that the dialog exists all the time the program does, consuming resources. However, this can be beneficial if you want the dialog to retain state all the time.

You could really have the "pmd" member variable as the Modeless dialog itself, rather than a pointer to it. Then you wouldn't have to do any newing, just creating.

If you don't want a dialog to exist all the time, then you'll have to go through the new/create/delete cycle whenever your button-presses require it.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now