A window procedure processes all messages sent to all windows in a given class. Windows sends messages to a window procedure when it receives input from the user that is intended for the given window, or when it needs the procedure to carry out some action on its window, such as painting inside the client area.
A window procedure receives the following types of messages:
Input messages from the keyboard, mouse or other pointing device, and timer
Requests for information, such as a request for the window title
Reports of changes made to the system by other windows, such as a change to the WIN.INI file
Messages that give the window procedure an opportunity to modify the standard system response to certain actions, such as an opportunity to adjust a menu before it is displayed
Requests to carry out some action on its window or client area, such as a request to update the client area
Information about its status in relation to other windows, such as its losing access to the keyboard or becoming the active window
Most of the messages a window procedure receives are from Windows, but it can also receive messages from other windows, including windows it owns. These messages can be requests for information or notification that a given event has occurred within another window.
A window procedure continues to receive messages from the system and possibly other windows in the system until the window procedure, the window procedure of a parent window, or the system destroys the window. Even while the window is in the process of being destroyed, the window procedure receives additional messages that give it the opportunity to carry out any cleanup tasks before terminating. These messages include WM_CLOSE, WM_DESTROY, WM_QUERYENDSESSION, and WM_ENDSESSION. But once the window is destroyed, no more messages are passed to the procedure for that particular window. If there is more than one window of the class, however, the window procedure continues to receive messages for the other windows until they, too, are destroyed.
A window procedure defines how all windows of a given window actually behave; that is, it defines what response the windows make to commands from the user or system. The window procedure must examine messages it receives from the system and determine what action, if any, to take. For example, if the user clicks the scroll bar, the window procedure may scroll the contents of the client area. Windows passes information that affects a window and provides some tools to carry out tasks, such as drawing and scrolling, but the window procedure must carry out each actual task.
A window procedure can also choose not to respond to a given message. If it does not respond, the procedure must pass the message to the DefWindowProc function to give the system the opportunity to respond. This function carries out default actions based on the given message and its parameters. Many messages, especially nonclient-area messages, must be processed, so the DefWindowProc function is required in all window procedures.
A window procedure also receives messages that are really intended to be processed by the system. These messages, called nonclient-area messages, inform the procedure either that the user has carried out some action in a nonclient area of the window, such as clicking the title bar, or that some information about the window is required by the system to carry out an action, such as to move or adjust the size of the window. Although Windows passes these messages to the window procedure, the procedure should pass them to the DefWindowProc function and not attempt to process them. In any case, the window procedure must not ignore the message or return without passing it to DefWindowProc.
A window message is a set of values that Windows sends to a window procedure to provide input to the window or request the window to carry out some action. Windows includes a wide variety of messages that it or applications can send to a window procedure. Most messages are sent to a window as a result of a given function being executed or as a result of input from the user.
Every message consists of four values: a handle that identifies the window, a message identifier, a 16-bit message-specific value, and a 32-bit message-specific value. These values are passed as individual parameters to the window procedure. The window procedure then examines the message identifier to determine what response to make and how to interpret the 16- and 32-bit values.
A window procedure must use the Pascal calling convention. The following illustrates the window procedure syntax:
LONG FAR PASCAL WndProc(hwnd, msg, wParam, lParam)
HWND hwnd;
UINT msg;
WPARAM wParam;
LPARAM lParam;
The hwnd parameter identifies the window receiving the message; the msg
parameter is the message identifier; the wParam parameter is 16 bits of addi-tional message-specific information; and lParam is 32 bits of additional message-specific information. The window procedure must return a 32-bit value that indicates the result of message processing. The possible return values depend on the actual message sent.
Windows expects to make an intersegment call to the window procedure, so the procedure must be declared with the FAR attribute. The window-procedure name must be exported by including it in an EXPORTS statement in the application's module-definition file.
The DefWindowProc function is the default message processor for window procedures that do not or cannot process some of the messages sent to them. For most window procedures, the DefWindowProc function carries out most, if not all, processing of nonclient-area messages. These are the messages that signify actions to be carried out on parts of the window other than the client area. The messages that DefWindowProc processes and the default actions for each are as follows:
Message | Default action |
WM_ACTIVATE | Activates or deactivates a window. |
WM_CANCELMODE | Cancels internal processing of standard scroll bar input, cancels internal menu processing, and releases mouse capture. |
WM_CHARTOITEM | Returns –1. |
WM_CLOSE | Calls the DestroyWindow function. |
WM_CTLCOLOR | Sets the background and text color and returns a handle of the brush used to fill the control background. |
WM_DRAWITEM | Draws the focus rectangle for an owner-drawn list box item. |
WM_ERASEBKGND | Fills the client area with the color and pattern specified by the class brush, if any. |
WM_GETTEXT | Copies the window title into a specified buffer. |
WM_GETTEXTLENGTH | Returns the length, in bytes, of the window title. |
WM_ICONERASEBKGND | Fills the icon's client area with the window's background brush. |
WM_KEYUP | Sends a WM_SYSCOMMAND message to the top-level window if the F10 key or the ALT key was released. The wParam parameter of the message is set to SC_KEYMENU. |
WM_MOUSEACTIVATE | Sends the WM_MOUSEACTIVATE response to the parent window. The parent determines whether to activate the child window. |
WM_NCACTIVATE | Activates or deactivates the window and draws the icon or title bar to show the new state. |
WM_NCCALCSIZE | Computes the size of the client area. |
WM_NCCREATE | Initializes standard scroll bars, if any, and sets the default title for the window. |
WM_NCDESTROY | Frees any space internally allocated for the window title. |
WM_NCHITTEST | Finds out what part of the window the mouse is in. |
WM_NCLBUTTONDBLCLK | Tests the given point to find out the location of the mouse and, if necessary, generates additional messages. |
WM_NCLBUTTONDOWN | Finds out whether the left mouse button was pressed while the mouse was in the nonclient area of a window. |
WM_NCLBUTTONUP | Tests the given point to find out the location of the mouse and, if necessary, generates additional messages. |
WM_NCMOUSEMOVE | Tests the given point to find out the location of the mouse and, if necessary, generates additional messages. |
WM_NCPAINT | Paints the nonclient areas of the window. |
WM_PAINT | Validates the current update region, but does not paint the region. |
WM_QUERYENDSESSION | Returns TRUE. |
WM_QUERYOPEN | Returns TRUE. |
WM_SETCURSOR | Displays the appropriate mouse cursor, based on the position of the cursor. |
WM_SETREDRAW | Forces an immediate update of information about the clipping region of the complete window. |
WM_SETTEXT | Sets and displays the window title. |
WM_SHOWWINDOW | Opens or closes a window. |
WM_SYSCHAR | Generates a WM_SYSCOMMAND message for menu input. |
WM_SYSCOMMAND | Carries out the requested system command. |
WM_SYSKEYDOWN | Examines the given key and generates a WM_SYSCOMMAND message if the key is either TAB or ENTER. |
WM_SYSKEYUP | Sends a WM_SYSCOMMAND message to the top-level window if the F10 key or the ALT key was released. The wParam parameter of the message is set to SC_KEYMENU. |
WM_VKEYTOITEM | Returns –1. |
WM_WINDOWPOSCHANGED | Sends the WM_SIZE and WM_MOVE messages to the window. |
WM_WINDOWPOSCHANGING | Sends the WM_GETMINMAXINFO mes-sage to the window if the window has the WS_OVERLAPPED or WS_THICKFRAME style. |
For detailed information on each Windows message, see the Microsoft Windows Programmer's Reference, Volume 3.