<Previous Lesson

Visual Programming

Next Lesson>

Lesson#16

Input Devices

16.1 KEYBOARD 2
16.1.1 KEYBOARD INPUT MODEL 2
16.1.2 KEYBOARD FOCUS AND ACTIVATION 3
16.1.3 KEYSTROKE MESSAGES 3
16.1.3.1 SYSTEM AND NON SYSTEM KEYSTROKES 4
16.1.3.2 VIRTUAL KEY CODES DESCRIBED 4
16.1.3.3 KEYSTROKE MESSAGE FLAGS 5
Repeat Count 5
Scan Code 6
Extended-Key Flag 6
Context Code 6
Previous Key-State Flag 6
Transition-State Flag 6
16.1.4 CHARACTER MESSAGES 6
16.1.4.1 NON-SYSTEM CHARACTER MESSAGES 7
16.1.4.2 DEAD-CHARACTER MESSAGES 7
16.1.5 KEY STATUS 8
16.1.6 KEY STROKE AND CHARACTER TRANSLATIONS 8
16.1.7 HOT-KEY SUPPORT 8
16.1.8 LANGUAGES, LOCALS, AND KEYBOARD LAYOUTS 9
16.1.9 KEYBOARD MESSAGES (BRIEF) 10
16.1.10 KEY DOWN MESSAGE FORMAT 11
16.1.11 CHARACTER MESSAGE FORMAT 11
16.1.12 GETTING KEY STATE 12
16.1.13 CHARACTER MESSAGE PROCESSING 13
16.2 CARET 13
16.2.1 CARET VISIBILITY 14
16.2.2 CARET BLINK TIME 14
16.2.3 CARET POSITION 14
16.2.4 REMOVING A CARET 14
16.2.5 CARET FUNCTIONS 15
16.3 MOUSE 15
16.3.1 MOUSE CURSOR 15
16.3.2 MOUSE CAPTURE 15
16.3.3 MOUSE CONFIGURATION 16
16.3.4 MOUSE MESSAGES 16
16.3.4.1 CLIENT AREA MOUSE MESSAGES 17
MESSAGE PARAMETERS 17
DOUBLE CLICK MESSAGES 18
16.3.4.2 NON CLIENT AREA MOUSE MESSAGES 19
16.3.4.3 THE WM_NCHITTEST MESSAGE 19
16.3.5 SCREEN AND CLIENT AREA COORDINATES 21
SUMMARY 21
EXERCISES 22
Input Devices 2

16.1 Keyboard

Keyboard is an external device in computer. Keyboard is used to input data in computer
system. An application receives keyboard input in the form of messages posted to its
windows.

16.1.1 Keyboard Input Model

The system provides device-independent keyboard support for applications by installing a
keyboard device driver appropriate for the current keyboard. The system provides
language-independent keyboard support by using the language-specific keyboard layout
currently selected by the user or the application. The keyboard device driver receives
scan codes from the keyboard, which are sent to the keyboard layout where they are
translated into messages and posted to the appropriate windows in your application.
Assigned to each key on a keyboard is a unique value called a scan code; it is a devicedependent
identifier for the key on the keyboard. A keyboard generates two scan codes
when the user types a key—one when the user presses the key and another when the user
releases the key.
The keyboard device driver interprets a scan code and translates (maps) it to a virtual-key
code; virtual-key code
is a device-independent value defined by the system that identifies
the purpose of a key. After translating a scan code, the keyboard layout creates a message
that includes the scan code, the virtual-key code, and other information about the
keystroke, and then places the message in the system message queue. The system
removes the message from the system message queue and posts it to the message queue
of the appropriate thread. Eventually, the thread's message loop removes the message and
passes it to the appropriate window procedure for processing. The following figure
illustrates the keyboard input model.

Figure 1

Input Devices
3

16.1.2 Keyboard Focus and Activation

The system posts keyboard messages to the message queue of the foreground thread that
created the window with the keyboard focus. The keyboard focus is a temporary property
of a window. The system shares the keyboard with all windows on the display by shifting
the keyboard focus, at the user's direction, from one window to another. The window that
has the keyboard focus receives (from the message queue of the thread that created it) all
keyboard messages until the focus changes to a different window.
A thread can call the GetFocus function to determine which of its windows (if any)
currently has the keyboard focus. A thread can give the keyboard focus to one of its
windows by calling the SetFocus function. When the keyboard focus changes from one
window to another, the system sends a WM_KILLFOCUS message to the window that
has lost the focus, and then sends a WM_SETFOCUS message to the window that has
gained the focus.
The concept of keyboard focus is related to that of the active window. The active window
is the top-level window the user is currently working with. The window with the
keyboard focus is either the active window, or a child window of the active window. To
help the user identify the active window, the system places it at the top of the Z order and
highlights its title bar (if it has one) and border.
The user can activate a top-level window by clicking it, selecting it using the ALT+TAB
or ALT+ESC key combination, or selecting it from the Task List. A thread can activate a
top-level window by using the SetActiveWindow function. It can determine whether a
top-level window it created is active by using the GetActiveWindow function.
When one window is deactivated and another activated, the system sends the
WM_ACTIVATE message. The low-order word of the wParam parameter is zero if the
window is being deactivated and nonzero if it is being activated. When the default
window procedure receives the WM_ACTIVATE message, it sets the keyboard focus to
the active window.
To block keyboard and mouse input events from reaching applications, use BlockInput.
Note. the BlockInput function will not interfere with the asynchronous keyboard inputstate
table. This means that calling the SendInput function while input is blocked will
change the asynchronous keyboard input-state table.

