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
Solved

changing a modal dialog to modalless - VC2008

Posted on 2012-03-26
11
313 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
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 33

Assisted Solution

by:sarabande
sarabande earned 300 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:olmuser
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
How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

 
LVL 44

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 33

Assisted Solution

by:sarabande
sarabande earned 300 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 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 200 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:olmuser
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 44

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 44

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 44

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 33

Accepted Solution

by:
sarabande earned 300 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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying 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

Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
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…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

856 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