title: Reading keyboard KBD.dll files and understanding modifier states
body: <p>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.</p>
  
  <p>I am using the kbd.h files in <a href="http://www.codeproject.com/Articles/439275/Loading-keyboard-layout-KbdLayerDescriptor-in-32-6" rel="nofollow">this CodePlex project</a>.</p>
  
  <p>Here is the struct that I am not understanding.</p>
  
  <pre><code>typedef struct {
      PVK_TO_BIT pVkToBit;     // Virtual Keys -&gt; Mod bits
      WORD       wMaxModBits;  // max Modification bit combination value
      BYTE       ModNumber[];  // Mod bits -&gt; Modification Number
  } MODIFIERS, *KBD_LONG_POINTER PMODIFIERS;
  </code></pre>
  
  <p>When reading the documentation, and analyzing the results with a US keyboard, this struct and its contained data makes sense.</p>
  
  <pre><code>---------------
  US
  ---------------
  CharModifiers
  0001    = SHIFT
  0010    = CTRL
  0100    = ALT
  ModNumber
  0000    = 0     = BASE
  0001    = 1     = SHIFT
  0010    = 2     = CTRL
  0011    = 3     = SHIFT + CTRL
  </code></pre>
  
  <p>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 <code>SHIFT</code> is held, and so on. This is accurate and maps perfectly to the array of characters returned for each virtual key.</p>
  
  <p>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.</p>
  
  <pre><code>---------------
  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
  </code></pre>
  
  <p>As you can see here, for example, 0010 should correlate with just a <code>CTRL</code> modifier, however, the character returned from the virtual key really represents <code>SHIFT + CTRL</code>.</p>
  
  <p>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?</p>