ID Number: Q78155
3.00
WINDOWS
Summary:
Applications in the Windows environment are scheduled using a
nonpreemptive multitasking system. Usually, multitasking operating
systems schedule tasks for execution based on some combination of time
slice and/or task priority. However, Windows does not preemptively
switch the processor away from a currently running application under
normal circumstances (excluding interrupts). Instead, multitasking in
Windows is based on the messaging system.
Windows applications must cooperatively offer to yield the processor
on a regular basis to allow Windows to multitask. Normally, an
application offers to yield by calling one of three functions:
GetMessage, PeekMessage, or WaitMessage. An application may also yield
when it calls DialogBox, DialogBoxIndirect, DialogBoxParam,
DialogBoxIndirectParam, MessageBox, or TrackPopupMenu.
More Information:
The GetMessage Loop
-------------------
In the Windows environment, most applications have a central
GetMessage loop that allows the application to cooperate with the
other applications running in the system.
When an application (called "App A") calls GetMessage, the GetMessage
function will return if there are any messages in App A's message
queue. If there are no messages, Windows will give control to another
application that has messages in its queue. If there are no messages
waiting for any application in the system, Windows idles. App A's call
to GetMessage will not return until there is a new message in App A's
queue.
Using this method, the Windows application with control will retain
control as long as messages are waiting in its queue. There is a small
wrinkle to this rule: Windows considers WM_PAINT and WM_TIMER messages
to be low-priority messages. If App A calls GetMessage and has only
low-priority messages in its queue, Windows will pass control to an
application with high-priority messages waiting.
It is important to note that an application can retain control of the
CPU indefinitely if it does not call GetMessage, PeekMessage, or
WaitMessage. However, an application that fails to periodically make
one of these three calls is very impolite, because it is not allowing
Windows to multitask.
Background Processing
---------------------
In the Windows environment, an application can perform a lengthy
processing task and allow Windows to multitask by using either a
PeekMessage loop or a Windows timer. In both cases, the general idea
is the same: break the large processing task into small pieces,
processing one piece at a time and offering to yield at regular short
intervals.
An application can use a PeekMessage loop to perform background
processing because, unlike GetMessage, PeekMessage does not wait for a
message to be placed in the application's message queue before
returning. If there are no messages waiting, PeekMessage returns
FALSE.
A typical PeekMessage loop resembles the following:
while (bDoingBackgroundWork)
{
if PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)
{
TranslateMessage(&msg); // a message is ready - process it
DispatchMessage(&msg);
}
else
{
// PeekMessage returned FALSE, which means no messages ready.
// Do a small piece of background work here.
}
}
The PM_REMOVE flag must be specified in the wRemoveMsg parameter;
otherwise, the application will never yield. PeekMessage will not
yield as long as there are messages in the application's queue. If the
application does not remove and process the messages, PeekMessage may
send the application into an infinite loop.
An application creates a Windows timer with the SetTimer function. An
application can use a Windows timer to do background processing by
setting a timer and doing a small piece of the background job each
time a WM_TIMER message is received or the timer notification function
is called. Even if the application is receiving a steady stream of
WM_TIMER messages, other applications will still have an opportunity
to run because Windows considers WM_TIMER messages to be a low
priority.
It may be necessary to consider two other facts about Windows timers:
they are not asynchronous, and the highest resolution that can be
obtained is about 55 milliseconds.
For more information about background processing in applications
running in the Windows environment, including references to sample
source code, query on the following words in the Microsoft Knowledge
Base:
prod(winsdk) and backproc
For more information on using Windows timers, see Chapter 5, "The
Timer," in Charles Petzold's book "Programming Windows 3" (Microsoft
Press).
Additional reference words: 3.00 3.0 backproc