/// <summary> /// Sends simulated key strokes. These are interpreted as real keystrokes by other programs. /// </summary> /// <param name="text"></param> private void SendVirtualKeys(string text) { var lines = text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); var i = 0; var count = lines.Length; foreach (var line in lines) { switch (ContentType) { case ContentTypes.List when _singleSelection: if (!string.IsNullOrEmpty(line)) { _inputSimulator.Keyboard.TextEntry(line); } if (i + 1 != count) //not last line { _inputSimulator.Keyboard.KeyPress(VirtualKeyCode.RETURN); } else //last line { OnPastingOccured?.Invoke(this, new PastingOccuredEventArgs()); } break; case ContentTypes.List when !_singleSelection: if (!string.IsNullOrEmpty(line)) { _inputSimulator.Keyboard.TextEntry(line); } _inputSimulator.Keyboard.KeyPress(VirtualKeyCode.RETURN); if (TextList != null) { if (i + 1 == count && TextList.Count != 0) //last line and not last selection { OnPastingOccured?.Invoke(this, new PastingOccuredEventArgs()); } else if (i + 1 == count && TextList.Count == 0) //last line and last selection { OnPastingOccured?.Invoke(this, new PastingOccuredEventArgs()); } } break; } i += 1; } }
private void GlobalHook_KeyDown(object sender, KeyEventArgs e) { switch (ContentType) { case ContentTypes.NotList : //Ignore repeated pasting when only the LAST text item is left in the text list. This happens when ctrl+v is continuously pressed. if (e.KeyCode == Keys.V && TextList.Count == 0) { e.SuppressKeyPress = true; } break; case ContentTypes.List: switch (SendingKeys) { case true: switch (e.KeyCode) { case Keys.Packet: case Keys.V: case Keys.LControlKey: case Keys.Enter: break; default: e.SuppressKeyPress = true; break; } break; case false: switch (e.KeyCode) { case Keys.V when e.KeyCode == Keys.V && e.Control && _vUp: _vUp = false; _ctrlUp = false; e.SuppressKeyPress = true; if (IsActiveWindowInThisList(new List <string> { "Clipboard Helper" })) //This program. { ReceivingProgram = ReceivingPrograms.ThisProgram; } else if (IsActiveWindowInThisList(ConsoleList) ) //Specific programs with alternative pasting mode: MobaXterm; mRemoteNG; PuTTY; Windows PowerShell; Kommandotolken. { ReceivingProgram = ReceivingPrograms.Console; CtrlVDetected = true; } else //All other programs. { ReceivingProgram = ReceivingPrograms.Standard; _cl = GetTextForVirtualKeys(); _cl = _cl.Replace("\n", "\r\n"); //So Notepad can handle line break. CtrlVDetected = true; LastPastedItem = _cl; //When we receive new clipboard value, we know we sent it. SetTextClipboard.Start(_cl); SendingKeys = true; _inputSimulator.Keyboard.KeyUp(VirtualKeyCode.LCONTROL); _inputSimulator.Keyboard.ModifiedKeyStroke(VirtualKeyCode.LCONTROL, VirtualKeyCode.VK_V); //prevents empty clipboard outputted when multi pasting. //This can happen if the user pastes, repeatedly, very fast. Thread.Sleep(3); if (TextList.Count != 0) { _inputSimulator.Keyboard.KeyPress(VirtualKeyCode.RETURN); } SendingKeys = false; _inputSimulator.Keyboard.KeyDown(VirtualKeyCode.LCONTROL); OnPastingOccured?.Invoke(this, new PastingOccuredEventArgs()); InitiateOrUpdateValuesDependingOnNrOfItemsInList(TextList.Count); } break; case Keys.V: if (ContentType == ContentTypes.List && !_ctrlUp) { //Ignore repeated pasting when NOT the last text item is left in the text list. //This happens when ctrl+v is continuously pushed down. e.SuppressKeyPress = true; } _vUp = false; break; case Keys.LControlKey: _ctrlUp = false; break; default: CtrlVDetected = false; break; } break; } break; default: throw new ArgumentOutOfRangeException(nameof(sender), Resources.Pasting_GlobalHook_KeyDown_An_error_occured_while_pasting); } }