I want to show a modeless dialog on the screen and display some information in it.
However if I use it the following way, it has some problems:
function()
{
showdialog(XXX).
//heavy work.
update the dialog..
//heavy work.
update the dialog...
}
It seems the dialog displayed, but it does not draw any information in it. It only draw all information when the function is over.
How can I modify the modeless dialog so it will display the information immediately?
To create a modeless dialog box, call your public constructor and then call the dialog object's Create member function to load the dialog resource. You can call Create either during or after the constructor call. If the dialog resource has the property WS_VISIBLE, the dialog box appears immediately.
Modal dialog boxes, which require the user to respond before continuing the program. Modeless dialog boxes, which stay on the screen and are available for use at any time but permit other user activities.
The difference between a modal and modeless dialog box is that, modal dialogs once invoked will not allow the users to access the parent window, whereas modeless dialogs will allow the user to work with the parent window.
To create a modal dialog box, call either of the two public constructors declared in CDialog. Next, call the dialog object's DoModal member function to display the dialog box and manage interaction with it until the user chooses OK or Cancel. This management by DoModal is what makes the dialog box modal.
There are a few things you can do.
(1) You could post the dialog a message from inside the CDialog::OnInitDialog method and then handle the long function in the message handler of that posted message. That way the dialog will first be displayed and then later the long function will get run.
(2) The second option is to make sure the message loop gets some processing time. So if your long function is some sort of loop just add the occasional call to the ProcessMessages to make sure the message queue is kept empty:
void ProcessMessages()
{
MSG msg;
CWinApp* pApp = AfxGetApp();
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
pApp->PumpMessage();
}
}
Edit: It certainly is possible to use threads is such a situation, but doing so is not always without risk and complexity.
Using threads with a GUI means having to deal with multiple message queues which then means using API's like PostThreadMessage and that introduces a new set of issues to be wary of.
For an example of one such issue refer to this link:
http://msdn.microsoft.com/en-us/library/ms644946(VS.85).aspx
where is says:
Messages sent by PostThreadMessage are not associated with a window. As a general rule, messages that are not associated with a window cannot be dispatched by the DispatchMessage function. Therefore, if the recipient thread is in a modal loop (as used by MessageBox or DialogBox), the messages will be lost. To intercept thread messages while in a modal loop, use a thread-specific hook.
I use the process message approach in the Zeus IDE and it works very well at making sure the GUI remains responsive to the user. It is also has the advantage of being very easy to implement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With