diff --git a/GreenshotPlugin/Core/BinaryStructHelper.cs b/GreenshotPlugin/Core/BinaryStructHelper.cs
new file mode 100644
index 000000000..af3c96398
--- /dev/null
+++ b/GreenshotPlugin/Core/BinaryStructHelper.cs
@@ -0,0 +1,72 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 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;
+
+namespace GreenshotPlugin.Core {
+ ///
+ /// A helper class which does the mashalling for structs
+ ///
+ public static class BinaryStructHelper {
+ ///
+ /// Get a struct from a byte array
+ ///
+ /// typeof struct
+ /// byte[]
+ /// struct
+ public static T FromByteArray(byte[] bytes) where T : struct {
+ IntPtr ptr = IntPtr.Zero;
+ try {
+ int size = Marshal.SizeOf(typeof(T));
+ ptr = Marshal.AllocHGlobal(size);
+ Marshal.Copy(bytes, 0, ptr, size);
+ object obj = Marshal.PtrToStructure(ptr, typeof(T));
+ return (T)obj;
+ } finally {
+ if (ptr != IntPtr.Zero) {
+ Marshal.FreeHGlobal(ptr);
+ }
+ }
+ }
+
+ ///
+ /// copy a struct to a byte array
+ ///
+ /// typeof struct
+ /// struct
+ /// byte[]
+ public static byte[] ToByteArray(T obj) where T : struct {
+ IntPtr ptr = IntPtr.Zero;
+ try {
+ int size = Marshal.SizeOf(typeof(T));
+ ptr = Marshal.AllocHGlobal(size);
+ Marshal.StructureToPtr(obj, ptr, true);
+ byte[] bytes = new byte[size];
+ Marshal.Copy(ptr, bytes, 0, size);
+ return bytes;
+ } finally {
+ if (ptr != IntPtr.Zero) {
+ Marshal.FreeHGlobal(ptr);
+ }
+ }
+ }
+ }
+}
diff --git a/GreenshotPlugin/Core/ClipboardHelper.cs b/GreenshotPlugin/Core/ClipboardHelper.cs
index dcb0ae935..c1eab0366 100644
--- a/GreenshotPlugin/Core/ClipboardHelper.cs
+++ b/GreenshotPlugin/Core/ClipboardHelper.cs
@@ -22,7 +22,6 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
-using System.Drawing.Imaging;
using System.IO;
using System.Text;
using System.Threading;
@@ -30,6 +29,7 @@ using System.Windows.Forms;
using Greenshot.IniFile;
using Greenshot.Plugin;
using GreenshotPlugin.UnmanagedHelpers;
+using System.Runtime.InteropServices;
namespace GreenshotPlugin.Core {
///
@@ -238,6 +238,37 @@ EndSelection:<<<<<<<4
}
}
}
+ // If the EnableSpecialDIBClipboardReader flag in the config is set, use the code from:
+ // http://www.thomaslevesque.com/2009/02/05/wpf-paste-an-image-from-the-clipboard/
+ // to read the DeviceIndependentBitmap from the clipboard, this might fix bug 3576125
+ if (config.EnableSpecialDIBClipboardReader) {
+ MemoryStream ms = Clipboard.GetData("DeviceIndependentBitmap") as MemoryStream;
+ if (ms != null) {
+ byte[] dibBuffer = new byte[ms.Length];
+ ms.Read(dibBuffer, 0, dibBuffer.Length);
+ BitmapInfoHeader infoHeader = BinaryStructHelper.FromByteArray(dibBuffer);
+
+ int fileHeaderSize = Marshal.SizeOf(typeof(BitmapFileHeader));
+ uint infoHeaderSize = infoHeader.biSize;
+ int fileSize = (int)(fileHeaderSize + infoHeader.biSize + infoHeader.biSizeImage);
+
+ BitmapFileHeader fileHeader = new BitmapFileHeader();
+ fileHeader.bfType = BitmapFileHeader.BM;
+ fileHeader.bfSize = fileSize;
+ fileHeader.bfReserved1 = 0;
+ fileHeader.bfReserved2 = 0;
+ fileHeader.bfOffBits = (int)(fileHeaderSize + infoHeaderSize + infoHeader.biClrUsed * 4);
+
+ byte[] fileHeaderBytes = BinaryStructHelper.ToByteArray(fileHeader);
+
+ using (MemoryStream msBitmap = new MemoryStream()) {
+ msBitmap.Write(fileHeaderBytes, 0, fileHeaderSize);
+ msBitmap.Write(dibBuffer, 0, dibBuffer.Length);
+ msBitmap.Seek(0, SeekOrigin.Begin);
+ return Image.FromStream(msBitmap);
+ }
+ }
+ }
return Clipboard.GetImage();
} catch (Exception ee) {
if (retryCount == 0) {
diff --git a/GreenshotPlugin/Core/CoreConfiguration.cs b/GreenshotPlugin/Core/CoreConfiguration.cs
index 96591f3c7..1ec077e94 100644
--- a/GreenshotPlugin/Core/CoreConfiguration.cs
+++ b/GreenshotPlugin/Core/CoreConfiguration.cs
@@ -191,6 +191,9 @@ namespace GreenshotPlugin.Core {
[IniProperty("ExperimentalFeatures", Description="A list of experimental features, this allows us to test certain features before releasing them.", ExcludeIfNull=true)]
public List ExperimentalFeatures;
+ [IniProperty("EnableSpecialDIBClipboardReader", Description = "Enable a special DIB clipboard reader", DefaultValue="False")]
+ public bool EnableSpecialDIBClipboardReader;
+
// Specify what THIS build is
public bool isRelease = false;
public bool isReleaseCandidate = true;
diff --git a/GreenshotPlugin/Core/IEHelper.cs b/GreenshotPlugin/Core/IEHelper.cs
index 2283daf44..481911d41 100644
--- a/GreenshotPlugin/Core/IEHelper.cs
+++ b/GreenshotPlugin/Core/IEHelper.cs
@@ -52,6 +52,9 @@ namespace GreenshotPlugin.Core {
/// The browser WindowDetails
/// WindowDetails for the DirectUI window
public static WindowDetails GetDirectUI(WindowDetails browserWindowDetails) {
+ if (browserWindowDetails == null) {
+ return null;
+ }
WindowDetails tmpWD = browserWindowDetails;
// Since IE 9 the TabBandClass is less deep!
if (IEHelper.IEVersion() < 9) {
diff --git a/GreenshotPlugin/GreenshotPlugin.csproj b/GreenshotPlugin/GreenshotPlugin.csproj
index 99dd85b8f..cbba0de09 100644
--- a/GreenshotPlugin/GreenshotPlugin.csproj
+++ b/GreenshotPlugin/GreenshotPlugin.csproj
@@ -198,6 +198,7 @@
+
diff --git a/GreenshotPlugin/UnmanagedHelpers/GDI32.cs b/GreenshotPlugin/UnmanagedHelpers/GDI32.cs
index c1262f850..8868271c1 100644
--- a/GreenshotPlugin/UnmanagedHelpers/GDI32.cs
+++ b/GreenshotPlugin/UnmanagedHelpers/GDI32.cs
@@ -46,7 +46,17 @@ namespace GreenshotPlugin.UnmanagedHelpers {
[DllImport("gdi32", SetLastError = true)]
public static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);
}
-
+
+ [StructLayout(LayoutKind.Sequential, Pack = 2)]
+ public struct BitmapFileHeader {
+ public static readonly short BM = 0x4d42; // BM
+ public short bfType;
+ public int bfSize;
+ public short bfReserved1;
+ public short bfReserved2;
+ public int bfOffBits;
+ }
+
[StructLayout(LayoutKind.Sequential)]
public struct BitmapInfoHeader {
public uint biSize;