The Message Loop

After the UpdateWindow call, the window is fully visible on the video display. The program must now make itself ready to read keyboard and mouse input from the user. Windows maintains a ”message queue“ for each Windows program currently running under Windows. When an input event occurs, Windows translates the event into a ”message“ that it places in the program's message queue.

A program retrieves these messages from the message queue by executing a block of code known as the ”message loop“:

while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

The msg variable is a structure of type MSG, which is defined in WINDOWS.H as follows:

typedef struct tagMSG

{

HWND hwnd ;

WORD message ;

WORD wParam ;

LONG lParam ;

DWORD time ;

POINT pt ;

}

MSG ;

The POINT data type is yet another structure, defined like this:

typedef struct tagPOINT

{

int x ;

int y ;

}

POINT ;

The GetMessage call that begins the message loop retrieves a message from the message queue:

GetMessage (&msg, NULL, 0, 0) ;

This call passes to Windows a far pointer to the MSG structure called msg. The second, third, and fourth parameters are set to NULL or 0 to indicate that the program wants all messages for all windows created by the program. Windows fills in the fields of the message structure with the next message from the message queue. The fields of this structure are:

hwnd—the handle to the window to which the message is directed. In the HELLOWIN program, this is the same as the hwnd value returned from CreateWindow, because that's the only window this program has.

message—the message identifier. This is a number that identifies the message. For each message, there is a corresponding identifier defined in WINDOWS.H that begins with the prefix WM (”window message“). For example, if you position the mouse pointer over HELLOWIN's client area and press the left mouse button, Windows will put a message in the message queue with a message field equal to WM_LBUTTONDOWN, which is the value 0x0201.

wParam—a 16-bit ”message parameter,“ the meaning and value of which depend on the particular message.

lParam—a 32-bit message parameter dependent on the message.

time—the time the message was placed in the message queue.

pt—the mouse coordinates at the time the message was placed in the message queue.

If the message field of the message retrieved from the message queue is anything except WM_QUIT (which equals 0x0012), then GetMessage returns a nonzero value. A WM_QUIT message causes the program to fall out of the message loop. The program then terminates, returning the wParam member of the msg structure.

The statement:

TranslateMessage (&msg) ;

passes the MSG structure back to Windows for some keyboard translation. (I'll discuss this more in Chapter 3.) The statement:

DispatchMessage (&msg) ;

again passes the MSG structure back to Windows. Windows then sends the message to the appropriate window procedure for processing. That window procedure is the WndProc function in HELLOWIN. After WndProc processes the message, it then returns to Windows, which is still servicing the DispatchMessage call. When Windows returns to HELLOWIN following the DispatchMessage call, the message loop continues with the next GetMessage call.