private void PublishKeyPress(char character, char?modifiedCharacter, bool publishModifiedCharacterAsText)
        {
            if (keyStateService.SimulateKeyStrokes)
            {
                Log.DebugFormat("KeyDownUp called with character '{0}' and modified character '{1}'",
                                character.ConvertEscapedCharToLiteral(),
                                modifiedCharacter == null ? null : modifiedCharacter.Value.ConvertEscapedCharToLiteral());

                var virtualKeyCode = character.ToVirtualKeyCode();
                if (virtualKeyCode != null &&
                    !publishModifiedCharacterAsText)
                {
                    publishService.KeyDownUp(virtualKeyCode.Value);
                }
                else if (modifiedCharacter != null)
                {
                    publishService.TypeText(modifiedCharacter.ToString());
                }
            }
        }
        private void PublishKeyPress(char character)
        {
            if (keyStateService.SimulateKeyStrokes)
            {
                var virtualKeyCode = character.ToVirtualKeyCode();
                if (virtualKeyCode != null)
                {
                    Log.InfoFormat("Publishing '{0}' => as virtual key code {1} (using hard coded mapping)",
                                   character.ToPrintableString(), virtualKeyCode);
                    publishService.KeyDownUp(virtualKeyCode.Value);
                    return;
                }

                if (!Settings.Default.PublishVirtualKeyCodesForCharacters)
                {
                    Log.InfoFormat("Publishing '{0}' as text", character.ToPrintableString());
                    publishService.TypeText(character.ToString());
                    return;
                }

                //Get keyboard layout of currently focused window
                IntPtr hWnd = PInvoke.GetForegroundWindow();
                int    lpdwProcessId;
                int    winThreadProcId = PInvoke.GetWindowThreadProcessId(hWnd, out lpdwProcessId);
                IntPtr keyboardLayout  = PInvoke.GetKeyboardLayout(winThreadProcId);

                //Convert this into a culture string for logging
                string keyboardCulture         = "Unknown";
                var    installedInputLanguages = InputLanguage.InstalledInputLanguages;
                for (int i = 0; i < installedInputLanguages.Count; i++)
                {
                    if (keyboardLayout == installedInputLanguages[i].Handle)
                    {
                        keyboardCulture = installedInputLanguages[i].Culture.DisplayName;
                        break;
                    }
                }

                //Attempt to lookup virtual key code (and modifier states)
                var vkKeyScan = PInvoke.VkKeyScanEx(character, keyboardLayout);
                var vkCode    = vkKeyScan & 0xff;
                var shift     = (vkKeyScan & 0x100) > 0;
                var ctrl      = (vkKeyScan & 0x200) > 0;
                var alt       = (vkKeyScan & 0x400) > 0;

                if (vkKeyScan != -1)
                {
                    Log.InfoFormat("Publishing '{0}' => as virtual key code {1}(0x{1:X}){2}{3}{4} (using VkKeyScanEx with keyboard layout:{5})",
                                   character.ToPrintableString(), vkCode, shift ? "+SHIFT" : null,
                                   ctrl ? "+CTRL" : null, alt ? "+ALT" : null, keyboardCulture);

                    bool releaseShift = false;
                    bool releaseCtrl  = false;
                    bool releaseAlt   = false;

                    if (shift && keyStateService.KeyDownStates[KeyValues.LeftShiftKey].Value == KeyDownStates.Up)
                    {
                        publishService.KeyDown(FunctionKeys.LeftShift.ToVirtualKeyCode().Value);
                        releaseShift = true;
                    }

                    if (ctrl && keyStateService.KeyDownStates[KeyValues.LeftCtrlKey].Value == KeyDownStates.Up)
                    {
                        publishService.KeyDown(FunctionKeys.LeftCtrl.ToVirtualKeyCode().Value);
                        releaseCtrl = true;
                    }

                    if (alt && keyStateService.KeyDownStates[KeyValues.LeftAltKey].Value == KeyDownStates.Up)
                    {
                        publishService.KeyDown(FunctionKeys.LeftAlt.ToVirtualKeyCode().Value);
                        releaseAlt = true;
                    }

                    publishService.KeyDownUp((VirtualKeyCode)vkCode);

                    if (releaseShift)
                    {
                        publishService.KeyUp(FunctionKeys.LeftShift.ToVirtualKeyCode().Value);
                    }
                    if (releaseCtrl)
                    {
                        publishService.KeyUp(FunctionKeys.LeftCtrl.ToVirtualKeyCode().Value);
                    }
                    if (releaseAlt)
                    {
                        publishService.KeyUp(FunctionKeys.LeftAlt.ToVirtualKeyCode().Value);
                    }
                }
                else
                {
                    Log.InfoFormat("No virtual key code found for '{0}' so publishing as text (keyboard:{1})",
                                   character.ToPrintableString(), keyboardCulture);
                    publishService.TypeText(character.ToString());
                }
            }
        }