private static KeyPressEventArgsExt CreateNonChar()
 {
     KeyPressEventArgsExt e = new KeyPressEventArgsExt((char)0x0);
       e.IsNonChar = true;
       e.Timestamp = Environment.TickCount;
       return e;
 }
        /// <summary>
        /// Creates <see cref="KeyPressEventArgsExt"/> from Windows Message parameters,
        /// based upon a system-wide hook.
        /// </summary>
        /// <param name="wParam">The first Windows Message parameter.</param>
        /// <param name="lParam">The second Windows Message parameter.</param>
        /// <returns>A new KeyPressEventArgsExt object.</returns>
        internal static KeyPressEventArgsExt FromRawDataGlobal(int wParam, IntPtr lParam)
        {
            if (wParam != Messages.WM_KEYDOWN) {
            return CreateNonChar();
              }

              KeyboardHookStruct keyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

              int virtualKeyCode = keyboardHookStruct.VirtualKeyCode;
              int scanCode = keyboardHookStruct.ScanCode;
              int fuState = keyboardHookStruct.Flags;

              char ch;
              bool isSuccessfull = Keyboard.TryGetCharFromKeyboardState(virtualKeyCode, scanCode, fuState, out ch);
              if (!isSuccessfull) {
            return CreateNonChar();
              }

              KeyPressEventArgsExt e = new KeyPressEventArgsExt(ch);
              e.Timestamp = keyboardHookStruct.Time;		// Update the timestamp to use the actual one from KeyboardHookStruct

              return e;
        }