16.1.3 Keystroke Messages

Pressing a key causes a WM_KEYDOWN or WM_SYSKEYDOWN message to be
placed in the thread message queue attached to the window that has the keyboard focus.
Releasing a key causes a WM_KEYUP or WM_SYSKEYUP message to be placed in the
queue.
Key-up and key-down messages typically occur in pairs, but if the user holds down a key
long enough to start the keyboard's automatic repeat feature, the system generates a
Input Devices 4
number of WM_KEYDOWN or WM_SYSKEYDOWN messages in a row. It then
generates a single WM_KEYUP or WM_SYSKEYUP message when the user releases
the key.

16.1.3.1 System and non system keystrokes

The system makes a distinction between system keystrokes and nonsystem keystrokes.
System keystrokes produce system keystroke messages, WM_SYSKEYDOWN and

WM_SYSKEYUP. Nonsystem keystrokes produce nonsystem keystroke messages,
WM_KEYDOWN
and WM_KEYUP.
If your window procedure must process a system keystroke message, make sure that after
processing the message, the procedure passes it to the DefWindowProc function.
Otherwise, all system operations involving the ALT key will be disabled whenever the
window has the keyboard focus, that is, the user won't be able to access the window's
menus or System menu, or use the ALT+ESC or ALT+TAB key combination to activate
a different window.
System keystroke messages are primarily used by the system rather than by an
application. The system uses them to provide its built-in keyboard interface to menus and
to allow the user to control which window is active. System keystroke messages are
generated when the user types a key in combination with the ALT key, or when the user
types and no window has the keyboard focus (for example, when the active application is
minimized). In this case, the messages are posted to the message queue attached to the
active window.
Nonsystem keystroke messages are used by application windows; the DefWindowProcfunction does nothing with them. A window procedure can discard any nonsystem
keystroke messages that it does not need.

16.1.3.2 Virtual key codes Described

The wParam parameter of a keystroke message contains the virtual-key code of the key
that was pressed or released. A window procedure processes or ignores a keystroke
message, depending on the value of the virtual-key code.
A typical window procedure processes only a small subset of the keystroke messages that
it receives and ignores the rest. For example, a window procedure might process only
WM_KEYDOWN keystroke messages, and only those that contain virtual-key codes for
the cursor movement keys, shift keys (also called control keys), and function keys. A
typical window procedure does not process keystroke messages from character keys.
Instead, it uses the TranslateMessage function to convert the message into character
messages.
Input Devices 5

16.1.3.3 Keystroke Message Flags

The lParam parameter of a keystroke message contains additional information about the
keystroke that generated the message. This information includes the repeat count, the
scan code, the extended-key flag, the context code, the previous key-state flag, and the
transition-state flag. The following illustration shows the locations of these flags and
values in the lParam parameter.

Figure 2

An application can use the following values to manipulate the keystroke flags.
KF_ALTDOWN Manipulates the ALT key flag, which indicated if the ALT key is
pressed.
KF_DLGMODE Manipulates the dialog mode flag, which indicates whether a dialog
box is active.
KF_EXTENDED Manipulates the extended key flag.
KF_MENUMODE Manipulates the menu mode flag, which indicates whether a menu is
active.
KF_REPEAT Manipulates the repeat count.
KF_UP Manipulates the transition state flag.

Repeat Count

You can check the repeat count to determine whether a keystroke message represents
more than one keystroke. The system increments the count when the keyboard generates
WM_KEYDOWN
or WM_SYSKEYDOWN messages faster than an application can
process them. This often occurs when the user holds down a key long enough to start the
keyboard's automatic repeat feature. Instead of filling the system message queue with the
resulting key-down messages, the system combines the messages into a single key down
message and increments the repeat count. Releasing a key cannot start the automatic
repeat feature, so the repeat count for WM_KEYUP and WM_SYSKEYUP messages is
always set to 1.
Input Devices 6

Scan Code

The scan code is the value that the keyboard hardware generates when the user presses a
key. It is a device-dependent value that identifies the key pressed, as opposed to the
character represented by the key. An application typically ignores scan codes. Instead, it
uses the device-independent virtual-key codes to interpret keystroke messages.

Extended-Key Flag

