Solved

changing a modal dialog to modalless - VC2008

Posted on 2012-03-26
11
304 Views
Last Modified: 2012-04-17
Hi Experts,

I have inherited some code that creates a modal dialog box.

	//In the menu event handler

	if( m_pCDialogDerivedDlg == NULL  )
	{		
		m_pCDialogDerivedDlg = new CDialogDerivedDlg(this);
		m_pCDialogDerivedDlg->SetShellReference( m_pShell ); 
		m_pCDialogDerivedDlg->Create(CBMTDonorRecipHLAMatchDlg::IDD);
		m_pCDialogDerivedDlg->ShowWindow(SW_SHOW);         
		
	}

Open in new window


This was done using VC++/MFC in VS2006 and ported to VS2008.

Now I have a requirement to make the dialog modalless, so users could intereact with the initiating application while the dialog is still open. What is the easiset way to make the dialog modalless?

thanks in advance.
0
Comment
Question by:olmuser
  • 6
  • 3
  • 2
11 Comments
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 200 total points
Comment Utility
Very interesting question.
The following code will do what you ask for - create and display a modeless dialog.

      if( m_pCDialogDerivedDlg == NULL  )
      {            
            m_pCDialogDerivedDlg = new CDialogDerivedDlg(this);
            m_pCDialogDerivedDlg->SetShellReference( m_pShell );
            m_pCDialogDerivedDlg->Create(CBMTDonorRecipHLAMatchDlg::IDD);
            m_pCDialogDerivedDlg->ShowWindow(SW_SHOW);        
            
      }

Look very carefully - there is NO change made whatsoever.

If your main app isn't responding then it is something else that is stopping it.  Maybe look into the function SetShellReference and see if there is some code which disables the main app window.
0
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 300 total points
Comment Utility
to add to Andy's comment:

modal dialog boxes would have no dlg.Create() call and would be started by dlg.DoModal().

none of the statements you posted does wait. so your current message loop remains responsive (menus, buttons, background formview). if the dialog covers all background you should make it smaller or let the user minimize it.

Sara
0
 
LVL 1

Author Comment

by:olmuser
Comment Utility
you both are right, I think I was confused by the behaviour that the main application does not come to the front if the child dialog is bloking the view, even though minimizing the child does the trick. Is there a way to do that? Bring the parent to the fore groundwithout mimimizing the child? thanks!
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
Is this what you want?

 if( m_pCDialogDerivedDlg == NULL  )
      {            
            m_pCDialogDerivedDlg = new CDialogDerivedDlg();   <<---- No this
            m_pCDialogDerivedDlg->SetShellReference( m_pShell );
            m_pCDialogDerivedDlg->Create(CBMTDonorRecipHLAMatchDlg::IDD);
            m_pCDialogDerivedDlg->ShowWindow(SW_SHOW);        
           
      }
0
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 300 total points
Comment Utility
you could handle the WM_ACTIVATE messsage which would be sent twice in your case. once for the old dialog (window) with wParam is WA_INACTIVE and after for the new dialog (clicked on by the user) with wParam is WA_ACTIVE.

Sara
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 200 total points
Comment Utility
Another point to remember.  The user has performed an action to display this dialog.  If you automatically hide the dialog (eg. by bringing the main window in front of it) then it is likely the user will think the dialog has not been shown and will try again (and again) to show the dialog - eventually saying this program is c**p, it doesn't work properly.

If the dialog completely hides the main window of the app you could consider opening the dialog so it only partially covers the main window.  (look at GetWindowRect and SetWindowPos in help for more info on how you could do that.)
0
 
LVL 1

Author Comment

by:olmuser
Comment Utility
Good point Andy. Could I not check if the dialog has been instantiated already and if so bring it to the foreground if the user my mistake tries to open it again?

thanks both
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
>>Could I not check if the dialog has been instantiated already and if so bring it to the foreground if the user my mistake tries to open it again?

To be honest I thought you were doing that already - because it was a modeless dialog and you had the if statement:
if( m_pCDialogDerivedDlg == NULL  )

Does this do what you want?
if( m_pCDialogDerivedDlg == NULL  )
{
//your code to create the dialog stays here
}
else
  m_pCDialogDerivedDlg->SetFocus();
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
ps.  If you did intercept the WM_ACTIVATE as suggested by Sara then you would need extra code in that function as well.
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
pps.
I hope you have prevented the user destroying this modeless dialog (without resetting the pointer m_pCDialogDerivedDlg to null) , otherwise you have no way to create it a second time.
0
 
LVL 32

Accepted Solution

by:
sarabande earned 300 total points
Comment Utility
to handle deletion//destroying of the modeless dialog properly you could/should handle the WM_NCDESTROY message in that dialog. that message is the last message handled by the derived CDialog object what means you savely could do

void MyModelessDlg::OnNcDestroy()
{
       // send user message to parent dialog 
       GetParent()->PostMessage(MY_WM_USER_MODELESS_DLG_DESTROYED, 0, 0);
       delete this;   // don't do that in another handler but in OnNcDestroy
}

Open in new window


The parent dialog of course needs to pass 'this' as parent argument if you do so. it also would handle the user message (which was defined as a const integer in the range from WM_USER +1 through WM_USER + 0x7ffff) and would set the pointer member to 0 in the handler (do not delete it!!!) .

Sara
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

762 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