Solved

How to create well a Modelles Dialog with MFC?

Posted on 2008-10-11
4
573 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
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.

749 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