The extended-key flag indicates whether the keystroke message originated from one of
the additional keys on the enhanced keyboard. The extended keys consist of the ALT and
CTRL keys on the right-hand side of the keyboard; the INS, DEL, HOME, END, PAGE
UP, PAGE DOWN, and arrow keys in the clusters to the left of the numeric keypad; the
NUM LOCK key, the BREAK (CTRL+PAUSE) key, the PRINT SCRN key, and the
divide (/) and ENTER keys in the numeric keypad. The extended-key flag is set if the key
is an extended key.

Context Code

The context code indicates whether the ALT key was down when the keystroke message
was generated. The code is 1 if the ALT key was down and 0 if it was up.

Previous Key-State Flag

The previous key-state flag indicates whether the key that generated the keystroke
message was previously up or down. It is 1 if the key was previously down and 0 if the
key was previously up. You can use this flag to identify keystroke messages generated by
the keyboard's automatic repeat feature. This flag is set to 1 for WM_KEYDOWN and
WM_SYSKEYDOWN keystroke messages generated by the automatic repeat feature. It
is always set to 0 for WM_KEYUP and WM_SYSKEYUP messages.

Transition-State Flag

The transition-state flag indicates whether pressing a key or releasing a key generated the
keystroke message. This flag is always set to 0 for WM_KEYDOWN and
WM_SYSKEYDOWN messages; it is always set to 1 for WM_KEYUP and
WM_SYSKEYUP messages.
16.1.4 Character MessagesKeystroke messages provide a lot of information about keystrokes, but they don't provide
character codes for character keystrokes. To retrieve character codes, an application must
include the TranslateMessage function in its thread message loop. TranslateMessage

passes a WM_KEYDOWN or WM_SYSKEYDOWN message to the keyboard layout.
The layout examines the message's virtual-key code and, if it corresponds to a character
key, it provides the character code equivalent (taking into account the state of the SHIFT
Input Devices 7
and CAPS LOCK keys). It then generates a character message that includes the character
code and places the message at the top of the message queue. The next iteration of the
message loop removes the character message from the queue and dispatches the message
to the appropriate window procedure.

16.1.4.1 Non-system Character Messages

A window procedure can receive the following character messages: WM_CHAR,
WM_DEADCHAR, WM_SYSCHAR, WM_SYSDEADCHAR, and WM_UNICHAR.
The TranslateMessage function generates a WM_CHAR or WM_DEADCHAR

message when it processes a WM_KEYDOWN message. Similarly, it generates a
WM_SYSCHAR or WM_SYSDEADCHAR message when it processes a
WM_SYSKEYDOWN
message.
An application that processes keyboard input typically ignores all but the WM_CHARand WM_UNICHAR messages, passing any other messages to the DefWindowProc function. Note that WM_CHAR uses 16-bit Unicode transformation format (UTF) while
WM_UNICHAR uses UTF-32. The system uses the WM_SYSCHAR and
WM_SYSDEADCHAR messages to implement menu mnemonics.
The wParam parameter of all character messages contains the character code of the
character key that was pressed. The value of the character code depends on the window
class of the window receiving the message. If the Unicode version of the RegisterClass
function was used to register the window class, the system provides Unicode characters
to all windows of that class. Otherwise, the system provides ASCII character codes. For
more information, see Unicode and Character Sets.
The contents of the lParam parameter of a character message are identical to the contents
of the lParam parameter of the key-down message that was translated to produce the
character message.

16.1.4.2 Dead-Character Messages

Some non-English keyboards contain character keys that are not expected to produce
characters by them. Instead, they are used to add a diacritic to the character produced by
the subsequent keystroke. These keys are called dead keys. The circumflex key on a
German keyboard is an example of a dead key. To enter the character consisting of an "o"
with a circumflex, a German user would type the circumflex key followed by the "o" key.
The window with the keyboard focus would receive the following sequence of messages:
􀀹 WM_KEYDOWN 􀀹 WM_DEADCHAR 􀀹 WM_KEYUP 􀀹 WM_KEYDOWN 􀀹 WM_CHAR 􀀹 WM_KEYUP Input Devices 8 TranslateMessage generates the WM_DEADCHAR message when it processes the
WM_KEYDOWN message from a dead key. Although the wParam parameter of the
WM_DEADCHAR message contains the character code of the diacritic for the dead
key, an application typically ignores the message. Instead, it processes the WM_CHARmessage generated by the subsequent keystroke. The WM_CHAR parameter of the
WM_CHAR message contains the character code of the letter with the diacritic. If the
subsequent keystroke generates a character that cannot be combined with a diacritic, the
system generates two WM_CHAR messages. The wParam parameter of the first
contains the character code of the diacritic; the wParam parameter of the second contains
the character code of the subsequent character key.
The TranslateMessage function generates the WM_SYSDEADCHAR message when it
processes the WM_SYSKEYDOWN message from a system dead key (a dead key that
is pressed in combination with the ALT key). An application typically ignores the
WM_SYSDEADCHAR message.

16.1.5 Key Status

