Add clipboard plugin.

This commit is contained in:
qianlifeng
2014-02-28 23:21:01 +08:00
parent 7d1ee33e1f
commit 7f769e00b9
31 changed files with 455 additions and 65 deletions

View File

@@ -125,6 +125,7 @@ namespace Wox.Plugin.Doc
//frm.ShowDoc(url);
string browser = GetDefaultBrowserPath();
Process.Start(browser, String.Format("\"file:///{0}\"", url));
return true;
}
});
}

View File

@@ -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
{
/// <summary>Specifies the standard ANSI text format. This static field is read-only.
/// </summary>
/// <filterpriority>1</filterpriority>
Text,
/// <summary>Specifies the standard Windows Unicode text format. This static field
/// is read-only.</summary>
/// <filterpriority>1</filterpriority>
UnicodeText,
/// <summary>Specifies the Windows device-independent bitmap (DIB) format. This static
/// field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Dib,
/// <summary>Specifies a Windows bitmap format. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Bitmap,
/// <summary>Specifies the Windows enhanced metafile format. This static field is
/// read-only.</summary>
/// <filterpriority>1</filterpriority>
EnhancedMetafile,
/// <summary>Specifies the Windows metafile format, which Windows Forms does not
/// directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
MetafilePict,
/// <summary>Specifies the Windows symbolic link format, which Windows Forms does
/// not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
SymbolicLink,
/// <summary>Specifies the Windows Data Interchange Format (DIF), which Windows Forms
/// does not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Dif,
/// <summary>Specifies the Tagged Image File Format (TIFF), which Windows Forms does
/// not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Tiff,
/// <summary>Specifies the standard Windows original equipment manufacturer (OEM)
/// text format. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
OemText,
/// <summary>Specifies the Windows palette format. This static field is read-only.
/// </summary>
/// <filterpriority>1</filterpriority>
Palette,
/// <summary>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.</summary>
/// <filterpriority>1</filterpriority>
PenData,
/// <summary>Specifies the Resource Interchange File Format (RIFF) audio format,
/// which Windows Forms does not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Riff,
/// <summary>Specifies the wave audio format, which Windows Forms does not directly
/// use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
WaveAudio,
/// <summary>Specifies the Windows file drop format, which Windows Forms does not
/// directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
FileDrop,
/// <summary>Specifies the Windows culture format, which Windows Forms does not directly
/// use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Locale,
/// <summary>Specifies text consisting of HTML data. This static field is read-only.
/// </summary>
/// <filterpriority>1</filterpriority>
Html,
/// <summary>Specifies text consisting of Rich Text Format (RTF) data. This static
/// field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Rtf,
/// <summary>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.</summary>
/// <filterpriority>1</filterpriority>
CommaSeparatedValue,
/// <summary>Specifies the Windows Forms string class format, which Windows Forms
/// uses to store string objects. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
StringFormat,
/// <summary>Specifies a format that encapsulates any type of Windows Forms object.
/// This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Serializable,
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B

View File

@@ -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<string> dataList = new List<string>();
public List<Result> Query(Query query)
{
return new List<Result>();
var results = new List<Result>();
List<string> displayData = new List<string>();
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());
}
}
}
}
}
}

View File

@@ -7,8 +7,8 @@
<ProjectGuid>{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.DotnetPluginTest</RootNamespace>
<AssemblyName>Wox.Plugin.DotnetPluginTest</AssemblyName>
<RootNamespace>Wox.Plugin.Clipboard</RootNamespace>
<AssemblyName>Wox.Plugin.Clipboard</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
@@ -38,12 +38,17 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsInput">
<HintPath>..\..\packages\InputSimulator.1.0.4.0\lib\net20\WindowsInput.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ClipboardMonitor.cs" />
<Compile Include="Main.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
@@ -59,9 +64,13 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="Images\clipboard.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\</PostBuildEvent>
<PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\
xcopy /Y /E $(ProjectDir)Images $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\Images\</PostBuildEvent>
</PropertyGroup>
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View File

@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="InputSimulator" version="1.0.4.0" targetFramework="net35" />
<package id="Newtonsoft.Json" version="6.0.1" targetFramework="net35" />
</packages>

View File

@@ -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

View File

@@ -36,6 +36,7 @@ namespace Wox.Plugin.Everything
{
context.ShowMsg("Could not start " + r.Title, ex.Message, null);
}
return true;
};
results.Add(r);
}

View File

@@ -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;
}
});
}

View File

@@ -69,7 +69,8 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<PropertyGroup>
<PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\</PostBuildEvent>
<PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\
xcopy /Y /E $(ProjectDir)Images $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\Images\</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.