FUNCTIONAL MAP OF ALL KEYBOARD MODIFIER KEYS
The keyboard, as seen by the system, is simply a set of buttons each with its own identification code; when a button is pressed, it is the system that, based on the button's identification code, assigns a particular meaning to that button.
For each button on the keyboard, the system reserves a memory bit: this memory bit is inverted with each click of a button, thus storing the last action performed for each button: this is how buttons such as
NumLock or
CapsLock keep their action effective even after they have been pressed, until the next click of the same button: it is the system, then, that completely defines the operation of the keyboard.
As for immediate action keys (character keys for example) it is always the system that identifies the code of the key pressed and, while storing the state inversion for that key, disregards it and immediately prints a character corresponding to the identified key pressed code (for motion keys the behavior is very similar: it does not prints any character but performs the movement corresponding to the identified key code).
This function reads system-wide values; it does not read the codes for each key on the keyboard.
This function reads and reports the physical position and value of all modifier keys on the keyboard: to do this it uses the API function
GetKeyState(...) once for each key to be detected.
Physical position means whether at the time of the test the key is pressed (1) or not pressed (0); value means the value stored through previous key presses: each individual modifier key each time it is pressed sets (1) or resets (0) a value of its own within the keyboard: this value remains stored in memory relative to the keyboard until the next click of the same key (Toggle effect).
Immediate-action keys are also handled in the same way, but are instead subject to a bug further below; since these keys are not detected by this function the problem is almost negligible, except for the
INS key, which, contrary to popular belief, is not a modifier key (note that it is not a modifier key since it has independent effect in each program in which the keyboard acts).
According to the tests performed, there is only one system memory for all connected keyboards (even if 2 or more keyboards are connected at the same time: in such a case, it is as if only one keyboard with many keys indistinguishable from keyboard to keyboard were connected): it is therefore possible, for example, to press the
SHIFT key on one keyboard and the
l key on another keyboard to obtain the character
L: this implies, also, that the values returned by this function are relative to a keyboard only if there is only one keyboard connected to the computer: conversely, if multiple keyboards are connected, the values returned by this function are relative to all keyboards simultaneously.
A clear visualization of this effect is through the
CAPS LOCK key: if you press this key on one keyboard it changes the switching on or off of the LED related to that key on all other keyboards as well.
In practice, the set defined while using one keyboard is also valid for all other possibly connected keyboards, and can be changed by each one at any time using its keys, while still remaining valid for all connected keyboards.
All keys really have 2 independent binary values, both of which are managed by the Operating System and stored in the memory related to the keyboard:
- Instantaneous value at the time of the test (0 or 1 depending on whether the key is not pressed or pressed, respectively, at the time of the test);
- Toggle value, INVERTED each time the key is clicked; at the start of the test program and at the time of the test, this value can be 0 or 1 (because it is not known whether such a key has been pressed previously and therefore whether it has inverted its Toggled value); in practice, changing this value indicates that in the meantime, since the previous test, the key has been pressed an odd number of times, at least 1, even if at the time of the test the key is not pressed;
- holding down a key causing automatic repetition does not generate automatic reversal of the Toggle level of that key, but always keeps the Toggle level equal to the value generated at the time of the key click: both the level and the Toggle value refer to the physical click on the key, NOT to the effect it causes (the generation of a character, the movement of the cursor, or other);
- modifier keys store their Toggle value in memory relative to the keyboard, and therefore their value is always the same in all programs in which the keyboard operates;
- BUG: for immediate action keys (e.g., a normal alphabetic letter key, but also INS), starting from the start of the test program, until the first button click is made, any tests of the stored value always return 0 even if the actual value is 1: that actual value will be correctly detected from the next button click onward and can be correctly tested from then on; since the initial value of Toggle for each button can be either 0 or 1, it is not possible to determine that value BEFORE the first click of that button; instead, the test performed immediately after the first click returns the actual value of Toggle, and from then on all clicks of that value will return the exact result.
The GetKeyState(..., T) function is subject to this bug since it reads this same value.
The keys definitely NOT subject to this bug are the following:
NUMLOCK
SCROLLLOCK
CAPITALSLOCK
LEFTCONTROL
RIGHTCONTROL
LEFTALT
RIGHTALT
LEFTSHIFT
RIGHTSHIFT
LEFTWIN
RIGHTWIN
APPS
ESCAPE
ENTER
BACKSPACE
TAB
- automatic repetition, which exists for character keys, shift keys, and others, is handled completely by the system.
State modifier keys are all those that by themselves do not act but modify the operation of the keyboard by keys that do act (e.g., the
CAPS LOCK key causes the next tadsti character typed on the keyboard to be considered lowercase or uppercase letters).
In the case of duplicate keys (such as
CONTROL, for example, of which there are normally 2 keys, one on the left and one on the right), the system memory relative to the keyboard has 1 bit for each individual modifier key both left and right, reversing the value of that bit with each click of each individual key: in this way at each click of each individual modifier key the state of the corresponding bit is inverted; this function reads the individual storage bits of each modifier key (and thus, in the case in example, the stored value of
LEFT CONTROL and the stored value of
RIGHT CONTROL are read), as well as the instantaneous value of the individual keys.
The detected modifier keys are:
NUM LOCK
SCROLL LOCK
CAPS LOCK
LEFT CTRL
RIGHT CTRL
LEFT ALT
RIGHT ALT
LEFT SHIFT
RIGHT SHIFT
LEFT WIN
RIGHT WIN
APPS
ALT GR : This key (ALTernate GRaphic), if present in the keyboard, is handled by the keyboard in the same way as the simultaneous
LEFT CONTROL +
RIGHT ALT click (i.e., in short, it replaces
Ctrl + Alt), causing all the effects of that action: if
ALT GR is pressed at the time this function is called, the instantaneous values of
LEFT CONTROL and
RIGHT ALT correspond to 1; in addition, the
ALT GR click simultaneously reverses the individual stored values of
LEFT CONTROL and
RIGHT ALT.
This key, therefore, has no corresponding identifying value, but the click of this key must be deduced from the reading of the instantaneous and stored values of
LEFT CLICK and
RIGHT ALT.
- The first 3 keys (NUM LOCK, SCROLL LOCK, CAPS LOCK, state modifiers) have the obvious feature on the keyboard of having an LED that displays their active state: when the LED is lit, it means that the stored value is active (1) and the effect is permanent even if the key is no longer pressed (e.g. CAPS LOCK: once pressed and released, it changes the next typed alphabetic characters from lower case to upper case or vice versa);
- subsequent modifier keys (double keys such as LEFT CONTROL and RIGHT CONTROL are also considered individually, one by one) have no LEDs on the keyboard, and, although they have a technical operation IDENTICAL to the first 3 keys, they are normally not considered for their stored value but are considered only for their instantaneous click value (active modifiers): in practice they are considered by the system and programs only if they are already pressed at the time of the click of another key of instantaneous operation (e.g., an alphabetic character key); their stored (toggled) value is normally not considered even though it exists and is stored in system memory related to the keyboard, and as such is read by this function.
This function assumes the external definition of the following global variables, defined in the file AHKHID.ahk Extended version (and in the file Constants.ahk, which contains all Virtual keys), which you can include via the directive:
Code: Select all
#Include ...\AHKHID.ahk:
VK_NUMLOCK := 0x90 ; NUMLOCK (keyboard hardware management)
VK_SCROLL := 0x91 ; SCROLL LOCK (keyboard hardware management)
VK_CAPITAL := 0x14 ; CAPITALS LOCK (CAPS LOCK) (keyboard hardware management)
VK_LCONTROL := 0xa2 ; LEFT CONTROL (LEFT CTRL) (keyboard hardware management)
VK_RCONTROL := 0xa3 ; RIGHT CONTROL (RIGHT CTRL) (keyboard hardware management)
VK_LMENU := 0xa4 ; LEFT ALT (keyboard hardware management)
VK_RMENU := 0xa5 ; RIGHT ALT (keyboard hardware management)
VK_LSHIFT := 0xa0 ; LEFT SHIFT (keyboard hardware management)
VK_RSHIFT := 0xa1 ; RIGHT SHIFT (keyboard hardware management)
VK_LWIN := 0x5b ; LEFT WIN (keyboard hardware management)
VK_RWIN := 0x5c ; RIGHT WIN (keyboard hardware management)
VK_APPS := 0x5d ; APPLICATIONS (APPS) (keyboard hardware management)
ARGUMENTS:
RETURN:
String of bits (not binary number) in which each bit represents a value relative to a key; a bit is represented by the value 0 or 1 within the string; sorting starts from the first bit corresponding to the first character on the RIGHT in the string.
The string consists of 2 sets of 13 bits for a total of 28 bits, i.e. 28 characters, of which each can represent 0 or 1; real example:
1000101101001000000000000000
starting from the right, the first set of 14 bits represents the level of each modifier key at the time of the test (key pressed = 1, key not pressed = 0), the second set of 14 bits represents the Toggle value (see description above) of each modifier key.
Bit position 24: stored value of NUM LOCK (0 NumLock not active; 1 NumLock active)
Bit position 23: stored value of SCROLL LOCK (0 ScrollLock not active; 1 ScrollLock active)
Bit position 22: stored value of CAPS LOCK (0 CapsLock not active; 1 CapsLock active)
Bit position 21: stored value of LEFT CTRL
Bit position 20: stored value of RIGHT CTRL
Bit position 19: stored value of LEFT ALT
Bit position 18: stored value of RIGHT ALT
Bit position 17: stored value of LEFT SHIFT
Bit position 16: stored value of RIGHT SHIFT
Bit position 15: stored value of LEFT WIN
Bit position 14: stored value of RIGHT WIN
Bit position 13: stored value of APPS
Bit position 12: NUM LOCK key level
Bit position 11: SCROLL LOCK key level
Bit position 10: CAPS LOCK key level.
Bit position 09: LEFT CTRL key level
Bit position 08: RIGHT CTRL key level.
Bit position 07: key level LEFT ALT
Bit position 06: RIGHT ALT key level
Bit position 05: LEFT SHIFT key level
Bit position 04: RIGHT SHIFT key level
Bit position 03: LEFT WIN key level
Bit position 02: RIGHT WIN key level
Bit position 01: APPS key level