While processing a keyboard message, an application may need to determine the status of
another key besides the one that generated the current message. For example, a wordprocessing
application that allows the user to press SHIFT+END to select a block of text
must check the status of the SHIFT key whenever it receives a keystroke message from
the END key. The application can use the GetKeyState function to determine the status of
a virtual key at the time the current message was generated; it can use the
GetAsyncKeyState function to retrieve the current status of a virtual key.
The keyboard layout maintains a list of names. The name of a key that produces a single
character is the same as the character produced by the key. The name of a noncharacter
key such as TAB and ENTER is stored as a character string. An application can retrieve
the name of any key from the device driver by calling the GetKeyNameText function.

16.1.6 Key Stroke and Character Translations

The system includes several special purpose functions that translate scan codes, character
codes, and virtual-key codes provided by various keystroke messages. These functions
include MapVirtualKey, ToAscii, ToUnicode, and VkKeyScan.

16.1.7 Hot-key Support

A hot key is a key combination that generates a WM_HOTKEY message, a message the
system places at the top of a thread's message queue, bypassing any existing messages in
the queue. Applications use hot keys to obtain high-priority keyboard input from the user.
For example, by defining a hot key consisting of the CTRL+C key combination, an
application can allow the user to cancel a lengthy operation.
To define a hot key, an application calls the RegisterHotKey function, specifying the
combination of keys that generates the WM_HOTKEY message, the handle to the
Input Devices 9
window to receive the message, and the identifier of the hot key. When the user presses
the hot key, a WM_HOTKEY message is placed in the message queue of the thread that
created the window. The wParam parameter of the message contains the identifier of the
hot key. The application can define multiple hot keys for a thread, but each hot key in the
thread must have a unique identifier. Before the application terminates, it should use the
UnregisterHotKey function to destroy the hot key.
Applications can use a hot key control to make it easy for the user to choose a hot key.
Hot key controls are typically used to define a hot key that activates a window; they do
not use the RegisterHotKey and UnregisterHotKey functions. Instead, an application
that uses a hot key control typically sends the WM_SETHOTKEY message to set the hot
key. Whenever the user presses the hot key, the system sends a WM_SYSCOMMAND
message specifying SC_HOTKEY. For more information about hot key controls, see
"Using Hot Key Controls" in Hot Key Controls.

16.1.8 Languages, Locals, and Keyboard Layouts

A language is a natural language, such as English, French, and Japanese. A sublanguage
is a variant of a natural language that is spoken in a specific geographical region, such as
the English sublanguages spoken in England and the United States. Applications use
values, called language identifiers, to uniquely identify languages and sublanguages.
Applications typically use locales to set the language in which input and output is
processed. Setting the locale for the keyboard, for example, affects the character values
generated by the keyboard. Setting the locale for the display or printer affects the glyphs
displayed or printed. Applications set the locale for a keyboard by loading and using
keyboard layouts. They set the locale for a display or printer by selecting a font that
supports the specified locale.
A keyboard layout not only specifies the physical position of the keys on the keyboard
but also determines the character values generated by pressing those keys. Each layout
identifies the current input language and determines which character values are generated
by which keys and key combinations.
Every keyboard layout has a corresponding handle that identifies the layout and
language. The low word of the handle is a language identifier. The high word is a device
handle specifying the physical layout, or is zero indicating a default physical layout. The
user can associate any input language with a physical layout. For example, an Englishspeaking
user who very occasionally works in French can set the input language of the
keyboard to French without changing the physical layout of the keyboard. This means the
user can enter text in French using the familiar English layout.
Applications are generally not expected to manipulate input languages directly. Instead,
the user sets up language and layout combinations, and then switches among them. When
the user clicks into text marked with a different language, the application calls the
ActivateKeyboardLayout function to activate the user's default layout for that language.
If the user edits text in a language which is not in the active list, the application can call
Input Devices 10
the LoadKeyboardLayout function with the language to get a layout based on that
language.
The ActivateKeyboardLayout function sets the input language for the current task. The
hkl parameter can be either the handle to the keyboard layout or a zero-extended language
identifier. Keyboard layout handles can be obtained from the LoadKeyboardLayout or
GetKeyboardLayoutList function. The HKL_NEXT and HKL_PREV values can also be
used to select the next or previous keyboard.
The GetKeyboardLayoutName function retrieves the name of the active keyboard layout
for the calling thread. If an application creates the active layout using the
LoadKeyboardLayout function, GetKeyboardLayoutName retrieves the same string
used to create the layout. Otherwise, the string is the primary language identifier
corresponding to the locale of the active layout. This means the function may not
necessarily differentiate among different layouts with the same primary language so, it
cannot return specific information about the input language. The GetKeyboardLayout
function, however, can be used to determine the input language.
The LoadKeyboardLayout function loads a keyboard layout and makes the layout
available to the user. Applications can make the layout immediately active for the current
thread by using the KLF_ACTIVATE value. An application can use the
KLF_REORDER value to reorder the layouts without also specifying the
KLF_ACTIVATE value. Applications should always use the KLF_SUBSTITUTE_OK
value when loading keyboard layouts to ensure that the user's preference, if any, is
selected.
For multilingual support, the LoadKeyboardLayout function provides the
KLF_REPLACELANG and KLF_NOTELLSHELL flags. The KLF_REPLACELANG
flag directs the function to replace an existing keyboard layout without changing the
language. Attempting to replace an existing layout using the same language identifier but
without specifying KLF_REPLACELANG is an error. The KLF_NOTELLSHELL flag
prevents the function from notifying the shell when a keyboard layout is added or
replaced. This is useful for applications that add multiple layouts in a consecutive series
of calls. This flag should be used in all but the last call.
The UnloadKeyboardLayout function is restricted in that it cannot unload the system
default input language. This ensures that the user always has one layout available for
enter text using the same character set as used by the shell and file system.
16.1.9 Keyboard Messages (brief)
The following are some of the keyboard messages.
WM_KEYDOWN: when the key down
WM_KEYUP: when the key up
WM_SYSKEYDOWN: when the system key down, e.g. ALT key
Input Devices 11
WM_SYSKEYUP: when the system key up
When user press Ctrl + key then two messages of WM_KEYDOWN and two messages
WM_KEYUP are sent to the Application Message Queue.

16.1.10 Key down message format

The WM_KEYDOWN message is 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.
WM_KEYDOWN
WPARAM wParam //wParam of the key down
LPARAM lParam; /*lParam of the key down
messages*/
wParam: Specifies the virtual-key code of the nonsystem key.
lParam: Specifies the repeat count, scan code, extended-key flag, context code, previous
key-state flag, and transition-state flag, as shown in the following table.
0-15: Specifies 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 keystroke is held long enough, multiple messages are sent. However,
the repeat count is not cumulative.

16-23: Specifies the scan code. The value depends on the OEM.
24: Specifies whether the key is an extended key, such as the right-hand ALT and
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: Specifies the context code. The value is always 0 for a WM_KEYDOWNmessage.
30:
Specifies the previous key state. The value is 1 if the key is down before the
message is sent, or it is zero if the key is up.
31: Specifies the transition state. The value is always zero for a
WM_KEYDOWN message.

16.1.11 Character message format

The WM_CHAR message is posted to the window with the keyboard focus when a
WM_KEYDOWN message is translated by the TranslateMessage function. The
WM_CHAR message contains the character code of the key that was pressed.
Input Devices 12
WM_CHAR
WPARAM wParam /*character code in this message
LPARAM lParam; /*data or scan code of character
parameter*/
wParam: Specifies the character code of the key.
lParam: Specifies the repeat count, scan code, extended-key flag, context code, previous
key-state flag, and transition-state flag.

16.1.12 Getting Key State

GetKeyState function gets the key state either its pressed or un-pressed.
SHORT GetKeyState(
Int vVirtKey) //virtual key code
);
There is another function available which is:
SHORT GetAsyncKeyState(
Int vVirtKey //virtual key code
);
Their complete description can be found from Microsoft Help System.
Input Devices 13

16.1.13 Character Message Processing
Figure 3
16.2 Caret
A caret is a blinking line, block, or bitmap in the client area of a window. The caret
typically indicates the place at which text or graphics will be inserted.
The system provides one caret per message queue. A window should create a caret only
when it has the keyboard focus or is active. The window should destroy the caret before
losing the keyboard focus or becoming inactive.
Use the CreateCaret function to specify the parameters for a caret. The system forms a
caret by inverting the pixel color within the rectangle specified by the caret's position,
width, and height. The width and height are specified in logical units; therefore, the
appearance of a caret is subject to the window's mapping mode.
Enter Key Pressed
WM_CHAR Message Generated
wParam contains ‘\n’ OR
0x0A OR
10
WM_KEYDOWN Message generated
TranslateMessage() is called
Input Devices 14

16.2.1 Caret Visibility

After the caret is defined, use the ShowCaret function to make the caret visible. When the
caret appears, it automatically begins flashing. To display a solid caret, the system inverts
every pixel in the rectangle; to display a gray caret, the system inverts every other pixel;
to display a bitmap caret, the system inverts only the white bits of the bitmap.

16.2.2 Caret Blink Time

The elapsed time, in milliseconds, required to invert the caret is called the blink time. The
caret will blink as long as the thread that owns the message queue has a message pump
processing the messages.
The user can set the blink time of the caret using the Control Panel and applications
should respect the settings that the user has chosen. An application can determine the
caret's blink time by using the GetCaretBlinkTime function. If you are writing an
application that allows the user to adjust the blink time, such as a Control Panel applet,
use the SetCaretBlinkTime function to set the rate of the blink time to a specified number
of milliseconds.
The flash time is the elapsed time, in milliseconds, required to display, invert, and restore
the caret's display. The flash time of a caret is twice as much as the blink time.

16.2.3 Caret Position

You can determine the position of the caret using the GetCaretPos function. The position,
in client coordinates, is copied to a structure specified by a parameter in GetCaretPos.
An application can move a caret in a window by using the SetCaretPos function. A
window can move a caret only if it already owns the caret. SetCaretPos can move the
caret whether it is visible or not.

16.2.4 Removing a Caret

You can temporarily remove a caret by hiding it, or you can permanently remove the
caret by destroying it. To hide the caret, use the HideCaret function. This is useful when
your application must redraw the screen while processing a message, but must keep the
caret out of the way. When the application finishes drawing, it can display the caret again
by using the ShowCaret function. Hiding the caret does not destroy its shape or invalidate
the insertion point. Hiding the caret is cumulative, that is, if the application calls
HideCaret five times, it must also call ShowCaret five times before the caret will
reappear.
To remove the caret from the screen and destroy its shape, use using the DestroyCaret
function. DestroyCaret destroys the caret only if the window involved in the current task
owns the caret.
Input Devices 15

16.2.5 Caret Functions

The following functions are used to handle a caret
􀂾 CreateCaret()
􀂾 DestroyCaret()
􀂾 SetCaretPos()

16.3 Mouse

In old ages or in Dos age, mouse is initialized with the interrupt INT 33h. Now-a-days we
don’t need to use interrupt and its services because we have windows which provides
APIs instead of interrupts. So using these APIs we can handle mouse and its other
properties.
The mouse is an important, but optional, user-input device for applications. A wellwritten
application should include a mouse interface, but it should not depend solely on
the mouse for acquiring user input. The application should provide full keyboard support
as well.
An application receives mouse input in the form of messages that are sent or posted to its
windows.

16.3.1 Mouse Cursor

When the user moves the mouse, the system moves a bitmap on the screen called the
mouse cursor. The mouse cursor contains a single-pixel point called the hot spot, a point
that the system tracks and recognizes as the position of the cursor. When a mouse event
occurs, the window that contains the hot spot typically receives the mouse message
resulting from the event. The window need not be active or have the keyboard focus to
receive a mouse message.
The system maintains a variable that controls mouse speed, that is, the distance the cursor
moves when the user moves the mouse. You can use the SystemParametersInfo function
with the SPI_GETMOUSE or SPI_SETMOUSE flag to retrieve or set mouse speed. For
more information about mouse cursors, see Cursors.

16.3.2 Mouse Capture

The system typically posts a mouse message to the window that contains the cursor hot
spot when a mouse event occurs. An application can change this behavior by using the
SetCapture function to route mouse messages to a specific window. The window receives
all mouse messages until the application calls the ReleaseCapture function or specifies
another capture window, or until the user clicks a window created by another thread.
Input Devices 16
When the mouse captures changes, the system sends a WM_CAPTURECHANGED
message to the window that is losing the mouse capture. The lParam parameter of the
message specifies a handle to the window that is gaining the mouse capture.
Only the foreground window can capture mouse input. When a background window
attempts to capture mouse input, it receives messages only for mouse events that occur
when the cursor hot spot is within the visible portion of the window.
Capturing mouse input is useful if a window must receive all mouse input, even when the
cursor moves outside the window. For example, an application typically tracks the cursor
position after a mouse button down event, following the cursor until a mouse button up
event occurs. If an application has not captured mouse input and the user releases the
mouse button outside the window, the window does not receive the button-up message.
A thread can use the GetCapture function to determine whether one of its windows has
captured the mouse. If one of the thread's windows has captured the mouse, GetCapture
retrieves a handle to the window.

16.3.3 Mouse Configuration

Although the mouse is an important input device for applications, not every user
necessarily has a mouse.
An application can determine whether the system includes a mouse by passing the
SM_MOUSEPRESENT value to the GetSystemMetrics function.
Windows supports a mouse having up to three buttons. On a three-button mouse, the
buttons are designated as the left, middle, and right buttons. Messages and named
constants related to the mouse buttons use the letters L, M, and R to identify the buttons.
The button on a single-button mouse is considered to be the left button. Although
Windows supports a mouse with multiple buttons, most applications use the left button
primarily and the others minimally, if at all.
An application can determine the number of buttons on the mouse by passing the
SM_CMOUSEBUTTONS value to the
GetSystemMetrics function.
To configure the mouse for a left-handed user, the application can use the
SwapMouseButton function to reverse the meaning of the left and right mouse buttons.
Passing the SPI_SETMOUSEBUTTONSWAP value to the SystemParametersInfo

function is another way to reverse the meaning of the buttons. Note, however, that the
mouse is a shared resource, so reversing the meaning of the buttons affects all
applications

16.3.4 Mouse Messages

The mouse generates an input event when the user moves the mouse, or presses or
releases a mouse button. The system converts mouse input events into messages and
Input Devices 17
posts them to the appropriate thread's message queue. When mouse messages are posted
faster than a thread can process them, the system discards all but the most recent mouse
message.
A window receives a mouse message when a mouse event occurs while the cursor is
within the borders of the window, or when the window has captured the mouse. Mouse
messages are divided into two groups: client area messages and nonclient area messages.
Typically, an application processes client area messages and ignores nonclient area
messages.

16.3.4.1 Client Area Mouse Messages

