views:

321

answers:

6

I need to open a dialog box instantiated from the same class twice. When I try this

CdelmeDlg dlg;
dlg.DoModal();
dlg.DoModal();

The second call opens the dialog only for a split second, then it is closed. My bet was there is a leftover message in the message queue, so I added this in between the calls

MSG msgCur;
while (::PeekMessage(&msgCur, NULL, NULL, NULL, PM_REMOVE))
 ;

This solves the problem, but it feels like a wrong kind of thing to do. Is there a way to process the leftover message properly?

+1  A: 

Don't call EndDialog( IDOK );

To handle the ok or cancel buttons being pressed just inherit OnOk or OnCancel ... Otherwise EndDialog is going to be called twice and you'll get the problem you are getting!

Goz
A: 

Sorry for adding this as an answer, but I created the original question as an anonymous user and my cookies were deleted when I closed the browser, therefore stackoverflow doesn't let me edit the answer or add comments.

Goz: I can verify that void CDialog::EndDialog(int) is getting called only once by placing a breakpoint at the function body in dlgcore.cpp. I have already tried inheriting OnOK and OnCancel as I stated in the comments.

Blake7: The message that closed dlg also closes dlg1. The end result is the same as I described in the question

MMx
A: 

If you want your application run in background without UI, why not juz temporary hide it? a simple function this->ShowWindow(SW_HIDE) will do the job for you.

i think you should revise your design decision as it seem illogical for an application to behave like what you wanted it to be.

YeenFei
A: 

I actually think that YeenFei has a good point here.

It's been a while since i've played with MFC (thank goodness), but from memory, a timer, may or may not be called from the UI thread depending on which one you use. If the timer is being raised on the main UI thread, then a modal dialog will likely halt the main thread until it is dismissed, after which it would be called by the next timer. If the timer is raised on a separate thread, then your dialog is not blocking the main UI thread as it is being shown on a separate thread.

It's does seem more conceivable as YeenFei has pointed out that you want to re-show your dialog each time the timer is raised, hiding it when the user clicks on the button to dismiss it. That way, if the time is raised again, all it does is re-show the dialog whether it is currently open or not.

There is a great post here (www.eggheadcafe.com) about Timers and concurrency that you may find interesting, and may make things clearer than what I managed to accomplish.

System.Exception
A: 

Why can't you code it like this:

CdelmeDlg dlg; 
dlg.DoModal(); 

CdelmeDlg dlg1; 
dlg1.DoModal(); 
Blake7
A: 

I solved the problem by hiding the dialog instead of closing it and launching another thread that first sleeps and then unhides the dialog.

MMx