From 7f769e00b9f925043bde68350f69f02f08481ca3 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Fri, 28 Feb 2014 23:21:01 +0800 Subject: [PATCH] Add clipboard plugin. --- Plugins/Wox.Plugin.Doc/Main.cs | 1 + .../ClipboardMonitor.cs | 234 ++++++++++++++++++ .../Images/clipboard.png | Bin 0 -> 924 bytes Plugins/Wox.Plugin.DotnetPluginTest/Main.cs | 76 +++++- ...est.csproj => Wox.Plugin.Clipboard.csproj} | 15 +- .../packages.config | 1 + .../Wox.Plugin.DotnetPluginTest/plugin.ini | 8 +- Plugins/Wox.Plugin.Everything/Main.cs | 1 + Plugins/Wox.Plugin.Fanyi/Main.cs | 1 + .../Wox.Plugin.Fanyi/Wox.Plugin.Fanyi.csproj | 3 +- Wox.Plugin.System/BrowserBookmarks.cs | 1 + Wox.Plugin.System/CMD.cs | 3 + Wox.Plugin.System/DirectoryIndicator.cs | 1 + Wox.Plugin.System/Programs.cs | 1 + Wox.Plugin.System/Setting.cs | 6 +- Wox.Plugin.System/Sys.cs | 18 +- .../ThirdpartyPluginIndicator.cs | 14 +- Wox.Plugin.System/WebSearchPlugin.cs | 6 +- Wox.Plugin/PluginInitContext.cs | 2 + Wox.Plugin/Query.cs | 12 + Wox.Plugin/Result.cs | 8 +- Wox.Test/QueryTest.cs | 4 +- Wox.sln | 2 +- Wox/CustomPluginHotkeySetting.xaml.cs | 2 +- Wox/ImagePathConverter.cs | 5 +- Wox/MainWindow.xaml | 2 +- Wox/MainWindow.xaml.cs | 58 ++--- Wox/PluginLoader/Plugins.cs | 3 +- Wox/PluginLoader/PythonPluginWrapper.cs | 6 +- Wox/ResultPanel.xaml | 2 +- Wox/ResultPanel.xaml.cs | 24 ++ 31 files changed, 455 insertions(+), 65 deletions(-) create mode 100644 Plugins/Wox.Plugin.DotnetPluginTest/ClipboardMonitor.cs create mode 100644 Plugins/Wox.Plugin.DotnetPluginTest/Images/clipboard.png rename Plugins/Wox.Plugin.DotnetPluginTest/{Wox.Plugin.DotnetPluginTest.csproj => Wox.Plugin.Clipboard.csproj} (85%) diff --git a/Plugins/Wox.Plugin.Doc/Main.cs b/Plugins/Wox.Plugin.Doc/Main.cs index e482d5c76..b506acf7c 100644 --- a/Plugins/Wox.Plugin.Doc/Main.cs +++ b/Plugins/Wox.Plugin.Doc/Main.cs @@ -125,6 +125,7 @@ namespace Wox.Plugin.Doc //frm.ShowDoc(url); string browser = GetDefaultBrowserPath(); Process.Start(browser, String.Format("\"file:///{0}\"", url)); + return true; } }); } diff --git a/Plugins/Wox.Plugin.DotnetPluginTest/ClipboardMonitor.cs b/Plugins/Wox.Plugin.DotnetPluginTest/ClipboardMonitor.cs new file mode 100644 index 000000000..b56158653 --- /dev/null +++ b/Plugins/Wox.Plugin.DotnetPluginTest/ClipboardMonitor.cs @@ -0,0 +1,234 @@ +using System; +using System.Runtime.InteropServices; +using System.Threading; +using System.Windows.Forms; + +namespace Wox.Plugin.Clipboard +{ + public static class ClipboardMonitor + { + public delegate void OnClipboardChangeEventHandler(ClipboardFormat format, object data); + public static event OnClipboardChangeEventHandler OnClipboardChange; + + public static void Start() + { + ClipboardWatcher.Start(); + ClipboardWatcher.OnClipboardChange += (ClipboardFormat format, object data) => + { + if (OnClipboardChange != null) + OnClipboardChange(format, data); + }; + } + + public static void Stop() + { + OnClipboardChange = null; + ClipboardWatcher.Stop(); + } + + class ClipboardWatcher : Form + { + // static instance of this form + private static ClipboardWatcher mInstance; + + // needed to dispose this form + static IntPtr nextClipboardViewer; + + public delegate void OnClipboardChangeEventHandler(ClipboardFormat format, object data); + public static event OnClipboardChangeEventHandler OnClipboardChange; + + // start listening + public static void Start() + { + // we can only have one instance if this class + if (mInstance != null) + return; + + Thread t = new Thread(new ParameterizedThreadStart(x => + { + Application.Run(new ClipboardWatcher()); + })); + t.SetApartmentState(ApartmentState.STA); // give the [STAThread] attribute + t.Start(); + } + + // stop listening (dispose form) + public static void Stop() + { + mInstance.Invoke(new MethodInvoker(() => + { + ChangeClipboardChain(mInstance.Handle, nextClipboardViewer); + })); + mInstance.Invoke(new MethodInvoker(mInstance.Close)); + + mInstance.Dispose(); + + mInstance = null; + } + + // on load: (hide this window) + protected override void SetVisibleCore(bool value) + { + CreateHandle(); + + mInstance = this; + + nextClipboardViewer = SetClipboardViewer(mInstance.Handle); + + base.SetVisibleCore(false); + } + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam); + + // defined in winuser.h + const int WM_DRAWCLIPBOARD = 0x308; + const int WM_CHANGECBCHAIN = 0x030D; + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case WM_DRAWCLIPBOARD: + ClipChanged(); + SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam); + break; + + case WM_CHANGECBCHAIN: + if (m.WParam == nextClipboardViewer) + nextClipboardViewer = m.LParam; + else + SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam); + break; + + default: + base.WndProc(ref m); + break; + } + } + + static readonly string[] formats = Enum.GetNames(typeof(ClipboardFormat)); + + private void ClipChanged() + { + IDataObject iData = System.Windows.Forms.Clipboard.GetDataObject(); + + ClipboardFormat? format = null; + + foreach (var f in formats) + { + if (iData.GetDataPresent(f)) + { + format = (ClipboardFormat)Enum.Parse(typeof(ClipboardFormat), f); + break; + } + } + + object data = iData.GetData(format.ToString()); + + if (data == null || format == null) + return; + + if (OnClipboardChange != null) + OnClipboardChange((ClipboardFormat)format, data); + } + + + } + } + + public enum ClipboardFormat : byte + { + /// Specifies the standard ANSI text format. This static field is read-only. + /// + /// 1 + Text, + /// Specifies the standard Windows Unicode text format. This static field + /// is read-only. + /// 1 + UnicodeText, + /// Specifies the Windows device-independent bitmap (DIB) format. This static + /// field is read-only. + /// 1 + Dib, + /// Specifies a Windows bitmap format. This static field is read-only. + /// 1 + Bitmap, + /// Specifies the Windows enhanced metafile format. This static field is + /// read-only. + /// 1 + EnhancedMetafile, + /// Specifies the Windows metafile format, which Windows Forms does not + /// directly use. This static field is read-only. + /// 1 + MetafilePict, + /// Specifies the Windows symbolic link format, which Windows Forms does + /// not directly use. This static field is read-only. + /// 1 + SymbolicLink, + /// Specifies the Windows Data Interchange Format (DIF), which Windows Forms + /// does not directly use. This static field is read-only. + /// 1 + Dif, + /// Specifies the Tagged Image File Format (TIFF), which Windows Forms does + /// not directly use. This static field is read-only. + /// 1 + Tiff, + /// Specifies the standard Windows original equipment manufacturer (OEM) + /// text format. This static field is read-only. + /// 1 + OemText, + /// Specifies the Windows palette format. This static field is read-only. + /// + /// 1 + Palette, + /// Specifies the Windows pen data format, which consists of pen strokes + /// for handwriting software, Windows Forms does not use this format. This static + /// field is read-only. + /// 1 + PenData, + /// Specifies the Resource Interchange File Format (RIFF) audio format, + /// which Windows Forms does not directly use. This static field is read-only. + /// 1 + Riff, + /// Specifies the wave audio format, which Windows Forms does not directly + /// use. This static field is read-only. + /// 1 + WaveAudio, + /// Specifies the Windows file drop format, which Windows Forms does not + /// directly use. This static field is read-only. + /// 1 + FileDrop, + /// Specifies the Windows culture format, which Windows Forms does not directly + /// use. This static field is read-only. + /// 1 + Locale, + /// Specifies text consisting of HTML data. This static field is read-only. + /// + /// 1 + Html, + /// Specifies text consisting of Rich Text Format (RTF) data. This static + /// field is read-only. + /// 1 + Rtf, + /// Specifies a comma-separated value (CSV) format, which is a common interchange + /// format used by spreadsheets. This format is not used directly by Windows Forms. + /// This static field is read-only. + /// 1 + CommaSeparatedValue, + /// Specifies the Windows Forms string class format, which Windows Forms + /// uses to store string objects. This static field is read-only. + /// 1 + StringFormat, + /// Specifies a format that encapsulates any type of Windows Forms object. + /// This static field is read-only. + /// 1 + Serializable, + } +} \ No newline at end of file diff --git a/Plugins/Wox.Plugin.DotnetPluginTest/Images/clipboard.png b/Plugins/Wox.Plugin.DotnetPluginTest/Images/clipboard.png new file mode 100644 index 0000000000000000000000000000000000000000..78afddcd9e69063ab31b5152271a2adfbdf290fb GIT binary patch literal 924 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7l!{JxM1({$v_d#0*}aI zAngIhZYQ(tK!Rljj_E*J0gT&!&6&%_|_+j6@yGl?T-(^Mm; zOYjID6yf@*vBk(`%T_^_zpURhb98l>UrsG?6L1tT+2N~oTEV4RP3+=^T_=ytoNy+u z?AhLI!`%m8NE=VyQ}NLEV_W(CnZ@V#rZ*@bIdsS=t*q>tjaQ$ud|YJYOr=HQKWqNg z#mC>DUbOSi$Nh{ms{g*q@z4MG^2?VmpL5J^%gD&=`Iwpc@#FTbT^_Sf2j$+Iy`$h| z&C4sLhkxWwW@HnPlD+YDd%NywCR4N6`>U;(lam);U&m*^r_ykD-b4n*4!O09d34tA zd_QkbUJjCC8c1?!9{P!tLE14W7dd|10?z zIz)R`Gd3vBJb32Cn>R-;To7mpc)dD6W5NFY_4c(c1v2a|ENN`sY{g3!AK~$Mws-xh zr$rWC9%1)t85krx{oM^#(EKRXP6! z7TWP{x#6>%aW9XHwjsmHNM?-SkLIzWj5vbg2ofkmkbtEiX1mgSYdWMZHe}!Zh>ECHLhw*J5#l{;r3Vm z7j3uR&Uk#=z>WFiv%(n(eJ(R@^eM0UVkq$4S&F+sa)U4P)0Ng$8Ul<_LLSdpqw6;8 z`W2kRU|kaMZb@Kix%R>zyEmNT?)oX5mb>~M>jW`|wL$O9oL~O^`A)n>>DhwS7ZWZ4 zQ?_b}YeY#(Vo9o1a#1RfVlXl=G|)9L(ls;;F)*|;GPW``(KRr$GB98Z_LD`?kei>9 rnN|tZU|gTe~DWM4f)oyya literal 0 HcmV?d00001 diff --git a/Plugins/Wox.Plugin.DotnetPluginTest/Main.cs b/Plugins/Wox.Plugin.DotnetPluginTest/Main.cs index f5c2372cc..3d95b3dd0 100644 --- a/Plugins/Wox.Plugin.DotnetPluginTest/Main.cs +++ b/Plugins/Wox.Plugin.DotnetPluginTest/Main.cs @@ -1,21 +1,85 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using WindowsInput; +using WindowsInput.Native; using Newtonsoft.Json; -namespace Wox.Plugin.DotnetPluginTest +namespace Wox.Plugin.Clipboard { public class Main : IPlugin { + private const int MaxDataCount = 100; + private readonly KeyboardSimulator keyboardSimulator = new KeyboardSimulator(new InputSimulator()); + private PluginInitContext context; + List dataList = new List(); + public List Query(Query query) { - return new List(); + var results = new List(); + List displayData = new List(); + if (query.ActionParameters.Count == 0) + { + displayData = dataList; + } + else + { + displayData = dataList.Where(i => i.ToLower().Contains(query.GetAllRemainingParameter().ToLower())) + .ToList(); + } + + results.AddRange(displayData.Select(o => new Result + { + Title = o, + IcoPath = "Images\\clipboard.png", + Action = c => + { + if (c.SpecialKeyState.CtrlPressed) + { + context.ShowCurrentResultItemTooltip(o); + return false; + } + else + { + System.Windows.Forms.Clipboard.SetText(o); + context.HideApp(); + keyboardSimulator.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_V); + return true; + } + } + }).Reverse()); + return results; } public void Init(PluginInitContext context) { - var s = JsonSerializer.Create(); + this.context = context; + ClipboardMonitor.OnClipboardChange += ClipboardMonitor_OnClipboardChange; + ClipboardMonitor.Start(); + } + + void ClipboardMonitor_OnClipboardChange(ClipboardFormat format, object data) + { + if (format == ClipboardFormat.Html || + format == ClipboardFormat.SymbolicLink || + format == ClipboardFormat.Text || + format == ClipboardFormat.UnicodeText) + { + if (data != null && !string.IsNullOrEmpty(data.ToString())) + { + if (dataList.Contains(data.ToString())) + { + dataList.Remove(data.ToString()); + } + dataList.Add(data.ToString()); + + if (dataList.Count > MaxDataCount) + { + dataList.Remove(dataList.First()); + } + } + } } } } diff --git a/Plugins/Wox.Plugin.DotnetPluginTest/Wox.Plugin.DotnetPluginTest.csproj b/Plugins/Wox.Plugin.DotnetPluginTest/Wox.Plugin.Clipboard.csproj similarity index 85% rename from Plugins/Wox.Plugin.DotnetPluginTest/Wox.Plugin.DotnetPluginTest.csproj rename to Plugins/Wox.Plugin.DotnetPluginTest/Wox.Plugin.Clipboard.csproj index ac5fe9ef6..b0acbe14f 100644 --- a/Plugins/Wox.Plugin.DotnetPluginTest/Wox.Plugin.DotnetPluginTest.csproj +++ b/Plugins/Wox.Plugin.DotnetPluginTest/Wox.Plugin.Clipboard.csproj @@ -7,8 +7,8 @@ {8C14DC11-2737-4DCB-A121-5D7BDD57FEA2} Library Properties - Wox.Plugin.DotnetPluginTest - Wox.Plugin.DotnetPluginTest + Wox.Plugin.Clipboard + Wox.Plugin.Clipboard v3.5 512 ..\..\ @@ -38,12 +38,17 @@ + + + ..\..\packages\InputSimulator.1.0.4.0\lib\net20\WindowsInput.dll + + @@ -59,9 +64,13 @@ Always + + + - xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\ + xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\ +xcopy /Y /E $(ProjectDir)Images $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\Images\ diff --git a/Plugins/Wox.Plugin.DotnetPluginTest/packages.config b/Plugins/Wox.Plugin.DotnetPluginTest/packages.config index 3a7903bb6..1a63fba3c 100644 --- a/Plugins/Wox.Plugin.DotnetPluginTest/packages.config +++ b/Plugins/Wox.Plugin.DotnetPluginTest/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.DotnetPluginTest/plugin.ini b/Plugins/Wox.Plugin.DotnetPluginTest/plugin.ini index a598232fe..7a6cb0864 100644 --- a/Plugins/Wox.Plugin.DotnetPluginTest/plugin.ini +++ b/Plugins/Wox.Plugin.DotnetPluginTest/plugin.ini @@ -1,8 +1,8 @@ [plugin] -ActionKeyword = ts -Name = dotnet test +ActionKeyword = cb +Name = clipboard monitor Author = qianlifeng Version = 0.1 Language = csharp -Description = test -ExecuteFile = Wox.Plugin.DotnetPluginTest.dll +Description = clipboard monitor +ExecuteFile = Wox.Plugin.Clipboard.dll diff --git a/Plugins/Wox.Plugin.Everything/Main.cs b/Plugins/Wox.Plugin.Everything/Main.cs index afbb03988..1783aed19 100644 --- a/Plugins/Wox.Plugin.Everything/Main.cs +++ b/Plugins/Wox.Plugin.Everything/Main.cs @@ -36,6 +36,7 @@ namespace Wox.Plugin.Everything { context.ShowMsg("Could not start " + r.Title, ex.Message, null); } + return true; }; results.Add(r); } diff --git a/Plugins/Wox.Plugin.Fanyi/Main.cs b/Plugins/Wox.Plugin.Fanyi/Main.cs index 6b378d14f..fdd8ad12f 100644 --- a/Plugins/Wox.Plugin.Fanyi/Main.cs +++ b/Plugins/Wox.Plugin.Fanyi/Main.cs @@ -81,6 +81,7 @@ namespace Wox.Plugin.Fanyi Clipboard.SetText(dst); context.ShowMsg("translation has been copyed to your clipboard.", "", AssemblyDirectory + "\\Images\\translate.png"); + return true; } }); } diff --git a/Plugins/Wox.Plugin.Fanyi/Wox.Plugin.Fanyi.csproj b/Plugins/Wox.Plugin.Fanyi/Wox.Plugin.Fanyi.csproj index 522fa3269..0960b62fe 100644 --- a/Plugins/Wox.Plugin.Fanyi/Wox.Plugin.Fanyi.csproj +++ b/Plugins/Wox.Plugin.Fanyi/Wox.Plugin.Fanyi.csproj @@ -69,7 +69,8 @@ - xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\ + xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\ +xcopy /Y /E $(ProjectDir)Images $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\Images\