A window receives a client area mouse message when a mouse event occurs within the
window's client area. The system posts the WM_MOUSEMOVE message to the window
when the user moves the cursor within the client area. It posts one of the following
messages when the user presses or releases a mouse button while the cursor is within the
client area.

Message Meaning

WM_LBUTTONDBLCLK The left mouse button was double-clicked.
WM_LBUTTONDOWN The left mouse button was pressed.
WM_LBUTTONUP The left mouse button was released.
WM_MBUTTONDBLCLK The middle mouse button was double-clicked.
WM_MBUTTONDOWN The middle mouse button was pressed.
WM_MBUTTONUP The middle mouse button was released.
WM_RBUTTONDBLCLK The right mouse button was double-clicked.
WM_RBUTTONDOWN The right mouse button was pressed.
WM_RBUTTONUP The right mouse button was released.
In addition, an application can call the TrackMouseEvent function to have the system
send two other messages. It posts the WM_MOUSEHOVER message when the cursor
hovers over the client area for a certain time period. It posts the WM_MOUSELEAVE
message when the cursor leaves the client area.

Message Parameters

The lParam parameter of a client area mouse message indicates the position of the cursor
hot spot. The low-order word indicates the x-coordinate of the hot spot, and the highorder
word indicates the y-coordinate. The coordinates are specified in client coordinates.
In the client coordinate system, all points on the screen are specified relative to the
coordinates (0, 0) of the upper-left corner of the client area.
Input Devices 18
The wParam parameter contains flags that indicate the status of the other mouse buttons
and the CTRL and SHIFT keys at the time of the mouse event. You can check for these
flags when mouse-message processing depends on the state of another mouse button or of
the CTRL or SHIFT key. The wParam parameter can be a combination of the following
values.

Value Meaning

MK_CONTROL The CTRL key is down.
MK_LBUTTON The left mouse button is down.
MK_MBUTTON The middle mouse button is down.
MK_RBUTTON The right mouse button is down.
MK_SHIFT The SHIFT key is down.

Double Click Messages

The system generates a double-click message when the user clicks a mouse button twice
in quick succession. When the user clicks a button, the system establishes a rectangle
centered around the cursor hot spot. It also marks the time at which the click occurred.
When the user clicks the same button a second time, the system determines whether the
hot spot is still within the rectangle and calculates the time elapsed since the first click. If
the hot spot is still within the rectangle and the elapsed time does not exceed the doubleclick
time-out value, the system generates a double-click message.
An application can get and set double-click time-out values by using the
GetDoubleClickTime and SetDoubleClickTime functions, respectively. Alternatively, the
application can set the double-click–time-out value by using the
SPI_SETDOUBLECLICKTIME flag with the SystemParametersInfo function. It can
also set the size of the rectangle that the system uses to detect double-clicks by passing
the SPI_SETDOUBLECLKWIDTH and SPI_SETDOUBLECLKHEIGHT flags to
SystemParametersInfo
. Note, however, that setting the double-click–time-out value and
rectangle affects all applications.
An application-defined window does not, by default, receive double-click messages.
Because of the system overhead involved in generating double-click messages, these
messages are generated only for windows belonging to classes that have the
CS_DBLCLKS class style. Your application must set this style when registering the
window class. For more information, see Window Classes.
A double-click message is always the third message in a four-message series. The first
two messages are the button-down and button-up messages generated by the first click.
The second click generates the double-click message followed by another button-up
message. For example, double-clicking the left mouse button generates the following
message sequence:
Input Devices 19
􀂾 WM_LBUTTONDOWN􀂾 WM_LBUTTONUP

􀂾 WM_LBUTTONDBLCLK

􀂾 WM_LBUTTONUP

Because a window always receives a button-down message before receiving a doubleclick
message, an application typically uses a double-click message to extend a task it
began during a button-down message. For example, when the user clicks a color in the
color palette of Microsoft Paint, Paint displays the selected color next to the palette.
When the user double-clicks a color, Paint displays the color and opens the Edit Colors

dialog box.

16.3.4.2 Non Client Area Mouse Messages

A window receives a nonclient area mouse message when a mouse event occurs in any
part of a window except the client area. A window's nonclient area consists of its border,
menu bar, title bar, scroll bar, window menu, minimize button, and maximize button.
The system generates nonclient area messages primarily for its own use. For example, the
system uses nonclient area messages to change the cursor to a two-headed arrow when
the cursor hot spot moves into a window's border. A window must pass nonclient area
mouse messages to the DefWindowProc function to take advantage of the built-in mouse
interface.
There is a corresponding nonclient area mouse message for each client area mouse
message. The names of these messages are similar except that the named constants for
the nonclient area messages include the letters NC. For example, moving the cursor in the
nonclient area generates a WM_NCMOUSEMOVE message, and pressing the left mouse
button while the cursor is in the nonclient area generates a WM_NCLBUTTONDOWN
message.
The lParam parameter of a nonclient area mouse message is a structure that contains the
x- and y-coordinates of the cursor hot spot. Unlike coordinates of client area mouse
messages, the coordinates are specified in screen coordinates rather than client
coordinates. In the screen coordinate system, all points on the screen are relative to the
coordinates (0,0) of the upper-left corner of the screen.
The wParam parameter contains a hit-test value, a value that indicates where in the
nonclient area the mouse event occurred.

