Week 5 Windows Messages Handling
Week 5 Windows Messages Handling
1
Windows Event and Messages
Hardware Event Send Message
Application 1
Window
App 2 Message
procedure
Queue
2
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) ;
}
• If the message field of the message retrieved from the message queue is
anything except WM_QUIT (which equals 0x0012), GetMessage returns a
nonzero value. 3
– A WM_QUIT message causes GetMessage to return 0.
The GetMessage Procedure
• 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 pointer to a MSG structure
named msg.
• The second, third, and fourth arguments 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 msg structure are:
4
The msg and pt Sturcture
MSG structure
Contains message information from a thread's message queue.
Syntax
typedef struct tagMSG {
HWND hwnd; A handle to the window whose window procedure receives the
message. This member is NULL when the message is a thread
message.
UINT message; The message identifier. Applications can only use the low
word; the high word is reserved by the system.
WPARAM wParam; Additional information about the message. The exact
meaning depends on the value of the message member.
LPARAM lParam; Additional information about the message. The exact
meaning depends on the value of the message member.
DWORD time; The time at which the message was posted.
POINT pt; The cursor position, in screen coordinates, when the message was
posted.
} MSG, *PMSG, *LPMSG;
5
The pt Sturcture
POINT structure
The POINT structure defines the x- and y- coordinates of a point.
Syntax
typedef struct tagPOINT {
LONG x;
LONG y;
} POINT, *PPOINT;
Members
x
The x-coordinate of the point.
y
The y-coordinate of the point.
6
Inside the Message Loop
• The statement:
TranslateMessage (&msg) ;
• passes the msg structure back to Windows for some keyboard translation.
(discussed this more in Chapter 6.)
• The statement
DispatchMessage (&msg) ;
• again passes the msg structure back to Windows.
– Windows then sends the message to the appropriate window procedure for
processing
– In this case the window procedure is WndProc as initialised in the registered
Windows Class structure variable .
– After WndProc processes the message, it returns control 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.
7
The Window Procedure
• WndProc procedure determines what the window displays in its client area and how
the window responds to user input.
• A window procedure is always defined like this:
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
– The four parameters to the window procedure are identical to and is a copy of from the first
four fields of the MSG structure.
– The first parameter is hwnd, the handle to the window receiving the message which is the
same handle returned from the CreateWindow function.
• For a program which creates only one window, this is the only window handle the program knows
about.
• If a program creates multiple windows based on the same window class (and hence the same window
procedure), hwnd identifies the particular window receiving the message.
– The second parameter is the same as the message field in the MSG structure.
• It's a number that identifies the message.
– The last two parameters are 32-bit message parameters that provide more information about
the message.
• What these parameters contain is specific to each type of message.
• Sometimes a message parameter is two 16-bit values stuck together, and sometimes a message
parameter is a pointer to a text string or to a data structure.
• Programs generally don't call window procedures directly.
– The window procedure is almost always called from Windows itself.
8
– A program can indirectly call its own window procedure by calling a function named
Processing the Messages (1)
• Every message that a window procedure receives is identified by
a number, which is the message parameter to the window
procedure.
– The identifiers beginning with the prefix WM ("window message") for
each type of message.
• Generally, Windows programmers use a switch and case
construction to determine what message the window procedure
is receiving and how to process it accordingly.
• When a window procedure processes a message, it should
return 0 from the window procedure.
• All messages that a window procedure chooses not to process
must be passed to a Windows function named DefWindowProc.
• The value returned from DefWindowProc must be returned from
the window procedure.
9
Processing the Messages (2)
• In HELLOWIN, WndProc chooses to process only three messages:
WM_CREATE, WM_PAINT, and WM_DESTROY.
• The window procedure is structured like this:
switch (message) //This is from the 2nd parameter from WndProc() input.
{
case WM_CREATE :
[process WM_CREATE message]
return 0 ;
case WM_PAINT :
[process WM_PAINT message]
return 0 ;
case WM_DESTROY :
[process WM_DESTROY message]
return 0 ; }
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
• DefWindowProc process of all other messages that is not processed
switch and case structure to avoid abnormal behaviour in the program,
such as being able to terminate the program, will not work. 10
Processing the Messages(3)
• Messages are defined in MSDN’s
About Messages and Message Queues.
• In this three sample message, the are no usable data in the
WPARAM and LPARAM (3rd and 4th) parameters of the WndProc()
input. So the are not processed.
• Other message may have usable data in the parameter for
example the WM_SIZE message is sent to a window after its size
has changed.
In the lParam parameter:
– The low-order word of lParam specifies the new width of the client
area.
– The high-order word of lParam specifies the new height of the client
area.
11
WM_CREATE Message
• The very first message that a window procedure receives is WM_CREATE
which is sent to the message queue when HELLOWIN calls CreateWindow.
• one-time window initialization during WM_CREATE processing.
• HELLOWIN is written to process WM_CREATE playing a waveform sound
file named HELLOWIN.WAV.
– It does this using the simple PlaySound function
– The PlaySound function plays a sound specified by the given file name, resource,
or system event. (A system event may be associated with a sound in the registry
or in the WIN.INI file.)
– To compile a program which uses PlaySound you must insert the following
statement after the # include declaration to tell the linker to include "winmm.lib“
when linking the program.
#pragma comment(lib,"winmm.lib")
– Read reference on PlaySound here
12
The WM_PAINT Message
• The second message that WndProc processes
• 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."
• 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.
• Because wndclass structure registered in HELLOWIN's window was
set to the flags CS_HREDRAW and CS_VREDRAW,
– when you resize,
– move windows around the screen,
– the client area becomes invalid and WM_PAINT message will be sent to
the message queue.
• WM_PAINT message is also sent when RedrawWindow function or
InvalidateRect function is called which is not used in HELLOWIN
program 13
Processing WM_PAINT
• WM_PAINT processing almost always begins with a call to BeginPaint()
during which:
– Windows erases the background of the client area if it hasn't been erased
already.
– erases the background using the brush specified in the hbrBackground field of
the registered WNDCLASS structure of the window.
– The BeginPaint call validates the entire client area and returns a "handle to a
device context" which is hdc in HELLOWIN program.
– A device context refers to a physical output device (such as a video display) and
its device driver.
• You need the device context handle to display text and graphics in the
client area of a window.
• and ends with a call to EndPaint:
– EndPaint releases the device context handle so that it is no longer valid.
• BeginPaint() – EndPaint() is a GDI structure which must be abided when
processing the WM_PAINT message.
• Within the GDI structure you then can use GDI functions to draw GDI
objects on the application widow. 14
The Real Repainting Job In HELLOWIN
• After WndProc calls BeginPaint,
– it calls
GetClientRect (hwnd, &rect)
to get the properties of the client rectangle of window identified by hwnd.
– the properties will be stored in variable rect of the structure type RECT.
– This structure has four LONG fields named left, top, right, and bottom.
• WndProc doesn't do anything with this RECT structure except pass a
pointer to it as the fourth argument to DrawText:
DrawText (hdc, TEXT ("Hello, Windows !"), -1, &rect, DT_SINGLELINE |
DT_CENTER | DT_VCENTER) ;
– DrawText, as the name implies, draws text.
• Because this function draws something, the first argument is a handle to the
device context returned from BeginPaint.
• The second argument is the text to draw,
• and the third argument is set to -1 to indicate that the text string is terminated
with a zero character.
– The last argument to DrawText is a series of bit flags defined in WINUSER.H.
which causes the string "Hello, Windows!" to be displayed centered in the 15
client area.
Debugging Exercise (1)
• Click here and write the program named “Programming Exercise for Week
5 Visual Studio.
• Built and RUN and try to get a good understanding how Window messages
works by observing the flow of the program as displayed by the
MessageBox Dialog.
• Then by using debugging technique, set breakpoints at all “case”
statements on every “if (DisplayMessageBox)” statement in the program.
• RUN the program and when the first MessageBox opens, select “No” so
that DisplayMessageBox will not be set TRUE
• Continue RUNning the program and when it breaks at breakpoint the
Watch 1 window will open.
– If it does not, select from Debug|Windows menu (available only when
in Debug mode).
• Set Watch on variable msg, message, wParam and lParam. Do you
know why should you do this?
Posted to the window with the keyboard focus when a nonsystem key is
pressed. A nonsystem key is a key that is pressed when the ALT key is not
pressed.
Parameters
wParam The virtual-key code of the nonsystem key. See Virtual-Key Codes.
19
WM_KEYDOWN message (1)
lParam The repeat count, scan code, extended-key flag, context code,
previous key-state flag, and transition-state flag, as shown following.
Bits Meaning
The repeat count for the current message. The value is the number of times the
keystroke is autorepeated as a result of the user holding down the key. If the
0-15
keystroke is held long enough, multiple messages are sent. However, the repeat
count is not cumulative.
16-23 The scan code. The value depends on the OEM.
Indicates whether the key is an extended key, such as the right-hand ALT and
24 CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if
it is an extended key; otherwise, it is 0.
25-28 Reserved; do not use.
29 The context code. The value is always 0 for a WM_KEYDOWN message.
The previous key state. The value is 1 if the key is down before the message is
30
sent, or it is zero if the key is up.
31 The transition state. The value is always 0 for a WM_KEYDOWN message.
20
WM_MOUSEWHEEL message (1)
Sent to the focus window when the mouse wheel is rotated. The
DefWindowProc function propagates the message to the window's parent.
There should be no internal forwarding of the message, since
DefWindowProc propagates it up the parent chain until it finds a window
that processes it.
Parameters
wParam The high-order word indicates the distance the wheel is rotated,
expressed in multiples or divisions of WHEEL_DELTA, which is 120. A
positive value indicates that the wheel was rotated forward, away
from the user; a negative value indicates that the wheel was rotated
backward, toward the user.
The low-order word indicates whether various virtual keys are down. This
parameter can be one or more of the following values.
21
WM_MOUSEWHEEL message (2)
22
WM_RBUTTONDOWN message(1)
Posted when the user presses the right mouse button while the cursor is in
the client area of a window.
If the mouse is not captured, the message is posted to the window beneath
the cursor. Otherwise, the message is posted to the window that has
captured the mouse.
Parameters
wParam
Indicates whether various virtual keys are down. This parameter can be
one or more of the following values.
23
WM_RBUTTONDOWN message (2)
Value Meaning Value Meaning
MK_CONTROL MK_SHIFT The SHIFT key is
The CTRL key is down.
0x0008 0x0004 down.
MK_LBUTTON The left mouse MK_XBUTTON1 The first X button is
0x0001 button is down. 0x0020 down.
MK_MBUTTON The middle mouse MK_XBUTTON2 The second X
0x0010 button is down. 0x0040 button is down.
MK_RBUTTON The right mouse
0x0002 button is down.
lParam
The low-order word specifies the x-coordinate of the cursor. The
coordinate is relative to the upper-left corner of the client area.
The high-order word specifies the y-coordinate of the cursor. The
coordinate is relative to the upper-left corner of the client area.
24
WM_SIZE message
Sent to a window after its size has changed.
A window receives this message through its WindowProc function.
Value Meaning Value Meaning
Message is sent to all pop-up
SIZE_MAXHIDE SIZE_MINIMIZED The window has been
windows when some other
4 1 minimized.
window is maximized.
lParam
The low-order word of lParam specifies the new width of the client area.
The high-order word of lParam specifies the new height of the client 25
area.
Summary: About Messages
• Windows-based applications are event-driven. They do not make explicit function
calls (such as C run-time library calls) to obtain input. Instead, they wait for the
system to pass input to them.
• There two types of messages:
• System-Defined Messages
• This are messages defined and recognized by windows. Some we have
used in the exercise we have just done. The are may more as shown in
MSDN System-Defined Messages.
• The system reserves message-identifier values in the range 0x0000
through 0x03FF (the value of WM_USER – 1) .
• Application-Defined Messages
• An application can create messages to be used by its own windows or to
communicate with windows in other processes. If an application creates
its own messages, the window procedure that receives them must
interpret the messages and provide appropriate processing.
• Application-Defined Message-identifier values are used in the range
0x0400 (the value of WM_USER) through 0x7FFF are available for
message identifiers for private window classes.
• Only application is marked version 4.0 can use message-identifier values
in the range 0x8000 (WM_APP) through 0xBFFF for private messages. 26