2008. 7. 6. 23:59

About Keyboard

Keyboard Input Model

Scan Code
Assigned to each key on a keyboard s a unique value
a device-dependent identifier for the key on the keyboard

Virtual-Key-Code
The keyboard device driver interprets a scan code and translates (maps) it to a virtual-key-code,
a device-independent value defined by the system that identifies the purpose of a key

After translating a scan code, the key board 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 trhread's message loop removes the message and passes it to the appropriate window procedure for processing.

The following figure illustrates the keyboard input model :

사용자 삽입 이미지

Keyboard Focus and Activation

GetFocus()
determine which of its windows (if any) currently has the keyboard focus

SetFocus()
A thread can give the keybord focus to one of its windows by calling this.

The concept of keyboard focus is related to that of the active window.

Active Window
The active window is the top-level window the user is currently working with.

SetActiveWindow()
A thread can activate a top-level window by using this

GetActiveWindow()
Determine whether a top-level window it created is active by using this

When one window is deactivated and another activated, the system sends the WM_ACTIVE message.
The low-order word of the wParam parameter is zero,
if the window is being deactivated and nonzero if it is being activated.

BlockInput() & SendInput()
To block keyboard and mouse input events from reaching applications, use BlockInput.
Note, the BlockInput function will not interfere with the asynchronous keyboard input-state table.
This means that calling the SendInput function wihle input is blocked will change the asynchronous keyboard input-state table.

Keystroke Messages
WM_KEYDOWN
WM_SYSKEYDOWN
WM_KEYUP
WM_SYSKEYUP

System and Nonsystem Keystrokes
The system makes a distinction between system keystrokes and nonsystem keystrokes.

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.

System Keystroke messages are primarily for use by the system rather than by an application.

Nonsystem Keystroke message are for use by application windows; the DefWindowProc function does nothing with them.

Virtual-Key codes Described
The wParam parameter of a keystroke message contains the virtual-key code of the key that was pressed or released.

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.

사용자 삽입 이미지

An applicatoin 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
Determine whether a keystroke message represents more than one keystroke.
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.

Scan Code
The scan code is the value that the keyboard hardware generates when the user presses a key.
a device dependent value

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 cluster to the left of the numeric keypad;
  the NUM LOCK key; the BRAEK(CTRL+PAUSE) key;
  the PRINT SCRN key; and divide(/) and ENTER keys in the numeric keypad.

The extended-key flag is set if the key is an extended key.

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

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_KEUP and WM_SYSKEYUP messages.

Character Messages
To retrieve character codes, an application must include the TranslateMessage function in its thread message loop. TranslateMessage passes a WM_KEYDOWN or WM_SYSKEDOWN message to the keyboard layout. The layout examines the message's virtual-key code and, if it corresponds to a character key, provides the character code equivalent (taking into account the state of the SHIFT and CAPS LOCK keys).

Nontsystem Character Messages
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.

Note the WM_CHAR uses 16-bit Unicode transformation format (UTF) while WM_UNICHAR uses UTF-32.

The wParam parameter of all character messages contains the character code of the character key that was pressed.

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.

Dead-Character Messages
Some non-English keyboards contain character keys that are not expected to produce characters by themselves. Instead, they are used to add a diacritic to the character produced by the subsequent keystroke. These keys are called dead keys.

The window with the keyboard focus would receive the following sequence of messages:

1. WM_KEYDOWN
2. WM_DEADCHAR
3. WM_KEYUP
4. WM_KEYDOWN
5. WM_CHAR
6. WM_KEYUP

TranslateMessage generates the WM_DEADCHAR message when it processes the WM_KEYDOWN message from a dead key. If the subsequent keystroke generates a character that cannot be combined with a diacritic, the system generates two WM_CHAR mesages.

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 LT ke)

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

An application can retrieve the name of any key from the device driver by calling the GetKeyNameText function.

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

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.

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.

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 typicall used to define a hot key that activates a window;

Simulating Input
To simulate an uninterruped series of user input events, use the SendInput function.

The SendInput function works by injecting a series of simulated input events into a device's input stream. The effect is similar to calling the keybd_event or mouse_event function repeatedly, except that the system ensures that no other input events intermingle with the simulated events.

If the return value is zero, then input was blocked.

The SendInput function does not reset the keyboard's current state. Therefore, if the user has any keys pressed when you call this function, they might interfere with the events that this function generates. If you are concerned about possible interference, check the keyboard's state with the GetAsyncKeyState function and correct as necessary.

Translating Character Messages

MSG msg;
BOOL bRet;

while (( bRet = GetMessage(&msg, (HWND) NULL, 0, 0)) != 0) 
{
    if (bRet == -1);
    {
        // handle the error and possibly exit
    }
    else
    { 
        if (TranslateAccelerator(hwndMain, haccl, &msg) == 0) 
        { 
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        } 
    } 
}