16.3.4.3 The WM_NCHITTEST Message

Whenever a mouse event occurs, the system sends a WM_NCHITTEST message to
either the window that contains the cursor hot spot or the window that has captured the
mouse. The system uses this message to determine whether to send a client area or
nonclient area mouse message. An application that must receive mouse movement and
Input Devices 20
mouse button messages must pass the WM_NCHITTEST message to the
DefWindowProc function.
The lParam parameter of the WM_NCHITTEST message contains the screen
coordinates of the cursor hot spot. The DefWindowProc function examines the
coordinates and returns a hit-test value that indicates the location of the hot spot. The hittest
value can be one of the following values.

Value Location of hot spot

HTBORDER In the border of a window that does not have a sizing border.
HTBOTTOM In the lower-horizontal border of a window.
HTBOTTOMLEFT In the lower-left corner of a window border.
HTBOTTOMRIGHT In the lower-right corner of a window border.
HTCAPTION In a title bar.
HTCLIENT In a client area.
HTCLOSE In a Close button.
HTERROR
On the screen background or on a dividing line between windows
(same as HTNOWHERE, except that the DefWindowProc

function produces a system beep to indicate an error).
HTGROWBOX In a size box (same as HTSIZE).
HTHELP In a Help button.
HTHSCROLL In a horizontal scroll bar.
HTLEFT In the left border of a window.
HTMENU In a menu.
HTMAXBUTTON In a Maximize button.
HTMINBUTTON In a Minimize button.
HTNOWHERE On the screen background or on a dividing line between windows.
HTREDUCE In a Minimize button.
HTRIGHT In the right border of a window.
HTSIZE In a size box (same as HTGROWBOX).
HTSYSMENU In a System menu or in a Close button in a child window.
HTTOP In the upper-horizontal border of a window.
HTTOPLEFT In the upper-left corner of a window border.
HTTOPRIGHT In the upper-right corner of a window border.
HTTRANSPARENT In a window currently covered by another window in the same
thread.
HTVSCROLL In the vertical scroll bar.
HTZOOM In a Maximize button.
If the cursor is in the client area of a window, DefWindowProc returns the HTCLIENT
hit-test value to the window procedure. When the window procedure returns this code to
Input Devices 21
the system, the system converts the screen coordinates of the cursor hot spot to client
coordinates, and then posts the appropriate client area mouse message.
The DefWindowProc function returns one of the other hit-test values when the cursor
hot spot is in a window's nonclient area. When the window procedure returns one of these
hit-test values, the system posts a nonclient area mouse message, placing the hit-test
value in the message's wParam parameter and the cursor coordinates in the lParam
parameter.

16.3.5 Screen and Client Area Coordinates

Screen coordinates start from the top left corner of the screen and end to right bottom
coordinates of the screen.
But Client Area coordinates start from the top left coordinate of the client area of the
window and ends with right-bottom coordinate of the client area of the window.
These coordinates can be converted to each other. Conversion from screen area
coordinates to client area coordinates can be done by using function
BOOL ScreenToClient(
HWND hWnd, //handle to the window
LPPOINT lpPoint //point structure
);
And conversion from client area coordinates of window to screen area coordinates can be
done by using function.
BOOL ClientToScreen(
HWND hWnd, //handle to the window
LPPOINT lpPoint //point structure
);

Summary

In this lecture, we studied about the input devices. Input devices include keyboard
and mouse. Keyboard is used to input the system. Whenever we press a key on keyboard,
we generate a message. This message directly goes to the Operating system and then rout
to our application. Keyboard messages include Key down and key up messages. Another
type of messages is character messages these messages also come from keyboard.
Keyboard messages are translated to their Character values and then send to the
application in form of character message. Mouse is another input device. Almost all user
interfaces uses mouse as input device as well as keyboard. Mouse device is optional in
the system but useful in complex applications. Mouse can be used to point anywhere on
screen. Mouse sends different messages e.g. mouse can send left button down message
when the mouse left button is down and in the same way left button up message when the
left button is up. During the movement of mouse pointer on screen mouse move message
Input Devices 22
is always sent. During input session, caret is used to position the keyboard. Caret shows
character can be placed where the caret is blinking.

Exercises

1. Create your own status bar and show it in a window at its proper location. This
status bar should display current time and NUM Lock, CAPS LOCK, SCROLL
lock states. If these keys are pressed show them otherwise don’t show.
2. Using the mouse messages draw a line which starts when a mouse left button is
down and end when the mouse left button is up. During the mouse pressed state if
ESC key is pressed the process should be cancelled and line should not be drawn.

<Previous Lesson

Visual Programming

Next Lesson>

Home

Lesson Plan

Topics

Go to Top

Next Lesson
Previous Lesson
Lesson Plan
Topics
Home
Go to Top