Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

changing a modal dialog to modalless - VC2008

Posted on 2012-03-26
11
Medium Priority
?
338 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:Mydeen Yussouf
  • 6
  • 3
  • 2
11 Comments
 
LVL 45

Assisted Solution

by:AndyAinscow
AndyAinscow earned 800 total points
ID: 37770167
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 35

Assisted Solution

by:sarabande
sarabande earned 1200 total points
ID: 37770478
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:Mydeen Yussouf
ID: 37777718
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 45

Expert Comment

by:AndyAinscow
ID: 37777819
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 35

Assisted Solution

by:sarabande
sarabande earned 1200 total points
ID: 37777890
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
 
LVL 45

Assisted Solution

by:AndyAinscow
AndyAinscow earned 800 total points
ID: 37778001
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:Mydeen Yussouf
ID: 37778041
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 45

Expert Comment

by:AndyAinscow
ID: 37778070
>>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 45

Expert Comment

by:AndyAinscow
ID: 37778076
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 45

Expert Comment

by:AndyAinscow
ID: 37778088
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 35

Accepted Solution

by:
sarabande earned 1200 total points
ID: 37780482
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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
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…
Suggested Courses

569 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