|
|
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. |
|
|
|