mirror of
https://github.com/greenshot/greenshot
synced 2025-07-14 00:53:51 -07:00
Added SafeHandles, see here: http://blogs.msdn.com/b/bclteam/archive/2005/03/15/396335.aspx to some of the Greenshot code. Not all possible handles have been converted, this should be done to prevent more possible memory/resource leaks.
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2427 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
e07278bc04
commit
502abed36a
5 changed files with 87 additions and 42 deletions
|
@ -56,18 +56,16 @@ namespace Greenshot.Controls {
|
||||||
/// <param name="hotspotY">Hotspot Y coordinate</param>
|
/// <param name="hotspotY">Hotspot Y coordinate</param>
|
||||||
/// <returns>Cursor</returns>
|
/// <returns>Cursor</returns>
|
||||||
private static Cursor CreateCursor(Bitmap bitmap, int hotspotX, int hotspotY) {
|
private static Cursor CreateCursor(Bitmap bitmap, int hotspotX, int hotspotY) {
|
||||||
IntPtr iconHandle = bitmap.GetHicon();
|
using (SafeIconHandle iconHandle = new SafeIconHandle( bitmap.GetHicon())) {
|
||||||
IntPtr icon;
|
IntPtr icon;
|
||||||
IconInfo iconInfo = new IconInfo();
|
IconInfo iconInfo = new IconInfo();
|
||||||
User32.GetIconInfo(iconHandle, out iconInfo);
|
User32.GetIconInfo(iconHandle, out iconInfo);
|
||||||
iconInfo.xHotspot = hotspotX;
|
iconInfo.xHotspot = hotspotX;
|
||||||
iconInfo.yHotspot = hotspotY;
|
iconInfo.yHotspot = hotspotY;
|
||||||
iconInfo.fIcon = false;
|
iconInfo.fIcon = false;
|
||||||
icon = User32.CreateIconIndirect(ref iconInfo);
|
icon = User32.CreateIconIndirect(ref iconInfo);
|
||||||
Cursor returnCursor = new Cursor(icon);
|
return new Cursor(icon);
|
||||||
//User32.DestroyIcon(icon);
|
}
|
||||||
User32.DestroyIcon(iconHandle);
|
|
||||||
return returnCursor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -498,33 +498,32 @@ namespace GreenshotPlugin.Core {
|
||||||
capture = new Capture();
|
capture = new Capture();
|
||||||
}
|
}
|
||||||
int x,y;
|
int x,y;
|
||||||
IntPtr hicon;
|
|
||||||
CursorInfo cursorInfo = new CursorInfo();
|
CursorInfo cursorInfo = new CursorInfo();
|
||||||
IconInfo iconInfo;
|
IconInfo iconInfo;
|
||||||
cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);
|
cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);
|
||||||
if (User32.GetCursorInfo(out cursorInfo)) {
|
if (User32.GetCursorInfo(out cursorInfo)) {
|
||||||
if (cursorInfo.flags == User32.CURSOR_SHOWING) {
|
if (cursorInfo.flags == User32.CURSOR_SHOWING) {
|
||||||
hicon = User32.CopyIcon(cursorInfo.hCursor);
|
using (SafeIconHandle safeIcon = User32.CopyIcon(cursorInfo.hCursor)) {
|
||||||
if (User32.GetIconInfo(hicon, out iconInfo)) {
|
if (User32.GetIconInfo(safeIcon, out iconInfo)) {
|
||||||
Point cursorLocation = GetCursorLocation();
|
Point cursorLocation = GetCursorLocation();
|
||||||
// Allign cursor location to Bitmap coordinates (instead of Screen coordinates)
|
// Allign cursor location to Bitmap coordinates (instead of Screen coordinates)
|
||||||
x = cursorLocation.X - iconInfo.xHotspot - capture.ScreenBounds.X;
|
x = cursorLocation.X - iconInfo.xHotspot - capture.ScreenBounds.X;
|
||||||
y = cursorLocation.Y - iconInfo.yHotspot - capture.ScreenBounds.Y;
|
y = cursorLocation.Y - iconInfo.yHotspot - capture.ScreenBounds.Y;
|
||||||
// Set the location
|
// Set the location
|
||||||
capture.CursorLocation = new Point(x, y);
|
capture.CursorLocation = new Point(x, y);
|
||||||
|
|
||||||
using (Icon icon = Icon.FromHandle(hicon)) {
|
using (Icon icon = Icon.FromHandle(safeIcon.DangerousGetHandle())) {
|
||||||
capture.Cursor = icon;
|
capture.Cursor = icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iconInfo.hbmMask != IntPtr.Zero) {
|
if (iconInfo.hbmMask != IntPtr.Zero) {
|
||||||
GDI32.DeleteObject(iconInfo.hbmMask);
|
GDI32.DeleteObject(iconInfo.hbmMask);
|
||||||
}
|
}
|
||||||
if (iconInfo.hbmColor != IntPtr.Zero) {
|
if (iconInfo.hbmColor != IntPtr.Zero) {
|
||||||
GDI32.DeleteObject(iconInfo.hbmColor);
|
GDI32.DeleteObject(iconInfo.hbmColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
User32.DestroyIcon(hicon);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return capture;
|
return capture;
|
||||||
|
|
|
@ -627,7 +627,11 @@ namespace GreenshotPlugin.Core {
|
||||||
return User32.IsIconic(this.hWnd) || Location.X <= -32000;
|
return User32.IsIconic(this.hWnd) || Location.X <= -32000;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
User32.SendMessage(this.hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_MINIMIZE, IntPtr.Zero);
|
if (value) {
|
||||||
|
User32.SendMessage(this.hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_MINIMIZE, IntPtr.Zero);
|
||||||
|
} else {
|
||||||
|
User32.SendMessage(this.hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_RESTORE, IntPtr.Zero);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,7 +664,7 @@ namespace GreenshotPlugin.Core {
|
||||||
if (monitor != IntPtr.Zero) {
|
if (monitor != IntPtr.Zero) {
|
||||||
if (appVisibility != null) {
|
if (appVisibility != null) {
|
||||||
MONITOR_APP_VISIBILITY monitorAppVisibility = appVisibility.GetAppVisibilityOnMonitor(monitor);
|
MONITOR_APP_VISIBILITY monitorAppVisibility = appVisibility.GetAppVisibilityOnMonitor(monitor);
|
||||||
LOG.DebugFormat("App visible: {0}", monitorAppVisibility);
|
LOG.DebugFormat("App {0} visible: {1} on {2}", Text, monitorAppVisibility, screen.Bounds);
|
||||||
if (monitorAppVisibility == MONITOR_APP_VISIBILITY.MAV_APP_VISIBLE) {
|
if (monitorAppVisibility == MONITOR_APP_VISIBILITY.MAV_APP_VISIBLE) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1097,6 +1101,7 @@ namespace GreenshotPlugin.Core {
|
||||||
/// <returns>Bitmap with transparency</returns>
|
/// <returns>Bitmap with transparency</returns>
|
||||||
private Bitmap ApplyTransparency(Bitmap blackBitmap, Bitmap whiteBitmap) {
|
private Bitmap ApplyTransparency(Bitmap blackBitmap, Bitmap whiteBitmap) {
|
||||||
Bitmap returnBitmap = new Bitmap(blackBitmap.Width, blackBitmap.Height, PixelFormat.Format32bppArgb);
|
Bitmap returnBitmap = new Bitmap(blackBitmap.Width, blackBitmap.Height, PixelFormat.Format32bppArgb);
|
||||||
|
returnBitmap.SetResolution(blackBitmap.HorizontalResolution, blackBitmap.VerticalResolution);
|
||||||
using (BitmapBuffer blackBuffer = new BitmapBuffer(blackBitmap, false)) {
|
using (BitmapBuffer blackBuffer = new BitmapBuffer(blackBitmap, false)) {
|
||||||
blackBuffer.Lock();
|
blackBuffer.Lock();
|
||||||
using (BitmapBuffer whiteBuffer = new BitmapBuffer(whiteBitmap, false)) {
|
using (BitmapBuffer whiteBuffer = new BitmapBuffer(whiteBitmap, false)) {
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
|
||||||
namespace GreenshotPlugin.UnmanagedHelpers {
|
namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
public static class GDIExtensions {
|
public static class GDIExtensions {
|
||||||
|
@ -37,6 +39,25 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
return topLeftVisible && topRightVisible && bottomLeftVisible && bottomRightVisible;
|
return topLeftVisible && topRightVisible && bottomLeftVisible && bottomRightVisible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A hbitmap SafeHandle implementation
|
||||||
|
/// </summary>
|
||||||
|
public class SafeHBitmapHandle : SafeHandleZeroOrMinusOneIsInvalid {
|
||||||
|
[SecurityCritical]
|
||||||
|
private SafeHBitmapHandle(): base(true) {
|
||||||
|
}
|
||||||
|
|
||||||
|
[SecurityCritical]
|
||||||
|
public SafeHBitmapHandle(IntPtr preexistingHandle) : base(true) {
|
||||||
|
SetHandle(preexistingHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ReleaseHandle() {
|
||||||
|
return GDI32.DeleteObject(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GDI32 Helpers
|
/// GDI32 Helpers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -77,9 +98,11 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
try {
|
try {
|
||||||
hDCDest = target.GetHdc();
|
hDCDest = target.GetHdc();
|
||||||
hDCSrc = CreateCompatibleDC(hDCDest);
|
hDCSrc = CreateCompatibleDC(hDCDest);
|
||||||
IntPtr pOrig = SelectObject(hDCSrc, sourceBitmap.GetHbitmap());
|
using (SafeHBitmapHandle hBitmapHandle = new SafeHBitmapHandle(sourceBitmap.GetHbitmap())) {
|
||||||
StretchBlt(hDCDest, destination.X, destination.Y, destination.Width, destination.Height, hDCSrc, source.Left, source.Top, source.Width, source.Height, CopyPixelOperation.SourceCopy);
|
IntPtr pOrig = SelectObject(hDCSrc, hBitmapHandle.DangerousGetHandle());
|
||||||
IntPtr pNew = SelectObject(hDCDest, pOrig);
|
StretchBlt(hDCDest, destination.X, destination.Y, destination.Width, destination.Height, hDCSrc, source.Left, source.Top, source.Width, source.Height, CopyPixelOperation.SourceCopy);
|
||||||
|
IntPtr pNew = SelectObject(hDCDest, pOrig);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (hDCSrc != IntPtr.Zero) {
|
if (hDCSrc != IntPtr.Zero) {
|
||||||
DeleteDC(hDCSrc);
|
DeleteDC(hDCSrc);
|
||||||
|
@ -101,9 +124,11 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
try {
|
try {
|
||||||
hDCDest = target.GetHdc();
|
hDCDest = target.GetHdc();
|
||||||
hDCSrc = CreateCompatibleDC(hDCDest);
|
hDCSrc = CreateCompatibleDC(hDCDest);
|
||||||
IntPtr pOrig = SelectObject(hDCSrc, sourceBitmap.GetHbitmap());
|
using (SafeHBitmapHandle hBitmapHandle = new SafeHBitmapHandle(sourceBitmap.GetHbitmap())) {
|
||||||
BitBlt(hDCDest, destination.X, destination.Y, source.Width, source.Height, hDCSrc, source.Left, source.Top, CopyPixelOperation.SourceCopy);
|
IntPtr pOrig = SelectObject(hDCSrc, hBitmapHandle.DangerousGetHandle());
|
||||||
IntPtr pNew = SelectObject(hDCDest, pOrig);
|
BitBlt(hDCDest, destination.X, destination.Y, source.Width, source.Height, hDCSrc, source.Left, source.Top, CopyPixelOperation.SourceCopy);
|
||||||
|
IntPtr pNew = SelectObject(hDCDest, pOrig);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (hDCSrc != IntPtr.Zero) {
|
if (hDCSrc != IntPtr.Zero) {
|
||||||
DeleteDC(hDCSrc);
|
DeleteDC(hDCSrc);
|
||||||
|
|
|
@ -25,6 +25,8 @@ using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
|
||||||
namespace GreenshotPlugin.UnmanagedHelpers {
|
namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used with EnumWindows or EnumChildWindows
|
/// Used with EnumWindows or EnumChildWindows
|
||||||
|
@ -46,6 +48,22 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
/// <param name="dwmsEventTime"></param>
|
/// <param name="dwmsEventTime"></param>
|
||||||
public delegate void WinEventDelegate(IntPtr hWinEventHook, WinEvent eventType, IntPtr hwnd, EventObjects idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
|
public delegate void WinEventDelegate(IntPtr hWinEventHook, WinEvent eventType, IntPtr hwnd, EventObjects idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A SafeHandle class implementation for the hIcon
|
||||||
|
/// </summary>
|
||||||
|
public class SafeIconHandle : SafeHandleZeroOrMinusOneIsInvalid {
|
||||||
|
private SafeIconHandle(): base(true) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SafeIconHandle(IntPtr hIcon) : base(true) {
|
||||||
|
this.SetHandle(hIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ReleaseHandle() {
|
||||||
|
return User32.DestroyIcon(this.handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// User32 Wrappers
|
/// User32 Wrappers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -210,13 +228,13 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
/// <param name="hIcon"></param>
|
/// <param name="hIcon"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[DllImport("user32", SetLastError = true)]
|
[DllImport("user32", SetLastError = true)]
|
||||||
public static extern IntPtr CopyIcon(IntPtr hIcon);
|
public static extern SafeIconHandle CopyIcon(IntPtr hIcon);
|
||||||
[DllImport("user32", SetLastError = true)]
|
[DllImport("user32", SetLastError = true)]
|
||||||
public static extern bool DestroyIcon(IntPtr hIcon);
|
public static extern bool DestroyIcon(IntPtr hIcon);
|
||||||
[DllImport("user32", SetLastError = true)]
|
[DllImport("user32", SetLastError = true)]
|
||||||
public static extern bool GetCursorInfo(out CursorInfo cursorInfo);
|
public static extern bool GetCursorInfo(out CursorInfo cursorInfo);
|
||||||
[DllImport("user32", SetLastError = true)]
|
[DllImport("user32", SetLastError = true)]
|
||||||
public static extern bool GetIconInfo(IntPtr hIcon, out IconInfo iconInfo);
|
public static extern bool GetIconInfo(SafeIconHandle iconHandle, out IconInfo iconInfo);
|
||||||
[DllImport("user32", SetLastError = true)]
|
[DllImport("user32", SetLastError = true)]
|
||||||
public static extern bool DrawIcon(IntPtr hDC, int X, int Y, IntPtr hIcon);
|
public static extern bool DrawIcon(IntPtr hDC, int X, int Y, IntPtr hIcon);
|
||||||
[DllImport("user32", SetLastError = true)]
|
[DllImport("user32", SetLastError = true)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue