I have a computationally intensive task in a program and used
BeginWaitCursor() and EndWaitCursor() pair to indicate that the
program is running (based on shape change of mouse pointer when moving
it on the top of the dialog). To avoid a dialog refresh problem, I
insert the MessageLoop() routine within the loop as shown below. By
doing so, however, the BeginWaitCursor() does not work anymore, at
least I could see it is working because the shape of mouse pointer
does not change any more if I move it on the top of the dialog.
Could you please advice and how can I avoid that? Thank you very much.
Frank
void CTest::OnOK()
{
UpdateData(TRUE);
BeginWaitCursor();
for (int i = 0; i < 50000; i++)
{
for (int j = 0; j < 50000; j++)
{
ProcessingJobA();
}
MessageLoop();
}
EndWaitCursor();
CDialog::OnOK();
}
void MessageLoop()
{
MSG Msg;
while (PeekMessage(&Msg,NULL,0,0,PM_REMOVE))
{
if (!AfxGetApp()->PreTranslateMessage(&Msg))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
}
You need to override WM_SETCURSOR. Read "A Persistent Wait Cursor" at
http://www.thecodeproject.com/dialog/persistentwaitcursor.asp
Incidentally, in your MessageLoop function, rather than mimicking the work
done by CWinThread::PumpMessage(), why not simply call it. In other words,
while ( ::PeekMessage( &iMsg, NULL, NULL, NULL, PM_NOREMOVE ) )
{
::AfxGetThread()->PumpMessage(); // pump messages until queue
is empty
}
Regards,
Mike
"frank" <ocean...@hotmail.com> wrote in message
news:c21b5fc6.0408...@posting.google.com...
If you have some long computation that needs a live GUI, it is considered best practice to
perform it in a thread, rather than using the quaint PeekMessage method, which is a
concession 16-bit Windows made to support pseudo-multitasking. If you don't need a live
GUI, why are you doing PeekMessage? Given this is an OnOK handler, there is nothing can be
activated in the GUI until you complete (excluding background messages such as timer
messages, asynchronous network messages and the like. But if you need these responsive,
the correct approach is to use a thread). Note that the complete absence of a PeekMessage
does not limit your ability to do anything else to any other app while the long loop is
running (only in 16-bit Windows was this an issue, and that system is very, very, dead)
A better strategy would be to have your OnOK handler launch a thread, disable the dialog,
and simple return without calling the CDialog::OnOK handler. When the thread completes, it
notifies the GUI that it has finished, and at that point you call the OnOK handler to
terminate the dialog. And this is only if you have some reason to need a live message pump
(note that for many reasons having a pseudo-live message pump that is only activated by
polling in a long loop will either result in a vastly slower loop than required, just to
do the polling, or uncontrollable delays based on how infrequently the polling is done)
If you must use such antiquated methods, then you must do your own OnSetCursor handler,
and expicitly set the cursor to the wait cursor whenever some flag you set says that you
should display the wait cursor.
joe
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm