WM_CREATE
WndProc receives this message while Windows is processing the CreateWindow function in WinMain. That is, when calling CreateWindow,
Windows does what it has to do and, in the process, Windows calls WndProc with the first argument set to the window handle and the second
argument set to WM_CREATE (the value 1). WndProc processes the WM_CREATE message and returns controls back to Windows. Windows can then
return to an application from the CreateWindow call to continue further progress in WinMain.
Often a window procedure performs one-time window initialization during WM_CREATE processing.
WM_PAINT
This message is extremely important in Windows programming. It informs a program when part or all of the window's client area is "invalid"
and must be "updated," which means that it must be redrawn or "painted." When the window is first created, the entire client area is invalid
because the program has not yet drawn anything on the window. The first WM_PAINT message (which normally occurs when the program calls UpdateWindow
in WinMain) directs the window procedure to draw something on the client area.
If a window procedure does not process WM_PAINT messages (which is very rare), they must be passed on to DefWindowProc. DefWindowProc simply
calls BeginPaint and EndPaint in succession so that the client area is validated.
PostQuitMessage (0) ;
This function inserts a WM_QUIT message in the program's message queue. I mentioned earlier that GetMessage returns nonzero for any message other
than WM_QUIT that it retrieves from the message queue. When GetMessage retrieves a WM_QUIT message, GetMessage returns 0. This causes WinMain to drop
out of the message loop. The program then executes the following statement:
return msg.wParam ;
The wParam field of the structure is the value passed to the PostQuitMessage function (generally 0). The return statement exits from WinMain and
terminates the program.
DefWindowProc processes this keyboard or mouse input. When it detects that you have selected the Close option, it sends a WM_SYSCOMMAND message to
the window procedure. WndProc passes this message to DefWindowProc. DefWindowProc responds by sending a WM_CLOSE message to the window procedure. WndProc
again passes this message to DefWindowProc. DefWindowProc responds to the WM_CLOSE message by calling DestroyWindow. DestroyWindow causes Windows to send
a WM_DESTROY message to the window procedure. WndProc finally responds to this message by calling PostQuitMessage to put a WM_QUIT message in the message
queue. This message causes the message loop in WinMain to terminate and the program to end.
Messages can be either "queued" or "nonqueued." The queued messages are those that are placed in a program's message queue by Windows. In the program's
message loop, the messages are retrieved and dispatched to the window procedure. The nonqueued messages are the results of calls by Windows directly to the
window procedure. It is said that queued messages are "posted" to a message queue and that nonqueued messages are "sent" to the window procedure. In any case,
the window procedure gets all the messages-both queued and nonqueued-for the window. The window procedure is "message central" for the window.
The queued messages are primarily those that result from user input in the form of keystrokes (such as the WM_KEYDOWN and WM_KEYUP messages), characters
that result from keystrokes (WM_CHAR), mouse movement (WM_MOUSEMOVE), and mouse-button clicks (WM_LBUTTONDOWN). Queued messages also include the timer message
(WM_TIMER), the repaint message (WM_PAINT), and the quit message (WM_QUIT).
The nonqueued messages are everything else. Nonqueued messages often result from calling certain Windows functions. For example, when WinMain calls CreateWindow,
Windows creates the window and in the process sends the window procedure a WM_CREATE message. When WinMain calls ShowWindow, Windows sends the window procedure
WM_SIZE and WM_SHOWWINDOW messages. When WinMain calls UpdateWindow, Windows sends the window procedure a WM_PAINT message. Queued messages signaling keyboard
or mouse input can also result in nonqueued messages. For example, when you select a menu item with the keyboard or mouse, the keyboard or mouse message is queued
but the eventual WM_COMMAND message indicating that a menu item has been selected is nonqueued.
When I say that messages come through in an orderly and synchronized manner, I mean first that messages are not like hardware interrupts. While processing one
message in a window procedure, the program will not be suddenly interrupted by another message.
Although Windows programs can have multiple threads of execution, each thread's message queue handles messages for only the windows whose window procedures are
executed in that thread. In other words, the message loop and the window procedure do not run concurrently. When a message loop retrieves a message from its message
queue and calls DispatchMessage to send the message off to the window procedure, DispatchMessage does not return until the window procedure has returned control back
to Windows.
However, the window procedure could call a function that sends the window procedure another message, in which case the window procedure must finish processing the
second message before the function call returns, at which time the window procedure proceeds with the original message. For example, when a window procedure calls
UpdateWindow, Windows calls the window procedure with a WM_PAINT message. When the window procedure finishes processing the WM_PAINT message, the UpdateWindow call
will return controls back to the window procedure. This means that window procedures must be reentrant.
In many Windows programs, a WM_SIZE message will eventually be followed by a WM_PAINT message. How do we know this? Because when we define the window class we
specify the class style as
CS_HREDRAW | CS_VREDRAW
Scroll Bar Messages
This class style tells Windows to force a repaint if either the horizontal or vertical size changes.
If you hold down the mouse button on the various parts of the scroll bar, your program can receive multiple scroll bar messages. When the mouse button is released,
you'll get a message with a notification code of SB_ENDSCROLL. You can generally ignore messages with the SB_ENDSCROLL notification code. Windows will not change the
position of the scroll bar thumb. Your application does that by calling SetScrollPos.
When you position the mouse cursor over the scroll bar thumb and press the mouse button, you can move the thumb. This generates scroll bar messages with notification
codes of SB_THUMBTRACK and SB_THUMBPOSITION. When the low word of wParam is SB_THUMBTRACK, the high word of wParam is the current position of the scroll bar thumb as
the user is dragging it. This position is within the minimum and maximum values of the scroll bar range. When the low word of wParam is SB_THUMBPOSITION, the high word
of wParam is the final position of the scroll bar thumb when the user released the mouse button. For other scroll bar actions, the high word of wParam should be ignored.
To provide feedback to the user, Windows will move the scroll bar thumb when you drag it with the mouse as your program is receiving SB_THUMBTRACK messages. However,
unless you process SB_THUMBTRACK or SB_THUMBPOSITION messages by calling SetScrollPos, the thumb will snap back to its original position when the user releases the mouse
button.
A program can process either the SB_THUMBTRACK or SB_THUMBPOSITION messages, but doesn't usually process both. If you process SB_THUMBTRACK messages, you'll move the
contents of your client area as the user is dragging the thumb. If instead you process SB_THUMBPOSITION messages, you'll move the contents of the client area only when
the user stops dragging the thumb. It's preferable (but more difficult) to process SB_THUMBTRACK messages; for some types of data your program may have a hard time keeping
up with the messages.
WndProc receives this message while Windows is processing the CreateWindow function in WinMain. That is, when calling CreateWindow,
Windows does what it has to do and, in the process, Windows calls WndProc with the first argument set to the window handle and the second
argument set to WM_CREATE (the value 1). WndProc processes the WM_CREATE message and returns controls back to Windows. Windows can then
return to an application from the CreateWindow call to continue further progress in WinMain.
Often a window procedure performs one-time window initialization during WM_CREATE processing.
WM_PAINT
This message is extremely important in Windows programming. It informs a program when part or all of the window's client area is "invalid"
and must be "updated," which means that it must be redrawn or "painted." When the window is first created, the entire client area is invalid
because the program has not yet drawn anything on the window. The first WM_PAINT message (which normally occurs when the program calls UpdateWindow
in WinMain) directs the window procedure to draw something on the client area.
If a window procedure does not process WM_PAINT messages (which is very rare), they must be passed on to DefWindowProc. DefWindowProc simply
calls BeginPaint and EndPaint in succession so that the client area is validated.
PostQuitMessage (0) ;
This function inserts a WM_QUIT message in the program's message queue. I mentioned earlier that GetMessage returns nonzero for any message other
than WM_QUIT that it retrieves from the message queue. When GetMessage retrieves a WM_QUIT message, GetMessage returns 0. This causes WinMain to drop
out of the message loop. The program then executes the following statement:
return msg.wParam ;
The wParam field of the structure is the value passed to the PostQuitMessage function (generally 0). The return statement exits from WinMain and
terminates the program.
DefWindowProc processes this keyboard or mouse input. When it detects that you have selected the Close option, it sends a WM_SYSCOMMAND message to
the window procedure. WndProc passes this message to DefWindowProc. DefWindowProc responds by sending a WM_CLOSE message to the window procedure. WndProc
again passes this message to DefWindowProc. DefWindowProc responds to the WM_CLOSE message by calling DestroyWindow. DestroyWindow causes Windows to send
a WM_DESTROY message to the window procedure. WndProc finally responds to this message by calling PostQuitMessage to put a WM_QUIT message in the message
queue. This message causes the message loop in WinMain to terminate and the program to end.
Messages can be either "queued" or "nonqueued." The queued messages are those that are placed in a program's message queue by Windows. In the program's
message loop, the messages are retrieved and dispatched to the window procedure. The nonqueued messages are the results of calls by Windows directly to the
window procedure. It is said that queued messages are "posted" to a message queue and that nonqueued messages are "sent" to the window procedure. In any case,
the window procedure gets all the messages-both queued and nonqueued-for the window. The window procedure is "message central" for the window.
The queued messages are primarily those that result from user input in the form of keystrokes (such as the WM_KEYDOWN and WM_KEYUP messages), characters
that result from keystrokes (WM_CHAR), mouse movement (WM_MOUSEMOVE), and mouse-button clicks (WM_LBUTTONDOWN). Queued messages also include the timer message
(WM_TIMER), the repaint message (WM_PAINT), and the quit message (WM_QUIT).
The nonqueued messages are everything else. Nonqueued messages often result from calling certain Windows functions. For example, when WinMain calls CreateWindow,
Windows creates the window and in the process sends the window procedure a WM_CREATE message. When WinMain calls ShowWindow, Windows sends the window procedure
WM_SIZE and WM_SHOWWINDOW messages. When WinMain calls UpdateWindow, Windows sends the window procedure a WM_PAINT message. Queued messages signaling keyboard
or mouse input can also result in nonqueued messages. For example, when you select a menu item with the keyboard or mouse, the keyboard or mouse message is queued
but the eventual WM_COMMAND message indicating that a menu item has been selected is nonqueued.
When I say that messages come through in an orderly and synchronized manner, I mean first that messages are not like hardware interrupts. While processing one
message in a window procedure, the program will not be suddenly interrupted by another message.
Although Windows programs can have multiple threads of execution, each thread's message queue handles messages for only the windows whose window procedures are
executed in that thread. In other words, the message loop and the window procedure do not run concurrently. When a message loop retrieves a message from its message
queue and calls DispatchMessage to send the message off to the window procedure, DispatchMessage does not return until the window procedure has returned control back
to Windows.
However, the window procedure could call a function that sends the window procedure another message, in which case the window procedure must finish processing the
second message before the function call returns, at which time the window procedure proceeds with the original message. For example, when a window procedure calls
UpdateWindow, Windows calls the window procedure with a WM_PAINT message. When the window procedure finishes processing the WM_PAINT message, the UpdateWindow call
will return controls back to the window procedure. This means that window procedures must be reentrant.
In many Windows programs, a WM_SIZE message will eventually be followed by a WM_PAINT message. How do we know this? Because when we define the window class we
specify the class style as
CS_HREDRAW | CS_VREDRAW
Scroll Bar Messages
This class style tells Windows to force a repaint if either the horizontal or vertical size changes.
If you hold down the mouse button on the various parts of the scroll bar, your program can receive multiple scroll bar messages. When the mouse button is released,
you'll get a message with a notification code of SB_ENDSCROLL. You can generally ignore messages with the SB_ENDSCROLL notification code. Windows will not change the
position of the scroll bar thumb. Your application does that by calling SetScrollPos.
When you position the mouse cursor over the scroll bar thumb and press the mouse button, you can move the thumb. This generates scroll bar messages with notification
codes of SB_THUMBTRACK and SB_THUMBPOSITION. When the low word of wParam is SB_THUMBTRACK, the high word of wParam is the current position of the scroll bar thumb as
the user is dragging it. This position is within the minimum and maximum values of the scroll bar range. When the low word of wParam is SB_THUMBPOSITION, the high word
of wParam is the final position of the scroll bar thumb when the user released the mouse button. For other scroll bar actions, the high word of wParam should be ignored.
To provide feedback to the user, Windows will move the scroll bar thumb when you drag it with the mouse as your program is receiving SB_THUMBTRACK messages. However,
unless you process SB_THUMBTRACK or SB_THUMBPOSITION messages by calling SetScrollPos, the thumb will snap back to its original position when the user releases the mouse
button.
A program can process either the SB_THUMBTRACK or SB_THUMBPOSITION messages, but doesn't usually process both. If you process SB_THUMBTRACK messages, you'll move the
contents of your client area as the user is dragging the thumb. If instead you process SB_THUMBPOSITION messages, you'll move the contents of the client area only when
the user stops dragging the thumb. It's preferable (but more difficult) to process SB_THUMBTRACK messages; for some types of data your program may have a hard time keeping
up with the messages.