title: SendInput sequence to create unicode character fails
body: <p>I'm working with an on-screen keyboard that needs to send key strokes to a third party application. They are running on Windows XP. A small set of characters that are not available on the US English keyboard need to be supported (such as "å" or ñ). After reviewing SendInput it seemed like the safest thing would be to send the hex unicode value of the character as a key stroke sequence. I wrote code that sends an "Alt" and "Add" key down event, followed by key down and up events for the four character unicode sequence with the Alt key ORed, then finally "Add" and "Alt" key up events. In my C# test app. I am using KeyPreview and sure enough, all of the events are coming through however all I get is a beep, no character. I have captured the same information from entering the key strokes manually, the KeyPreview information is identical, and the character appears.</p>
  
  <p>Is it possible to use SendInput in this way? I haven't used a hook to examine the data but I've seen posts that indicate SendInput events have some sort of "injected" flag attached, maybe this causes the sequence to fail?</p>
  
  <p>This demo code successfully sends key events, but a sequence of key events intended to generate a unicode character fails.</p>
  
  <pre><code>    private const uint KEYEVENTF_KEYDOWN = 0x0000;
      private const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
      private const uint KEYEVENTF_KEYUP = 0x0002;
  
      private const int INPUT_KEYBOARD = 1;
  
      [DllImport ("user32.dll", SetLastError = false)]
      static extern IntPtr GetMessageExtraInfo ();
  
      [DllImport ("user32.dll", SetLastError = true)]
      static extern uint SendInput (uint nInputs, [MarshalAs (UnmanagedType.LPArray, SizeConst = 1)] INPUT[] pInputs, int cbSize);
  
      [StructLayout (LayoutKind.Sequential, Size = 24)]
      private struct KEYBDINPUT
      {
          public ushort wVk;
          public ushort wScan;
          public uint dwFlags;
          public uint time;
          public IntPtr dwExtraInfo;
      }
  
      [StructLayout (LayoutKind.Explicit)]
      private struct INPUT
      {
          [FieldOffset (0)]
          public int type;
          [FieldOffset (4)]
          public KEYBDINPUT ki;
      }
  
      private void PressKey (Keys k)
      {
          PressKeyDown (k);
          PressKeyUp (k);
      }
  
      private void PressKeyDown (Keys k)
      {
          INPUT input = new INPUT ();
          input.type = INPUT_KEYBOARD;
          input.ki.wVk = (byte)k;
          input.ki.wScan = 0;
          input.ki.time = 0;
  
          uint flags = KEYEVENTF_KEYDOWN;
          if ((33 &lt;= (byte)k &amp;&amp; (byte)k &lt;= 46) || (91 &lt;= (byte)k) &amp;&amp; (byte)k &lt;= 93)
              flags |= KEYEVENTF_EXTENDEDKEY;
          input.ki.dwFlags = flags;
  
          input.ki.dwExtraInfo = GetMessageExtraInfo ();
  
          Output ("Sending key down {0}. Flags:{1}", k, flags);
  
          INPUT[] inputs = new INPUT[] { input };
          uint result = SendInput ((uint)inputs.Length, inputs, Marshal.SizeOf (typeof (INPUT)));
  
          if ((uint)inputs.Length != result)
              MessageBox.Show ("PressKeyDown result = " + Marshal.GetLastWin32Error ());
      }
  
      private void PressKeyUp (Keys k)
      {
          INPUT input = new INPUT ();
          input.type = INPUT_KEYBOARD;
          input.ki.wVk = (byte)k;
          input.ki.wScan = 0;
          input.ki.time = 0;
  
          uint flags = KEYEVENTF_KEYUP;
          if ((33 &lt;= (byte)k &amp;&amp; (byte)k &lt;= 46) || (91 &lt;= (byte)k) &amp;&amp; (byte)k &lt;= 93)
              flags |= KEYEVENTF_EXTENDEDKEY;
          input.ki.dwFlags = flags;
  
          input.ki.dwExtraInfo = GetMessageExtraInfo ();
  
          Output ("Sending key up {0}", k);
  
          INPUT[] inputs = new INPUT[] { input };
          uint result = SendInput ((uint)inputs.Length, inputs, Marshal.SizeOf (typeof (INPUT)));
  
          if ((uint)inputs.Length != result)
              MessageBox.Show ("PressKeyUp result = " + Marshal.GetLastWin32Error ());
      }
  
      private void TestSend ()
      {
          System.Threading.Thread.CurrentThread.Join (1000);
  
          Keys k = Keys.Menu;
          PressKeyDown (k);
  
          System.Threading.Thread.Sleep (100);
  
          k = Keys.Add;
          k |= Keys.Alt;
          PressKeyDown (k);
  
          System.Threading.Thread.Sleep (100);
  
          k = Keys.NumPad0;
          k |= Keys.Alt;
          PressKey (k);
  
          System.Threading.Thread.Sleep (100);
  
          k = Keys.NumPad0;
          k |= Keys.Alt;
          PressKey (k);
  
          System.Threading.Thread.Sleep (100);
  
          k = Keys.E;
          k |= Keys.Alt;
          PressKey (k);
  
          System.Threading.Thread.Sleep (100);
  
          k = Keys.NumPad5;
          k |= Keys.Alt;
          PressKey (k);
  
          System.Threading.Thread.Sleep (100);
  
          PressKeyUp (Keys.Add);
          PressKeyUp (Keys.Menu);
      }
  </code></pre>