fixed a bug of Screenshot on win7
This commit is contained in:
1 parent
dc64d5cacb
commit
f4087574c0
11 files changed
+850
-450
No files matched your search
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Windows;
|
||||
@@ -12,6 +14,7 @@ namespace HandyControl.Tools.Interop
|
||||
public const string
|
||||
User32 = "user32.dll",
|
||||
Gdi32 = "gdi32.dll",
|
||||
GdiPlus = "gdiplus.dll",
|
||||
Kernel32 = "kernel32.dll",
|
||||
Shell32 = "shell32.dll",
|
||||
MsImg = "msimg32.dll";
|
||||
@@ -31,6 +34,7 @@ namespace HandyControl.Tools.Interop
|
||||
PLANES = 14,
|
||||
BI_RGB = 0,
|
||||
DIB_RGB_COLORS = 0,
|
||||
E_FAIL = unchecked((int)0x80004005),
|
||||
NIF_MESSAGE = 0x00000001,
|
||||
NIF_ICON = 0x00000002,
|
||||
NIF_TIP = 0x00000004,
|
||||
@@ -659,5 +663,275 @@ namespace HandyControl.Tools.Interop
|
||||
public BitmapHandle hbmMask = null;
|
||||
public BitmapHandle hbmColor = null;
|
||||
}
|
||||
|
||||
internal enum WINDOWCOMPOSITIONATTRIB
|
||||
{
|
||||
WCA_ACCENT_POLICY = 19
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct WINCOMPATTRDATA
|
||||
{
|
||||
public WINDOWCOMPOSITIONATTRIB Attribute;
|
||||
public IntPtr Data;
|
||||
public int DataSize;
|
||||
}
|
||||
|
||||
internal enum ACCENTSTATE
|
||||
{
|
||||
ACCENT_DISABLED = 0,
|
||||
ACCENT_ENABLE_GRADIENT = 1,
|
||||
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
|
||||
ACCENT_ENABLE_BLURBEHIND = 3,
|
||||
ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
|
||||
ACCENT_INVALID_STATE = 5
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ACCENTPOLICY
|
||||
{
|
||||
public ACCENTSTATE AccentState;
|
||||
public int AccentFlags;
|
||||
public uint GradientColor;
|
||||
public int AnimationId;
|
||||
}
|
||||
|
||||
[ComImport, Guid("0000000C-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
internal interface IStream
|
||||
{
|
||||
int Read([In] IntPtr buf, [In] int len);
|
||||
|
||||
int Write([In] IntPtr buf, [In] int len);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.I8)]
|
||||
long Seek([In, MarshalAs(UnmanagedType.I8)] long dlibMove, [In] int dwOrigin);
|
||||
|
||||
void SetSize([In, MarshalAs(UnmanagedType.I8)] long libNewSize);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.I8)]
|
||||
long CopyTo([In, MarshalAs(UnmanagedType.Interface)] IStream pstm, [In, MarshalAs(UnmanagedType.I8)] long cb, [Out, MarshalAs(UnmanagedType.LPArray)] long[] pcbRead);
|
||||
|
||||
void Commit([In]int grfCommitFlags);
|
||||
|
||||
void Revert();
|
||||
|
||||
void LockRegion([In, MarshalAs(UnmanagedType.I8)]long libOffset, [In, MarshalAs(UnmanagedType.I8)] long cb, [In] int dwLockType);
|
||||
|
||||
void UnlockRegion([In, MarshalAs(UnmanagedType.I8)] long libOffset, [In, MarshalAs(UnmanagedType.I8)] long cb, [In] int dwLockType);
|
||||
|
||||
void Stat([In] IntPtr pStatstg, [In] int grfStatFlag);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
IStream Clone();
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
internal class StreamConsts
|
||||
{
|
||||
public const int LOCK_WRITE = 0x1;
|
||||
public const int LOCK_EXCLUSIVE = 0x2;
|
||||
public const int LOCK_ONLYONCE = 0x4;
|
||||
public const int STATFLAG_DEFAULT = 0x0;
|
||||
public const int STATFLAG_NONAME = 0x1;
|
||||
public const int STATFLAG_NOOPEN = 0x2;
|
||||
public const int STGC_DEFAULT = 0x0;
|
||||
public const int STGC_OVERWRITE = 0x1;
|
||||
public const int STGC_ONLYIFCURRENT = 0x2;
|
||||
public const int STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE = 0x4;
|
||||
public const int STREAM_SEEK_SET = 0x0;
|
||||
public const int STREAM_SEEK_CUR = 0x1;
|
||||
public const int STREAM_SEEK_END = 0x2;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 8)]
|
||||
internal class ImageCodecInfoPrivate
|
||||
{
|
||||
[MarshalAs(UnmanagedType.Struct)]
|
||||
public Guid Clsid;
|
||||
[MarshalAs(UnmanagedType.Struct)]
|
||||
public Guid FormatID;
|
||||
|
||||
public IntPtr CodecName = IntPtr.Zero;
|
||||
public IntPtr DllName = IntPtr.Zero;
|
||||
public IntPtr FormatDescription = IntPtr.Zero;
|
||||
public IntPtr FilenameExtension = IntPtr.Zero;
|
||||
public IntPtr MimeType = IntPtr.Zero;
|
||||
|
||||
public int Flags;
|
||||
public int Version;
|
||||
public int SigCount;
|
||||
public int SigSize;
|
||||
|
||||
public IntPtr SigPattern = IntPtr.Zero;
|
||||
public IntPtr SigMask = IntPtr.Zero;
|
||||
}
|
||||
|
||||
internal class ComStreamFromDataStream : IStream
|
||||
{
|
||||
protected Stream DataStream;
|
||||
|
||||
// to support seeking ahead of the stream length...
|
||||
private long _virtualPosition = -1;
|
||||
|
||||
internal ComStreamFromDataStream(Stream dataStream)
|
||||
{
|
||||
this.DataStream = dataStream ?? throw new ArgumentNullException(nameof(dataStream));
|
||||
}
|
||||
|
||||
private void ActualizeVirtualPosition()
|
||||
{
|
||||
if (_virtualPosition == -1) return;
|
||||
|
||||
if (_virtualPosition > DataStream.Length)
|
||||
DataStream.SetLength(_virtualPosition);
|
||||
|
||||
DataStream.Position = _virtualPosition;
|
||||
|
||||
_virtualPosition = -1;
|
||||
}
|
||||
|
||||
public virtual IStream Clone()
|
||||
{
|
||||
NotImplemented();
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void Commit(int grfCommitFlags)
|
||||
{
|
||||
DataStream.Flush();
|
||||
ActualizeVirtualPosition();
|
||||
}
|
||||
|
||||
public virtual long CopyTo(IStream pstm, long cb, long[] pcbRead)
|
||||
{
|
||||
const int bufsize = 4096; // one page
|
||||
var buffer = Marshal.AllocHGlobal(bufsize);
|
||||
if (buffer == IntPtr.Zero) throw new OutOfMemoryException();
|
||||
long written = 0;
|
||||
|
||||
try
|
||||
{
|
||||
while (written < cb)
|
||||
{
|
||||
var toRead = bufsize;
|
||||
if (written + toRead > cb) toRead = (int)(cb - written);
|
||||
var read = Read(buffer, toRead);
|
||||
if (read == 0) break;
|
||||
if (pstm.Write(buffer, read) != read)
|
||||
{
|
||||
throw EFail("Wrote an incorrect number of bytes");
|
||||
}
|
||||
written += read;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
}
|
||||
if (pcbRead != null && pcbRead.Length > 0)
|
||||
{
|
||||
pcbRead[0] = written;
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
public virtual Stream GetDataStream() => DataStream;
|
||||
|
||||
public virtual void LockRegion(long libOffset, long cb, int dwLockType)
|
||||
{
|
||||
}
|
||||
|
||||
protected static ExternalException EFail(string msg) => throw new ExternalException(msg, E_FAIL);
|
||||
|
||||
protected static void NotImplemented() => throw new NotImplementedException();
|
||||
|
||||
public virtual int Read(IntPtr buf, int length)
|
||||
{
|
||||
var buffer = new byte[length];
|
||||
var count = Read(buffer, length);
|
||||
Marshal.Copy(buffer, 0, buf, length);
|
||||
return count;
|
||||
}
|
||||
|
||||
public virtual int Read(byte[] buffer, int length)
|
||||
{
|
||||
ActualizeVirtualPosition();
|
||||
return DataStream.Read(buffer, 0, length);
|
||||
}
|
||||
|
||||
public virtual void Revert() => NotImplemented();
|
||||
|
||||
public virtual long Seek(long offset, int origin)
|
||||
{
|
||||
var pos = _virtualPosition;
|
||||
if (_virtualPosition == -1)
|
||||
{
|
||||
pos = DataStream.Position;
|
||||
}
|
||||
var len = DataStream.Length;
|
||||
|
||||
switch (origin)
|
||||
{
|
||||
case StreamConsts.STREAM_SEEK_SET:
|
||||
if (offset <= len)
|
||||
{
|
||||
DataStream.Position = offset;
|
||||
_virtualPosition = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_virtualPosition = offset;
|
||||
}
|
||||
break;
|
||||
case StreamConsts.STREAM_SEEK_END:
|
||||
if (offset <= 0)
|
||||
{
|
||||
DataStream.Position = len + offset;
|
||||
_virtualPosition = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_virtualPosition = len + offset;
|
||||
}
|
||||
break;
|
||||
case StreamConsts.STREAM_SEEK_CUR:
|
||||
if (offset + pos <= len)
|
||||
{
|
||||
DataStream.Position = pos + offset;
|
||||
_virtualPosition = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_virtualPosition = offset + pos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return _virtualPosition != -1 ? _virtualPosition : DataStream.Position;
|
||||
}
|
||||
|
||||
public virtual void SetSize(long value) => DataStream.SetLength(value);
|
||||
|
||||
public virtual void Stat(IntPtr pstatstg, int grfStatFlag) => NotImplemented();
|
||||
|
||||
public virtual void UnlockRegion(long libOffset, long cb, int dwLockType)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Write(IntPtr buf, int length)
|
||||
{
|
||||
var buffer = new byte[length];
|
||||
Marshal.Copy(buf, buffer, 0, length);
|
||||
return Write(buffer, length);
|
||||
}
|
||||
|
||||
public virtual int Write(byte[] buffer, int length)
|
||||
{
|
||||
ActualizeVirtualPosition();
|
||||
DataStream.Write(buffer, 0, length);
|
||||
return length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user