I am writing a virtual keyboard application that reads windows KBD file to build the keyboard. I am having trouble understanding how to interpret the array of characters returned for each virtual key.
I am using the kbd.h files in this CodePlex project.
Here is the struct that I am not understanding.
typedef struct {
PVK_TO_BIT pVkToBit; // Virtual Keys -> Mod bits
WORD wMaxModBits; // max Modification bit combination value
BYTE ModNumber[]; // Mod bits -> Modification Number
} MODIFIERS, *KBD_LONG_POINTER PMODIFIERS;
When reading the documentation, and analyzing the results with a US keyboard, this struct and its contained data makes sense.
---------------
US
---------------
CharModifiers
0001 = SHIFT
0010 = CTRL
0100 = ALT
ModNumber
0000 = 0 = BASE
0001 = 1 = SHIFT
0010 = 2 = CTRL
0011 = 3 = SHIFT + CTRL
What this says is that for the array of characters returned for each virtual key (another kbd.h struct), the first one represents no modifiers, the second represents the value when SHIFT
is held, and so on. This is accurate and maps perfectly to the array of characters returned for each virtual key.
However, if I load a German keyboard layout (KBDGR.dll), the PMODIFIERS doesn't line up with array of characters returned for each virtual key.
---------------
German
---------------
CharModifiers
0001 = SHIFT
0010 = CTRL
0100 = ALT
ModNumber
0000 = 0 = BASE = REALLY BASE
0001 = 1 = SHIFT = REALLY SHIFT
0011 = 3 = SHIFT + CTRL = REALLY ALTGR
0100 = 4 = ALT = REALLY CTRL
1111 = 15 = INVALID = INVALID
1111 = 15 = INVALID = INVALID
0010 = 2 = CTRL = REALLY SHIFT + CTRL
0101 = 5 = SHIFT + ALT = REALLY SHIFT + ALTGR
As you can see here, for example, 0010 should correlate with just a CTRL
modifier, however, the character returned from the virtual key really represents SHIFT + CTRL
.
What am I not understanding? I thought that the array of ModNumber describes each index of characters for each virtual key, and the modifier keys they represent. This assumption worked correctly for the US keyboard layout, but when not for the German keyboard layout?
I emailed the makers of KbdEdit for their input, and they just replied with the answer!
The zero-based position within ModNumber array defines the modifier combination: eg, the last element "2" is at position 6, whose binary representation is 110, ie KBDCTRL | KBDALT, ie AltGr (www.kbdedit.com/manual/low_level_modifiers.html#AltGr) The value "2" means that AltGr mappings will appear at index 2 in all aVkToWchX[] arrays (for X>=3).
The position 3 corresponds to Shift+Ctrl (= 011 = KBDSHIFT | KBDCTRL) - you see that this combination is to be found at aVkToWchX[4] (for X>=5)
If you open the German layout in KbdEdit, you will see that indeed AltGr is at position 2, and Shift+Ctrl at position 4 (zero based) - see attached screenshot.
Hope this helps.
Regards, Ivica
Thanks Ivica!