Re: What are the difference between GetMessage() and PeekMessage()?
"Joseph M. Newcomer" <newcomer@flounder.com> wrote in message
news:885rn2lh32q416h6fq3furrgoqeovtvnlf@4ax.com...
In addition, it is nearly always the case that the use of PeekMessage
indicates an
architectural failure in the design. There are reasons to use
PeekMessage, but most of
the time when it is done, it was because the programmer was trying to do
some long
computation which blocked the GUI thread and is trying to make sure that
user interaction
is handled. This is an old Win16 idiom (where it was necessary), but no
new code should
be written using this technique; instead, threads should be used for long
computations.
Besides producing very convoluted code, which sometimes doesn't even work
right,
PeekMessage actually imposes some significant overheads which serve to
slow the
computation down. Possibly by a small percentage, possibly by a large
multiplier,
depending on how badly done it is. I use the presence of PeekMessage as a
strong
indicator that there is a serious design problem in the application. It
is often account
for by people who never outgrew Win16.
It is true this kind of GetMessage loop can cause re-entrancy issues, but I
wish Windows had a better way of pumping messages while an event handler
waits for a long process to end. As it is, it's mighty inconvenient. For
example, this simple code:
CMyWnd::OnMyHandler(WPARAM wParam, LPARAM)
{
ExecuteLongProcess();
// Pump messages to UI remains responsive until long process ends
do
{
if ( PeekMessage() )
{
GetMessage();
DispatchMessage();
}
Sleep (100);
} while ( LongProcessIsStillRunning() );
// Continue event handling after long process completes
AfxMessageBox ("Long process has completed while not freezing up your
entire window");
}
needs to be replaced with:
CMyWnd::OnMyHandler(WPARAM wParam, LPARAM)
{
// Start long process on it's own thread
AfxBeginThread ( LongProcessThread, GetSafeHwnd() );
}
static UINT CMyWnd::LongProcessThread(LPVOID pParam)
{
ExecuteLongProcess();
// Notify main thread that long process is done
::PostMessage ( (HWND) pParam, UWM_MYWND_LONGPROCESS_DONE );
}
CMyWnd::OnLongProcessDone(WPARAM wParam, LPARAM)
{
// Continue event handling after long process completes
AfxMessageBox ("Long process has completed while not freezing up your
entire window");
}