|
|
|
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.
IntroductionA 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 MessageThis 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 MessageThis 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 MessageThe 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 MessageFinally, 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 in print or online must be granted by the author in writing.
|
|
|
|
|
|
|
|