Processing Win32 WM_ Messages

Some Common Windows Messages and How to Process Them

© Guy Lecky-Thompson

An introduction to processing WM_ messages sent to a Windows Procedure, and how they should be handled when the application processes them on behalf of Windows.

Introduction

A Windows application does nothing except process messages from the operating system, except in very rare cases where an application must process continually. These applications include some screensavers, programs that draw forever, virus monitoring software, and so on.

Exactly how the messages are received and dispatched to the Windows application lies out of the scope of this article. However, a detailed examination of how these mechanisms work can be found in the Win32 Message Processing Primer. For those readers having never programmed Windows before, that article, plus the The Win32 WinMain Function tutorial would be good additional reading to have under their belt.

This article covers the 4 basic messages that an application must be able to process:

It is rare that an application does not need to do some processing on start up and shut down, or process any child controls or menu commands, but they might not draw directly onto their window area, and the WM_PAINT message could be ignored in those cases. Otherwise, an understanding of these messages is fairly vital.

We shall look at the 3 principle message components defined in the MSG structure:

There are other members of the MSG structure, but we shall ignore them for now. It is assumed that the reader understands the use of the WndProc windows procedure, passed as a member of the window class creation variable, during the CreateWindow call. It is usually prototyped as:

long FAR PASCAL _export WndProc (HWND, UINT, WPARAM, LPARAM)

The message comes in the second parameter, with the wParam and lParam members of the MSG structure in the third and fourth. The message value is usually used as a condition in a switch statement, with WM_ processing done on each case label.

The WM_CREATE Message

This is the first message that an application will receive. In the lParam, the CREATESTRUCT data is passed, which is identical to the data used in the call to CreateWindow. This means that we can retrieve the application instance (for example) during the creation process:

case WM_CREATE:
hInst = (HINSTANCE) ((LPCREATESTRUCT)lParam)->hInstance;
return 0;

If -1 is returned from processing the WM_CREATE message, then the creation is halted and the application is not initialized.

The WM_DESTROY Message

This is the last message that the application is likely to receive, and is sent to inform the application that Windows has received an instruction to quit the application. Usually, a well-behaved application will call the PostQuitMessage to inform Windows that the message processing should be halted and the application can be shut down:

case WM_DESTROY:
PostQuitMessage(0);
return 0;

The PostQuitMessage parameter is the exit code, passed through the WPARAM parameter of the resulting WM_QUIT message. Processing the WM_DESTORY message is also the appropriate time to do any application shutdown tasks, such as asking for a file to be saved.

The WM_PAINT Message

The WM_PAINT message is sent whenever the application area needs to be updated. It can also be triggered by calling the InvalidateRect function with the window handle, and a NULL rectangle. It is usual for the application to call the BeginPaint and EndPaint functions to inform Windows that the region to be updated is now valid again:

case WM_PAINT:
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd,&ps);
// Do client area painting here
EndPaint (hwnd, &ps) ;
return 0;

If this message is processed, the application should return 0.

The WM_COMMAND Message

Finally, whenever a child control needs to inform the parent that an operation has been performed (such as a button being clicked), or a menu item has been selected, it is done through the WM_COMMAND message. The application will receive the identifier of the menu item or control in the WPARAM, and some additional information (depending on the control) in the LPARAM parameter.

It is usual to construct a switch statement inside the case used to process the WM_COMMAND message to test various values of the WPARAM in order to determine the child control or menu item that has been clicked:

case WM_COMMAND:
switch (wParam)
{
case IDM_EXIT:
// The user clicked exit
SendMessage(hwnd, WM_DESTROY, 0, 0L);
break;
}
return 0;

If the application processes the WM_COMMAND message, then it should return zero.


The copyright of the article Processing Win32 WM_ Messages in Windows Programming is owned by Guy Lecky-Thompson. Permission to republish Processing Win32 WM_ Messages must be granted by the author in writing.




Post this Article to facebook Add this Article to del.icio.us! Digg this Article furl this Article Add this Article to Reddit Add this Article to Technorati Add this Article to Newsvine Add this Article to Windows Live Add this Article to Yahoo Add this Article to StumbleUpon Add this Article to BlinkLists Add this Article to Spurl Add this Article to Google Add this Article to Ask Add this Article to Squidoo