From 911d06154ca3e4fbfc114be4e7d0c9909959aa25 Mon Sep 17 00:00:00 2001 From: Jed Laundry Date: Sat, 14 Jun 2025 09:07:47 +1200 Subject: [PATCH] restore SendKeys as an option --- TypeClipboard/Form1.Designer.cs | 69 +++++++--- TypeClipboard/Form1.cs | 25 +++- TypeClipboard/Form1.resx | 123 ++++++++++++++++++ TypeClipboard/Properties/Settings.Designer.cs | 35 ++++- TypeClipboard/TypeClipboard.csproj | 5 + TypeClipboard/Typer.cs | 76 ++++++++++- 6 files changed, 303 insertions(+), 30 deletions(-) create mode 100644 TypeClipboard/Form1.resx diff --git a/TypeClipboard/Form1.Designer.cs b/TypeClipboard/Form1.Designer.cs index 72dcf20..93b5ccf 100644 --- a/TypeClipboard/Form1.Designer.cs +++ b/TypeClipboard/Form1.Designer.cs @@ -1,4 +1,7 @@ -namespace TypeClipboard +using System.Drawing; +using System.Windows.Forms; + +namespace TypeClipboard { partial class Form1 { @@ -23,14 +26,12 @@ #region Windows Form Designer generated code /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.textBox1 = new System.Windows.Forms.TextBox(); this.button1 = new System.Windows.Forms.Button(); this.chkHotkey = new System.Windows.Forms.CheckBox(); @@ -39,6 +40,8 @@ this.button3 = new System.Windows.Forms.Button(); this.chkEnter = new System.Windows.Forms.CheckBox(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); this.SuspendLayout(); // // textBox1 @@ -63,7 +66,7 @@ // chkHotkey // this.chkHotkey.AutoSize = true; - this.chkHotkey.Location = new System.Drawing.Point(172, 42); + this.chkHotkey.Location = new System.Drawing.Point(102, 98); this.chkHotkey.Name = "chkHotkey"; this.chkHotkey.Size = new System.Drawing.Size(73, 17); this.chkHotkey.TabIndex = 2; @@ -104,7 +107,7 @@ // chkEnter // this.chkEnter.AutoSize = true; - this.chkEnter.Location = new System.Drawing.Point(244, 42); + this.chkEnter.Location = new System.Drawing.Point(177, 98); this.chkEnter.Name = "chkEnter"; this.chkEnter.Size = new System.Drawing.Size(78, 17); this.chkEnter.TabIndex = 7; @@ -119,10 +122,39 @@ // this.toolTip1.ShowAlways = true; // + // comboBox1 + // + this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBox1.FormattingEnabled = true; + this.comboBox1.Items.AddRange(new object[] { + "SendInput", + "SendKeys"}); + this.comboBox1.Location = new System.Drawing.Point(12, 95); + this.comboBox1.Margin = new System.Windows.Forms.Padding(5); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(82, 21); + this.comboBox1.TabIndex = 9; + this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); + // + // linkLabel1 + // + this.linkLabel1.AutoSize = true; + this.linkLabel1.Location = new System.Drawing.Point(293, 98); + this.linkLabel1.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(29, 13); + this.linkLabel1.TabIndex = 10; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "Help"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // // Form1 // - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; - this.ClientSize = new System.Drawing.Size(334, 99); + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(332, 124); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.comboBox1); this.Controls.Add(this.chkEnter); this.Controls.Add(this.button3); this.Controls.Add(this.textBox2); @@ -148,14 +180,15 @@ #endregion - private System.Windows.Forms.TextBox textBox1; - private System.Windows.Forms.Button button1; - private System.Windows.Forms.CheckBox chkHotkey; - private System.Windows.Forms.Button button2; - private System.Windows.Forms.TextBox textBox2; - private System.Windows.Forms.Button button3; - private System.Windows.Forms.CheckBox chkEnter; - private System.Windows.Forms.ToolTip toolTip1; + private TextBox textBox1; + private Button button1; + private CheckBox chkHotkey; + private Button button2; + private TextBox textBox2; + private Button button3; + private CheckBox chkEnter; + private ToolTip toolTip1; + private ComboBox comboBox1; + private LinkLabel linkLabel1; } } - diff --git a/TypeClipboard/Form1.cs b/TypeClipboard/Form1.cs index d26ee38..c20dd45 100644 --- a/TypeClipboard/Form1.cs +++ b/TypeClipboard/Form1.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Text; using System.Threading; using System.Windows.Forms; @@ -97,7 +98,10 @@ namespace TypeClipboard // Changing the chkEnter.Checked property also changes _tc.TypeEnter property chkEnter.Checked = Properties.Settings.Default.enableEnter; - ClipboardNotification.ClipboardUpdate += delegate (object cb_sender, EventArgs cb_e) { + comboBox1.SelectedItem = Properties.Settings.Default.typeMethod; + + ClipboardNotification.ClipboardUpdate += delegate (object cb_sender, EventArgs cb_e) + { UpdateTextbox(); }; UpdateTextbox(); @@ -141,5 +145,24 @@ namespace TypeClipboard _tc.TypeEnter = chkEnter.Checked; Properties.Settings.Default.Save(); } + + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + try + { + Process.Start(new ProcessStartInfo { FileName = @"https://github.com/jlaundry/TypeClipboard/wiki/Help", UseShellExecute = true }); + } + catch (Exception ex) + { + MessageBox.Show("Unable to open default browser. Go to https://github.com/jlaundry/TypeClipboard/wiki/Help"); + } + } + + private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) + { + Properties.Settings.Default.typeMethod = (string)comboBox1.SelectedItem; + _tc.TypeMethod = (string)comboBox1.SelectedItem; + Properties.Settings.Default.Save(); + } } } diff --git a/TypeClipboard/Form1.resx b/TypeClipboard/Form1.resx new file mode 100644 index 0000000..df8339b --- /dev/null +++ b/TypeClipboard/Form1.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/TypeClipboard/Properties/Settings.Designer.cs b/TypeClipboard/Properties/Settings.Designer.cs index 720e543..3e699ab 100644 --- a/TypeClipboard/Properties/Settings.Designer.cs +++ b/TypeClipboard/Properties/Settings.Designer.cs @@ -26,25 +26,46 @@ namespace TypeClipboard.Properties { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool enableHotkey { - get { + public bool enableHotkey + { + get + { return ((bool)(this["enableHotkey"])); } - set { + set + { this["enableHotkey"] = value; } } - + [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool enableEnter { - get { + public bool enableEnter + { + get + { return ((bool)(this["enableEnter"])); } - set { + set + { this["enableEnter"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("SendInput")] + public string typeMethod + { + get + { + return ((string)(this["typeMethod"])); + } + set + { + this["typeMethod"] = value; + } + } } } diff --git a/TypeClipboard/TypeClipboard.csproj b/TypeClipboard/TypeClipboard.csproj index aab0711..001d976 100644 --- a/TypeClipboard/TypeClipboard.csproj +++ b/TypeClipboard/TypeClipboard.csproj @@ -27,6 +27,8 @@ 1.6.0.0 false true + PerMonitorV2 + true @@ -77,6 +79,9 @@ + + Form1.cs + ResXFileCodeGenerator Resources.Designer.cs diff --git a/TypeClipboard/Typer.cs b/TypeClipboard/Typer.cs index 638f22e..9b4c764 100644 --- a/TypeClipboard/Typer.cs +++ b/TypeClipboard/Typer.cs @@ -17,8 +17,11 @@ namespace TypeClipboard private const int INTERKEY_DELAY = 50; private bool _typeEnter = false; + private string _typeMethod = "SendInput"; public bool TypeEnter { get => _typeEnter; set => _typeEnter = value; } + public string TypeMethod { get => _typeMethod; set => _typeMethod = value; } + public void Type(String str, int delay = 2000) { Thread.Sleep(delay); @@ -26,20 +29,85 @@ namespace TypeClipboard //KeyboardTyper.Reset(); KeyboardTyper.Type(str, _typeEnter, INTERKEY_DELAY); - //KeyboardTyper.Press(Key.LeftShift); - //KeyboardTyper.Type("hello, capitalized world"); - //KeyboardTyper.Release(Key.LeftShift); NativeMethods.BlockInput(false); } + public void TypeWithSendKeys(String str, int delay) + { + Thread.Sleep(delay); + foreach (Char c in str.ToCharArray()) + { + // Some characters have special meaning + // https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/sendkeys-statement + switch (c) + { + case '\n': + if (_typeEnter) + { + SendKeys.Send("{ENTER}"); + break; + } + else + { + return; + } + case '\r': + if (_typeEnter) + { + break; + } + else + { + return; + } + case '{': + SendKeys.Send("{{}"); + break; + case '}': + SendKeys.Send("{}}"); + break; + case '+': + SendKeys.Send("{+}"); + break; + case '^': + SendKeys.Send("{^}"); + break; + case '%': + SendKeys.Send("{%}"); + break; + case '~': + SendKeys.Send("{~}"); + break; + case '(': + SendKeys.Send("{(}"); + break; + case ')': + SendKeys.Send("{)}"); + break; + default: + SendKeys.Send(c.ToString()); + break; + } + Thread.Sleep(INTERKEY_DELAY); + } + } + public void TypeClipboard(int delay = 2000) { if (Clipboard.ContainsText(TextDataFormat.UnicodeText)) { String clipboard = Clipboard.GetText(TextDataFormat.UnicodeText); - this.Type(clipboard, delay); + if (_typeMethod == "SendKeys") + { + TypeWithSendKeys(clipboard, delay); + } + else + { + // SendInput is default + Type(clipboard, delay); + } } } }