A message pump or message loop retrieves and dispatches all messages for its task, that is for a running application in the WinMain function( in the Power++ framework the message loop is inside the Run method of WApplication. The WApplication class is not published by Sybase). For a modal dialog, created by DialogBox( called by the Power++ Create method), the message loop is inside the DialogBox routine. DialogBox creates all the dialog windows, then falls into a message loop, retrieving and dispatching messages until the dialog is dismissed with EndDialog.

Modeless dialogs messages are retrieved and dispatched by the application's own message loop. Power++ installs for every modeless dialog a message filter for keyboard and mouse messages, that calls the dialog manager( IsDialogMessage() ). Also Power++ installs for every form a message filter, that translates the accelerators and for every window a message filter for performing the drag and drop functions; this message filter calls also the virtual member FilterMessage( WMessage &msg, WBool & eatMessage). If you process the message, set eatMessage to true and return true.

The message filter is a wrapper class to the windows hook 'WH_GETMESSAGE'. See win32 online help "GetMsgProc"

while( GetMessage(  ))
{
  if( TranslateAccelerator())
    continue;
  else if( IsDialogMessage())
   continue
  else
  {
    TranslateMessage();
    DispatchMessage();
  }
}

GetMessage

GetMessage looks for posted messages at first, if it doesn't find any, it looks for the quit flag, to see whether PostQuitMessage was called. If that flag is clear, it checks the system queue for events. If it still hasn't found a message to process, it looks at the paint flags to see whether any of the windows have a invalid pixels. If it find one, it returns with WM_PAINT message for the window that contains invalid pixels. If all the windows are completely valid, it checks the timer flags und returns with a WM_TIMER message if it finds one that's set.
If it doesn't find a message to process, it starts over again; it won't return until it finds a message to process.
This retrieval order means that the message queue is flushed before the quit flag is even looked at.mouse and keyboard input are not checked unless the quit flag is clear. Also, if it returns with WM_PAINT message, you know there is no pending mouse or keyboard input. Finally timers are checked only if there are no other pending messages.The message retrieval algorithm goes straight to timer flags after it finds, that all the paint flags are clear.

TranslateAccelerator ( TranslateMDISysAccel for MDI document windows )

pulls off keystroke messages and sends WM_COMMAND/WM_SYSCOMMAND messages instead. That is, it turns keystrokes into accelerators. Notice that TranslateAccelerators and TranslateMDISysAccel send the accelerators messages, rather than simply changing the message in the MSG structure. The actual keystroke message GetMessage retrieves is never diapatched at all.

IsDialogMessage

is the dialog manager and pulls out keystrokes and treat them as dialog keys. It sends a WM_GETDLGCODE message to the control, that would have received the keystroke, which determines, wether the routine should interpret the key as a dialog keystroke or let it pass through to the control. It provides the Tab, arrow, mnemonics, return and escape keyboard interfaces for dialogs. Upon deciding that the keystroke message should be handled as a dialog key, it sends out the appropriate messages. 

The WM_GETDLGCODE message has normally no parameters. But if the lParam parameter is not NULL, lParam is pointer to the MSG struct for the keydown message, that causes the WM_GETDLGCODE message. The control can now respond to the keystrokes with individuell return values. 

A control specifies one of these flags returned from the WM_GETDLGCODE:

DLGC_DEFPUSHBUTTON	The dialog manager should handle a Return key by “pushing” this button
DLGC_UNDEFPUSHBUTTON	This button becomes a default button when it receives focus
DLGC_RADIOBUTTONS	This control sits in a mutually-exclusive set
DLGC_HASSETSEL	This edit-type control accepts EM_SETSEL messages, which is sent to select all of the text in the control.
DLGC_STATIC	If the user types the mnemonic( Alt + underlined letter ) for this control and this control does not have the style WS_TABSTOP( so doesn’t want focus), focus should go to the next control instead of this one.

The control also specifies as many of these flags as is appropriate

0	The dialog manager should handle all keystrokes it would like to: Alt + letter, Tab, Shift + Tab, and arrow keys.
DLGC_WANTTAB	This control has ist own handlers for Tab and Shift + Tab, so the dialog manager should pass these keystrokes on rather than using them to move focus to the next group
DLGC_WANTARROWS	This control has ist own handlers for arrow keys, so the dialog manager should pass these keystrokes on rather than using them to move focus to the next control in the group
DLGC_WANTCHARS	This control handles WM_CHAR messages
DLGC_WANTALLKEYS	This control would like all keystrokes rather than having the dialog manager handle any of them
DLGC_WANTMESSAGE	same as DLGC_WANTALLKEYS

TranslateMessage

It watches the keydown and keyup messages and posts a WM_CHAR message for each ASCII keydown message it sees. Then TranslateMessage turns keystroke messages into WM_SYSKEYDOWN, WM_SYSCHAR, and WM_SYSKEYUP messages for those that had the ALT key down at the time.

DispatchMessage

dispatches a message to a window procedure.If the message is a WM_TIMER message and the lParam parameter of the WM_TIMER message is not NULL, lParam points to a function that is called instead of the window procedure.

Notes

The Windows system does all of its work on the keydown events, Often you will get "stray" keyup events for keystrokes, that the system has already handled. For example, when the user tabs to a control, you will get the WM_KEYUP message for the TAB key.

UpdateWindow( P++: Update()) checks whether the specified window's paint flag is set, that is, it checks for invalid pixels, which can be thought of an indicator, that the window has a pending WM_PAINT message. If so, the routine delivers the WM_PAINT message to the window immediatly. UpdateWindow does not put a WM_PAINT message in the message queue; it actually delivers the message to the window's win proc right away.

By the time UpdateWindow returns, the window has repainted its client area.

The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message. Because the message queue isn’t used, the message cannot be handled by the dialog manager or translated to an accelerator or to WM_CHAR, or catched by any filter.

The PostMessage function places (posts) a message in the message queue associated with the thread that created the specified window and then returns without waiting for the thread to process the message. Messages in a message queue are retrieved by calls to the GetMessage or PeekMessage function.

With the introduction of Windows CE and the Internet Client SDK Microsoft changes the parameters of the WM_PAINT message:

hdc = (HDC) wParam; // the device context to draw in
 
Parameters
hdc 
Identifies the device context to draw in. If this parameter is NULL, use the default device context. This parameter is used by some common controls to enable drawing in a device context other than the default device context. Other windows can safely ignore this parameter. 

An application should return zero if it processes this message. 

Currently most of the common control support this feature. It gives the programmer the possibility, to draw a control flickerfree. He can catch the original message, create a memory DC, send WM_PAINT to the control with the memory DC, and copy the memory DC to the screen. For more information consult the documentation of the Microsoft Internet Client SDK.

If you don’t have the SDK, you can find it at:
http://www.microsoft.com/msdn/sdk/inetsdk/help/itt/CommCtls/CommCtls.htm
 
Summary of the WinSider column by Kim Crouse, published in Windows Tech Journal, December 1995
Additional informations by Herbert Menke