Solved

How to create well a Modelles Dialog with MFC?

Posted on 2008-10-11
4
570 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

Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
bobThere java chalenge 45 92
string initialization in java 11 113
VBA "SendKeys" Syntax for Multiple Keystrokes 7 108
Problem to event 3 96
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
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.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

772 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