using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using ManagedWinapi; using Microsoft.Win32; using System.Net.Sockets; using System.IO; namespace ClipHancer { public partial class MainForm : Form { private static readonly string REGISTRY_PATH = @"Software\SMsoft Michael Schierl\ClipHancer\0.1\ServerList"; private static MainForm instance; private int counter = 0; private ApplicationContext ac; bool copying = false; private SharingServer ss = null; private Dictionary<string, string> servers = new Dictionary<string, string>(); public static MainForm Instance { get { return instance; } } public MainForm(ApplicationContext ac) { this.ac = ac; instance = this; InitializeComponent(); SetHotkeysEnabled(true); LoadServerList(); fetchClipboardEntry(); } private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { if (e != null && e.CloseReason == CloseReason.UserClosing) { e.Cancel = true; Hide(); return; } SetHotkeysEnabled(false); ac.ExitThread(); } public void SetHotkeysEnabled(bool enabled) { try { hotkeyX.Enabled = enabled; hotkeyC.Enabled = enabled; hotkeyV.Enabled = enabled; } catch (HotkeyAlreadyInUseException) { hotkeyX.Enabled = false; hotkeyC.Enabled = false; hotkeyV.Enabled = false; MessageBox.Show("One or more hotkeys are already in use by another application. Disabling all hotkeys."); } } private void clipNotify_ClipboardChanged(object sender, EventArgs e) { try { try { if (copying) return; fetchClipboardEntry(false); } catch (Exception ex) { MessageBox.Show("Exception while reading clipboard: " + ex.ToString()); } } catch { } // to prevent abrupt termination of this method } private void fetchClipboardEntry() { fetchClipboardEntry(true); } private void fetchClipboardEntry(bool allowDuplicate) { IDataObject ido = Clipboard.GetDataObject(); ClipboardEntry ce = new ClipboardEntry(ido); byte[] serialized = ce.Serialize(); byte[] reserialized = new ClipboardEntry(ce.Serialize(), "").Serialize(); if (!ArrayEquals(serialized, reserialized)) { MessageBox.Show("Warning: Unserializable clipboard entry detected"); } if (!allowDuplicate && clips.Items.Count > 0 && ArrayEquals(serialized, ((ClipboardEntry)clips.Items[0].Tag).Serialize())) { return; } string key = "image" + (counter++); previewImages.Images.Add(key, ce.PreviewImage); ListViewItem lvi = new ListViewItem(ce.Caption, previewImages.Images.IndexOfKey(key)); lvi.Tag = ce; clips.Items.Insert(0, lvi); } private bool ArrayEquals(byte[] a, byte[] b) { if (a.Length != b.Length) return false; for (int i = 0; i < a.Length; i++) { if (a[i] != b[i]) return false; } return true; } private void hotkeyC_HotkeyPressed(object sender, EventArgs e) { if (clips.Items.Count == 0) return; SetHotkeysEnabled(false); PopupForm pf = new PopupForm('c', "copy", "c = cycle, x = select format, 0-9 = select"); pf.Visible = true; pf.Focus(); } private void hotkeyX_HotkeyPressed(object sender, EventArgs e) { if (clips.Items.Count == 0) return; SetHotkeysEnabled(false); PopupForm pf = new PopupForm('x', "delete", "x = cycle, a = all, 0-9 = select"); pf.Visible = true; pf.Focus(); } private void hotkeyV_HotkeyPressed(object sender, EventArgs e) { if (clips.Items.Count == 0) return; SetHotkeysEnabled(false); PopupForm pf = new PopupForm('v', "paste", "v = cycle, x = select format, 0-9 = select"); pf.Visible = true; pf.Focus(); } private void hide_Click(object sender, EventArgs e) { Visible = false; } private void trayIcon_MouseDoubleClick(object sender, MouseEventArgs e) { Visible = true; } private void openToolStripMenuItem_Click(object sender, EventArgs e) { Visible = true; } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { MainForm_FormClosing(null, null); Dispose(); } private void MainForm_Load(object sender, EventArgs e) { } internal void DoAction(char mychar, ClipboardEntry ce, int index, string format) { if (mychar == 'x') { clips.Items.RemoveAt(index); } else if (mychar == 'X') { clips.Items.Clear(); } else { copying = true; ce.CopyToClipboard(format); copying = false; fetchClipboardEntry(); if (mychar == 'v') { using (new LockKeyResetter()) { SendKeys.Send("^v"); } } } } internal ClipboardEntry[] LastClipboardEntries { get { int count = clips.Items.Count; if (count > 10) count = 10; ClipboardEntry[] result = new ClipboardEntry[count]; for (int i = 0; i < count; i++) { ListViewItem lvi = clips.Items[i]; result[i] = (ClipboardEntry)lvi.Tag; } return result; } } private void copy_Click(object sender, EventArgs e) { copying = true; ClipboardEntry ce = (ClipboardEntry)clips.SelectedItems[0].Tag; ce.CopyToClipboard(); copying = false; fetchClipboardEntry(); } private void clips_SelectedIndexChanged(object sender, EventArgs e) { if (clips.SelectedItems.Count == 0) { copy.Enabled = false; delete.Enabled = false; share.Enabled = false; clips.ContextMenuStrip = null; } else { clips.ContextMenuStrip = copyStrip; copy.Enabled = true; delete.Enabled = true; share.Enabled = true; while (copyStrip.Items.Count > 3) { copyStrip.Items.RemoveAt(3); } ClipboardEntry ce = (ClipboardEntry)clips.SelectedItems[0].Tag; bool firstSep = true; foreach (String s in ce.Formats) { if (s == null) { copyStrip.Items.Add(new ToolStripSeparator()); ToolStripMenuItem i = new ToolStripMenuItem(firstSep ? "Auto-converted formats:" : "Extra conversions:"); i.Font = storedFormatsToolStripMenuItem.Font; i.Enabled = false; copyStrip.Items.Add(i); firstSep = false; } else { ToolStripMenuItem i = new ToolStripMenuItem(s); i.Click += new EventHandler(copyFormat_Click); copyStrip.Items.Add(i); } } } } void copyFormat_Click(object sender, EventArgs e) { copying = true; ClipboardEntry ce = (ClipboardEntry)clips.SelectedItems[0].Tag; ce.CopyToClipboard(((ToolStripMenuItem)sender).Text); copying = false; fetchClipboardEntry(); } private void delete_Click(object sender, EventArgs e) { clips.Items.RemoveAt(clips.SelectedIndices[0]); } private void clearClipboardToolStripMenuItem_Click(object sender, EventArgs e) { Clipboard.Clear(); } private void clearListToolStripMenuItem_Click(object sender, EventArgs e) { clips.Items.Clear(); clips_SelectedIndexChanged(null, null); } private void share_Click(object sender, EventArgs e) { if (clips.SelectedItems.Count == 0) return; if (ss == null) ss = new SharingServer(); ss.Share((ClipboardEntry)clips.SelectedItems[0].Tag); } private void stopSharingToolStripMenuItem_Click(object sender, EventArgs e) { if (ss != null) { ss.StopSharing(); ss = null; } } private void LoadServerList() { RegistryKey key = Registry.CurrentUser.OpenSubKey(REGISTRY_PATH, false); if (key != null) { foreach (string server in key.GetValueNames()) { servers.Add(server, (string)key.GetValue(server)); } key.Close(); } } private void SaveServerList() { RegistryKey key = Registry.CurrentUser.CreateSubKey(REGISTRY_PATH, RegistryKeyPermissionCheck.ReadWriteSubTree); if (key != null) { foreach (String valueName in key.GetValueNames()) { key.DeleteValue(valueName); } foreach (KeyValuePair<string, string> p in servers) { key.SetValue(p.Key, p.Value); } } key.Close(); } private void receive_Click(object sender, EventArgs e) { while (onReceiveStrip.Items.Count > 2) { onReceiveStrip.Items.RemoveAt(0); } byte[] buff = new byte[4096]; int len; foreach (KeyValuePair<string, string> p in servers) { TcpClient c; try { c = new TcpClient(p.Value, 5120); } catch (SocketException) { continue; } Stream s = c.GetStream(); MemoryStream ms = new MemoryStream(); while ((len = s.Read(buff, 0, buff.Length)) != 0) { ms.Write(buff, 0, len); } c.Close(); ClipboardEntry pe = new ClipboardEntry(ms.ToArray(), "[" + p.Key + "] "); ToolStripMenuItem mi = new ToolStripMenuItem(pe.Caption, pe.PreviewImage); mi.Click += new EventHandler(receivedItem_Click); mi.Tag = pe; onReceiveStrip.Items.Insert(0, mi); } onReceiveStrip.Show(receive, new Point(receive.Width, receive.Height), ToolStripDropDownDirection.AboveLeft); } void receivedItem_Click(object sender, EventArgs e) { ClipboardEntry ce = (ClipboardEntry)((ToolStripMenuItem)sender).Tag; copying = true; ce.CopyToClipboard(); copying = false; fetchClipboardEntry(); } private void copyServerListToClipboardToolStripMenuItem_Click(object sender, EventArgs e) { StringBuilder sb = new StringBuilder(); sb.Append("# Servers for ClipHancer\r\n# Use lines servername=ip\r\n# Example: test=192.168.0.1\r\n"); foreach (KeyValuePair<string, string> p in servers) { sb.Append(p.Key + "=" + p.Value + "\r\n"); } Clipboard.SetText(sb.ToString()); } private void pasteServerListFromClipboardToolStripMenuItem_Click(object sender, EventArgs e) { string cb; try { cb = Clipboard.GetText(); } catch (Exception ex) { MessageBox.Show("Could not read clipboard: " + ex.ToString()); cb = ""; } servers.Clear(); foreach (string line_ in cb.Split('\r', '\n')) { string line = line_.Trim(); if (line.StartsWith("#") || !line.Contains("=")) continue; int pos = line.IndexOf('='); servers.Add(line.Substring(0, pos), line.Substring(pos + 1)); } } private void clips_SizeChanged(object sender, EventArgs e) { clips.Columns[0].Width = clips.Width - 22; } } }