diff --git a/GreenshotWin10Plugin/GreenshotWin10Plugin.csproj b/GreenshotWin10Plugin/GreenshotWin10Plugin.csproj
index 9aa9b6a71..3830b6f20 100644
--- a/GreenshotWin10Plugin/GreenshotWin10Plugin.csproj
+++ b/GreenshotWin10Plugin/GreenshotWin10Plugin.csproj
@@ -12,6 +12,7 @@
GreenshotWin10Plugin
v4.5
512
+
true
@@ -35,6 +36,8 @@
+
+
@@ -43,16 +46,19 @@
+
+
+
+
-
+
False
..\Greenshot\lib\log4net.dll
-
diff --git a/GreenshotWin10Plugin/MemoryRandomAccessStream.cs b/GreenshotWin10Plugin/MemoryRandomAccessStream.cs
new file mode 100644
index 000000000..4b3476a04
--- /dev/null
+++ b/GreenshotWin10Plugin/MemoryRandomAccessStream.cs
@@ -0,0 +1,69 @@
+using System.IO;
+using Windows.Storage.Streams;
+
+namespace GreenshotWin10Plugin
+{
+ public sealed class MemoryRandomAccessStream : MemoryStream, IRandomAccessStream
+ {
+ public MemoryRandomAccessStream()
+ {
+ }
+
+ public MemoryRandomAccessStream(byte[] bytes)
+ {
+ Write(bytes, 0, bytes.Length);
+ }
+
+ public IInputStream GetInputStreamAt(ulong position)
+ {
+ Seek((long)position, SeekOrigin.Begin);
+
+ return this.AsInputStream();
+ }
+
+ public IOutputStream GetOutputStreamAt(ulong position)
+ {
+ Seek((long)position, SeekOrigin.Begin);
+
+ return this.AsOutputStream();
+ }
+
+ ulong IRandomAccessStream.Position => (ulong)Position;
+
+ public ulong Size
+ {
+ get { return (ulong)Length; }
+ set { SetLength((long)value); }
+ }
+
+ public IRandomAccessStream CloneStream()
+ {
+ var cloned = new MemoryRandomAccessStream();
+ CopyTo(cloned);
+ return cloned;
+ }
+
+ public void Seek(ulong position)
+ {
+ Seek((long)position, SeekOrigin.Begin);
+ }
+
+ public Windows.Foundation.IAsyncOperationWithProgress ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
+ {
+ var inputStream = GetInputStreamAt(0);
+ return inputStream.ReadAsync(buffer, count, options);
+ }
+
+ Windows.Foundation.IAsyncOperation IOutputStream.FlushAsync()
+ {
+ var outputStream = GetOutputStreamAt(0);
+ return outputStream.FlushAsync();
+ }
+
+ public Windows.Foundation.IAsyncOperationWithProgress WriteAsync(IBuffer buffer)
+ {
+ var outputStream = GetOutputStreamAt(0);
+ return outputStream.WriteAsync(buffer);
+ }
+ }
+}
diff --git a/GreenshotWin10Plugin/Native/DataTransferManagerHelper.cs b/GreenshotWin10Plugin/Native/DataTransferManagerHelper.cs
new file mode 100644
index 000000000..cca7d08c3
--- /dev/null
+++ b/GreenshotWin10Plugin/Native/DataTransferManagerHelper.cs
@@ -0,0 +1,64 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using System;
+using System.Runtime.InteropServices.WindowsRuntime;
+using Windows.ApplicationModel.DataTransfer;
+
+namespace GreenshotWin10Plugin.Native
+{
+ public class DataTransferManagerHelper
+ {
+ private const string DataTransferManagerId = "a5caee9b-8708-49d1-8d36-67d25a8da00c";
+ private readonly IDataTransferManagerInterOp _dataTransferManagerInterOp;
+ private readonly IntPtr _windowHandle;
+
+ public DataTransferManager DataTransferManager
+ {
+ get;
+ private set;
+ }
+
+ public DataTransferManagerHelper(IntPtr handle)
+ {
+ //TODO: Add a check for failure here. This will fail for versions of Windows below Windows 10
+ IActivationFactory activationFactory = WindowsRuntimeMarshal.GetActivationFactory(typeof(DataTransferManager));
+
+ // ReSharper disable once SuspiciousTypeConversion.Global
+ _dataTransferManagerInterOp = (IDataTransferManagerInterOp)activationFactory;
+
+ _windowHandle = handle;
+ var riid = new Guid(DataTransferManagerId);
+ DataTransferManager dataTransferManager;
+ _dataTransferManagerInterOp.GetForWindow(_windowHandle, riid, out dataTransferManager);
+ DataTransferManager = dataTransferManager;
+ }
+
+ ///
+ /// Show the share UI
+ ///
+ public void ShowShareUi()
+ {
+ _dataTransferManagerInterOp.ShowShareUIForWindow(_windowHandle);
+ }
+ }
+
+}
diff --git a/GreenshotWin10Plugin/Native/IDataTransferManagerInterOp.cs b/GreenshotWin10Plugin/Native/IDataTransferManagerInterOp.cs
new file mode 100644
index 000000000..f350e7372
--- /dev/null
+++ b/GreenshotWin10Plugin/Native/IDataTransferManagerInterOp.cs
@@ -0,0 +1,57 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.ApplicationModel.DataTransfer;
+
+namespace GreenshotWin10Plugin.Native
+{
+ ///
+ /// The IDataTransferManagerInterOp is documented here: https://msdn.microsoft.com/en-us/library/windows/desktop/jj542488(v=vs.85).aspx.
+ /// This interface allows an app to tie the share context to a specific
+ /// window using a window handle. Useful for Win32 apps.
+ ///
+ [ComImport, Guid("3A3DCD6C-3EAB-43DC-BCDE-45671CE800C8")]
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IDataTransferManagerInterOp
+ {
+ ///
+ /// Get an instance of Windows.ApplicationModel.DataTransfer.DataTransferManager
+ /// for the window identified by a window handle
+ ///
+ /// The window handle
+ /// ID of the DataTransferManager interface
+ /// The DataTransferManager instance for this window handle
+ /// HRESULT
+ [PreserveSig]
+ uint GetForWindow([In] IntPtr appWindow, [In] ref Guid riid, [Out] out DataTransferManager pDataTransferManager);
+
+ ///
+ /// Show the share flyout for the window identified by a window handle
+ ///
+ /// The window handle
+ /// HRESULT
+ [PreserveSig]
+ uint ShowShareUIForWindow(IntPtr appWindow);
+ }
+
+}
diff --git a/GreenshotWin10Plugin/Win10OcrDestination.cs b/GreenshotWin10Plugin/Win10OcrDestination.cs
index 9b2730455..e12bcf0fc 100644
--- a/GreenshotWin10Plugin/Win10OcrDestination.cs
+++ b/GreenshotWin10Plugin/Win10OcrDestination.cs
@@ -39,6 +39,9 @@ namespace GreenshotWin10Plugin
public override string Designation { get; } = "OCR";
public override string Description { get; } = "Windows 10 OCR";
+ ///
+ /// Constructor, this is only debug information
+ ///
public Win10OcrDestination()
{
var languages = OcrEngine.AvailableRecognizerLanguages;
@@ -58,7 +61,7 @@ namespace GreenshotWin10Plugin
/// ExportInformation
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails)
{
- ExportInformation exportInformation = new ExportInformation(Designation, Description);
+ var exportInformation = new ExportInformation(Designation, Description);
try
{
var text = Task.Run(async () =>
@@ -76,7 +79,13 @@ namespace GreenshotWin10Plugin
return ocrResult.Text;
}
}).Result;
- ClipboardHelper.SetClipboardData(text);
+
+ // Check if we found text
+ if (!string.IsNullOrWhiteSpace(text))
+ {
+ // Place the OCR text on the
+ ClipboardHelper.SetClipboardData(text);
+ }
exportInformation.ExportMade = true;
}
catch (Exception ex)
diff --git a/GreenshotWin10Plugin/Win10Plugin.cs b/GreenshotWin10Plugin/Win10Plugin.cs
index 38826a0cf..527411d8f 100644
--- a/GreenshotWin10Plugin/Win10Plugin.cs
+++ b/GreenshotWin10Plugin/Win10Plugin.cs
@@ -22,6 +22,7 @@
using System;
using System.Collections.Generic;
using Greenshot.Plugin;
+using GreenshotPlugin.Core;
namespace GreenshotWin10Plugin
{
@@ -48,9 +49,18 @@ namespace GreenshotWin10Plugin
throw new NotImplementedException();
}
+ ///
+ /// yields the windows 10 destinations if Windows 10 is detected
+ ///
+ /// IEnumerable with the destinations
public IEnumerable Destinations()
{
+ if (!Environment.OSVersion.IsWindows10())
+ {
+ yield break;
+ }
yield return new Win10OcrDestination();
+ yield return new Win10ShareDestination();
}
public IEnumerable Processors()
diff --git a/GreenshotWin10Plugin/Win10ShareDestination.cs b/GreenshotWin10Plugin/Win10ShareDestination.cs
new file mode 100644
index 000000000..5eb16487c
--- /dev/null
+++ b/GreenshotWin10Plugin/Win10ShareDestination.cs
@@ -0,0 +1,146 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2016 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using System;
+using Windows.Storage.Streams;
+using Greenshot.Plugin;
+using GreenshotPlugin.Core;
+using GreenshotWin10Plugin.Native;
+using System.Threading.Tasks;
+using Color = Windows.UI.Color;
+
+namespace GreenshotWin10Plugin
+{
+ ///
+ /// This uses the Share from Windows 10 to make the capture available to apps.
+ ///
+ public class Win10ShareDestination : AbstractDestination
+ {
+ private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(Win10ShareDestination));
+
+ public override string Designation { get; } = "Share";
+ public override string Description { get; } = "Windows 10 share";
+
+ ///
+ /// Share the screenshot with a windows app
+ ///
+ ///
+ ///
+ ///
+ /// ExportInformation
+ public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails)
+ {
+ var exportInformation = new ExportInformation(Designation, Description);
+ try
+ {
+ var handle = PluginUtils.Host.GreenshotForm.Handle;
+
+ var exportTarget = Task.Run(async () =>
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ using (var imageStream = new MemoryRandomAccessStream())
+ using (var logoStream = new MemoryRandomAccessStream())
+ using (var thumbnailStream = new MemoryRandomAccessStream())
+ {
+ // Create capture for export
+ ImageOutput.SaveToStream(surface, imageStream, new SurfaceOutputSettings());
+ imageStream.Position = 0;
+ var imageRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(imageStream);
+ RandomAccessStreamReference thumbnailRandomAccessStreamReference;
+ RandomAccessStreamReference logoRandomAccessStreamReference;
+
+ // Create thumbnail
+ using (var tmpImageForThumbnail = surface.GetImageForExport())
+ {
+ using (var thumbnail = ImageHelper.CreateThumbnail(tmpImageForThumbnail, 240, 160))
+ {
+ ImageOutput.SaveToStream(thumbnail, null, thumbnailStream, new SurfaceOutputSettings());
+ thumbnailStream.Position = 0;
+ thumbnailRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(thumbnailStream);
+ }
+ }
+ // Create logo
+ using (var logo = GreenshotResources.getGreenshotIcon().ToBitmap())
+ {
+ using (var logoThumbnail = ImageHelper.CreateThumbnail(logo, 30, 30))
+ {
+ ImageOutput.SaveToStream(logoThumbnail, null, logoStream, new SurfaceOutputSettings());
+ logoStream.Position = 0;
+ logoRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(logoStream);
+ }
+ }
+ string applicationName = null;
+ var dataTransferManagerHelper = new DataTransferManagerHelper(handle);
+ dataTransferManagerHelper.DataTransferManager.TargetApplicationChosen += (dtm, args) =>
+ {
+ Log.DebugFormat("Trying to share with {0}", args.ApplicationName);
+ applicationName = args.ApplicationName;
+ };
+ dataTransferManagerHelper.DataTransferManager.DataRequested += (sender, args) =>
+ {
+ var deferral = args.Request.GetDeferral();
+ args.Request.Data.OperationCompleted += (dp, eventArgs) =>
+ {
+ Log.DebugFormat("OperationCompleted: {0}, shared with", eventArgs.Operation);
+ taskCompletionSource.TrySetResult(applicationName);
+ };
+ var dataPackage = args.Request.Data;
+ dataPackage.Properties.Title = captureDetails.Title;
+ dataPackage.Properties.ApplicationName = "Greenshot";
+ dataPackage.Properties.Description = "Share a screenshot";
+ dataPackage.Properties.Thumbnail = thumbnailRandomAccessStreamReference;
+ dataPackage.Properties.Square30x30Logo = logoRandomAccessStreamReference;
+ dataPackage.Properties.LogoBackgroundColor = Color.FromArgb(0xff, 0x3d, 0x3d, 0x3d);
+ dataPackage.SetBitmap(imageRandomAccessStreamReference);
+ dataPackage.Destroyed += (dp, o) =>
+ {
+ Log.Debug("Destroyed.");
+ taskCompletionSource.TrySetCanceled();
+ };
+ deferral.Complete();
+ };
+ dataTransferManagerHelper.ShowShareUi();
+ return await taskCompletionSource.Task;
+ }
+ }).Result;
+ if (string.IsNullOrWhiteSpace(exportTarget))
+ {
+ exportInformation.ExportMade = false;
+ }
+ else
+ {
+ exportInformation.ExportMade = true;
+ exportInformation.DestinationDescription = exportTarget;
+ }
+ }
+ catch (Exception ex)
+ {
+ exportInformation.ExportMade = false;
+ exportInformation.ErrorMessage = ex.Message;
+ }
+
+ ProcessExport(exportInformation, surface);
+ return exportInformation;
+
+ }
+ }
+}