Input: 3.2 Keyboard Input: Keyboard Events

Up: GEOS SDK TechDocs | Up | Prev: 3.1 Keyboard Input Flow | Next: 4 Pen Input and Ink

Each Keyboard event your application and objects receive has gone through preliminary parsing by the keyboard driver. Keyboard drivers are intelligent enough to know several things about different types of keystrokes depending on the character set and the modifier keys held down.

All Keyboard events pass two sets of information: the current character as interpreted by the keyboard driver, and the actual scan code of the character pressed. This allows you to do additional parsing or to ignore any extraneous information about the keypress that may have been included by the driver.

For example, if the user presses Ctrl-1 , the keyboard driver passes on the character "1" with a flag indicating the Ctrl key was pressed. If the user presses Shift-1 , the keyboard driver passes on the "!" character without a flag indicating the Shift key is pressed (the Shift key is eaten by the keyboard driver); in this case, it also passes on the scan code of the "1" key. If the user then presses Ctrl-Shift-1 , different keyboard drivers may pass different characters. Whether the driver passes "1" or "!," however, the scan code for the "1" key will also be passed.

The keyboard driver also understands special "extended" keypresses and "temporary accents". Some keyboard drivers may use two keystrokes to specify special characters; for example, some keyboard drivers may require the ö character to be entered as "Ctrl-q o" (this is called an extended keypress), and some may require it to be entered as two separate keys: the "o" and the umlaut (this is called a temporary accent).

In addition to the actual character and the scan code, every Keyboard event gives flags indicating the state of the modifier keys (Ctrl, Alt, Shift), the state of the toggle keys (Caps Lock, Num Lock, etc.), and what type of event it is (first press, repeated press, release, or first press of an extended sequence).

Standard Keyboard events come in MSG_META_KBD_CHAR . This message has the same parameters and return values as its pre-passive and post-passive counterparts, MSG_META_PRE_PASSIVE_KBD_CHAR and MSG_META_POST_PASSIVE_KBD_CHAR . The parameters are listed below:

character
The character value determined by the keyboard driver and Input Manager.
flags
A word value: The high byte is a record of ShiftState detailing the modifier keys pressed, and the low byte is a record of CharFlags giving information about the type of character passed. Both of these records are detailed below.
state
A word value: The high byte is the scan code of the key pressed (without modifiers), and the low byte is a record of ToggleState detailing the state of the toggle keys. ToggleState is detailed below.

Three different records of flags define the Keyboard event. The ShiftState record describes which modifier keys are pressed and has the following flags:

SS_LALT
The left Alt key is pressed.
SS_RALT
The right Alt key is pressed.
SS_LCTRL
The left Ctrl key is pressed.
SS_RCTRL
The right Ctrl key is pressed.
SS_LSHIFT
The left Shift key is pressed.
SS_RSHIFT
The right Shift key is pressed.
SS_FIRE_BUTTON_1
The first joystick-style "fire button" (if any) is pressed.
SS_FIRE_BUTTON_2
The second joystick-style "fire button" (if any) is pressed.

The ToggleState record describes which toggle keys are currently active. It has the following flags.

TS_CAPSLOCK
The Caps Lock is set.
TS_NUMLOCK
The Num Lock is set.
TS_SCROLLLOCK
The Scroll Lock is set.

The CharFlags record contains several flags indicating whether this event is a first press, a release, a repeat press, or an extended or temporary character. Its flags are listed below.

CF_STATE_KEY
Set if either a ShiftState key or a ToggleState key is being pressed along with the passed character.
CF_EXTENDED
Set if this event is part of an extended keystroke. This flag is generally only used by the keyboard driver during its parsing; you will not have to use it. (Extended keypresses are passed by the Input Manager to your application as a single event with the resultant character, not as two events.)
CF_TEMP_ACCENT
Set if this event is part of a temporary accent keystroke. Temporary accents are used only by the keyboard driver, like extended keypresses above.
CF_FIRST_PRESS
Set if the event represents the user's first press of the key. This is akin to a button press event and will, at some point, be followed by a CF_RELEASE event.
CF_REPEAT_PRESS
Set if the event is generated by the user holding down the key (as opposed to a first press, above). If you want the user to hit the key for each individual character, you should ignore this type of event.
CF_RELEASE
Set if the user lets up on a key. Applications typically are not interested in these events for text, and they can automatically be ignored by setting GVA_DONT_SEND_KBD_RELEASES in your GenView's instance data (this only affects handling Keyboard events in visible objects).

A sample handler for MSG_META_KBD_CHAR is shown in Sample MSG_META_KBD_CHAR Handler . It is used by a visible object that simply increments one of its instance fields each time the greater-than key (>) is pressed.

Code Display 11-1 Sample MSG_META_KBD_CHAR Handler

/* This method is used by a visible object of MyVisObjClass. It takes all
 * occurrences of the greater-than (>) key and increments the object's MVOCI_data
 * instance field, ignoring when the user holds down the key. Also, the GenView
 * is set to pass along key releases as well as presses; the method must also
 * ignore releases.
 *
 * Note that the object will only get keyboard input when it has the focus. */
/* The format of this message is
 * void (word character, word flags, word state) */
@method MyVisObjClass, MSG_META_KBD_CHAR {
	/* First, check if the character is the one we want. */
    if (character == `>') {
	/* If it is, make sure the user is not holding the key down and
	 * that this is not a release event. Check that CF_REPEAT_PRESS and
	 * CF_RELEASE are not set in the low byte of the flags parameter.
	 * If either is set, ignore the character and send MSG_META_FUP_KBD_CHAR
	 * so the UI may provide default keyboard navigation. */
	if ((flags & CF_REPEAT_PRESS) || (flags & CF_RELEASE)) {
	    @call self::MSG_META_FUP_KBD_CHAR(character, flags, state);
	} else {
	    /* If we get here, we know the character is what we want. Increment
	     * the instance field and return. */
	    (pself->MVOCI_data)++;
	}
	/* If the character is not a greater-than, we must send it on to the UI
	 * with MSG_META_FUP_KBD_CHAR. If we do not, all other keyboard presses
	 * we receive will never be handled; this will cause keyboard
	 * accelerators and menu navigation not to work. */
    } else {
	@call self::MSG_META_FUP_KBD_CHAR(character, flags, state);
    }
}

Up: GEOS SDK TechDocs | Up | Prev: 3.1 Keyboard Input Flow | Next: 4 Pen Input and Ink