|
|
Win32 Message Processing PrimerA Tutorial on the Differences Between Getmessage and PeekmessageA message processing tutorial article for Win32 programmers illustrating the difference between GetMessage and PeekMessage inside and outside the message processing loop
IntroductionIn this GetMessage vs. PeekMessage tutorial we look at the difference between the two function calls, and how they can be used practically when writing Win32 applications. The tutorial is language independent, but we have used C calling conventions for illustration purposes. Please refer to your compiler / development kit documentation for details on how to interface with the Windows library routines supplied with your development environment. The Message LoopThe Windows message loop is part of the WinMain function called when the application starts up. Its job is to:
The loop itself looks something like: while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } The TranslateMessage and DispatchMessage functions process the incoming message, in the first instance translating any accelerators, and in the second passing the message to the message processing function specified in the WNDCLASS member lpfnWndProc. This is usually set to the WndProc function. GetMessageThe GetMessage function returns nonzero as long as the WM_QUIT message is not retrieved from the message queue. Hence, it can be tested as in the message processing loop and provide an exit from the loop before the WM_QUIT message is processed. Subsequently, if there is any processing that needs to be done upon program exit, it must be done before the WM_QUIT message is placed on the queue. GetMessage also takes four parameters:
The filtering system allows the programmer to use pre-defined constants such as WM_MOUSEFIRST and WM_MOUSELAST to retrieve only (in this instance) mouse messages. These are not much help in the message loop, however. Since GetMessage removes messages from the queue, it is usually only ever found in the message loop. It does not remove WM_PAINT messages, however, which remain in the queue until they are processed. All other messages are removed, whether they are processed or not. By way of contrast, let us look at the PeekMessage function. PeekMessageThe PeekMessage function allows the program to look at the message queue, retrieve messages, but not necessarily remove them. It returns zero if there are no messages on the queue, or nonzero if messages are available. PeekMessage takes 5 parameters:
The additional parameter can be set to PM_REMOVE or PM_NOREMOVE to indicate whether a message should be removed or not. Subsequently, we could re-write the message loop using PeekMessage as follows: do { if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } } while (msg.message != WM_QUIT); This approach is presented here by way of illustration, and is not recommended. Like GetMessage, PeekMessage will not remove a WM_PAINT message from the queue, even if instructed to do so. Unlike GetMessage, there is an exception - if the update area is null, then PeekMessage will remove the WM_PAINT message if PM_REMOVE is specified. Outside the Message LoopIf a programmer needs access to the message queue outside of the message loop, then they should only ever use PeekMessage, and be very careful about removing messages from the queue. The key difference between Windows pre-Win32 and Win32 programming is that since software applications run concurrently in Win32, there should be no need to look into the message queue at all. This is illustrated by the WinWord.exe application, which used to use a PeekMessage loop to wait for incoming messages rather than an idle loop (message loop). This method consumes 100% of the CPU resources allocated to it, as it is caught in a busy-waiting loop; PeekMessage returns zero until a message is available. Pre-Win32 this could cause the machine to hang, were it not for the fact that the PM_YIELD flag was set in the wRemoveMessage paremeter (PM_REMOVE|PM_YIELD). With the advent of Win32 however, PM_YIELD becomes obsolete as all applications run concurrently. However, older versions of WinWord may use 100% of their time slice, due to the fact the the PM_YIELD flag is no longer recognised. This is the risk of using PeekMessage outside the message loop. Links
The copyright of the article Win32 Message Processing Primer in Windows Programming is owned by Guy Lecky-Thompson. Permission to republish Win32 Message Processing Primer in print or online must be granted by the author in writing.
|
|
|
|
|
|
|
|