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:
RKrom 2013-01-13 15:53:35 +00:00
commit 502abed36a
5 changed files with 87 additions and 42 deletions

View file

@ -21,6 +21,8 @@
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Security;
using Microsoft.Win32.SafeHandles;
namespace GreenshotPlugin.UnmanagedHelpers {
public static class GDIExtensions {
@ -37,6 +39,25 @@ namespace GreenshotPlugin.UnmanagedHelpers {
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>
/// GDI32 Helpers
/// </summary>
@ -77,9 +98,11 @@ namespace GreenshotPlugin.UnmanagedHelpers {
try {
hDCDest = target.GetHdc();
hDCSrc = CreateCompatibleDC(hDCDest);
IntPtr pOrig = SelectObject(hDCSrc, sourceBitmap.GetHbitmap());
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);
using (SafeHBitmapHandle hBitmapHandle = new SafeHBitmapHandle(sourceBitmap.GetHbitmap())) {
IntPtr pOrig = SelectObject(hDCSrc, hBitmapHandle.DangerousGetHandle());
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 {
if (hDCSrc != IntPtr.Zero) {
DeleteDC(hDCSrc);
@ -101,9 +124,11 @@ namespace GreenshotPlugin.UnmanagedHelpers {
try {
hDCDest = target.GetHdc();
hDCSrc = CreateCompatibleDC(hDCDest);
IntPtr pOrig = SelectObject(hDCSrc, sourceBitmap.GetHbitmap());
BitBlt(hDCDest, destination.X, destination.Y, source.Width, source.Height, hDCSrc, source.Left, source.Top, CopyPixelOperation.SourceCopy);
IntPtr pNew = SelectObject(hDCDest, pOrig);
using (SafeHBitmapHandle hBitmapHandle = new SafeHBitmapHandle(sourceBitmap.GetHbitmap())) {
IntPtr pOrig = SelectObject(hDCSrc, hBitmapHandle.DangerousGetHandle());
BitBlt(hDCDest, destination.X, destination.Y, source.Width, source.Height, hDCSrc, source.Left, source.Top, CopyPixelOperation.SourceCopy);
IntPtr pNew = SelectObject(hDCDest, pOrig);
}
} finally {
if (hDCSrc != IntPtr.Zero) {
DeleteDC(hDCSrc);

View file

@ -25,6 +25,8 @@ using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;
namespace GreenshotPlugin.UnmanagedHelpers {
/// <summary>
/// Used with EnumWindows or EnumChildWindows
@ -45,6 +47,22 @@ namespace GreenshotPlugin.UnmanagedHelpers {
/// <param name="dwEventThread"></param>
/// <param name="dwmsEventTime"></param>
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>
/// User32 Wrappers
@ -210,13 +228,13 @@ namespace GreenshotPlugin.UnmanagedHelpers {
/// <param name="hIcon"></param>
/// <returns></returns>
[DllImport("user32", SetLastError = true)]
public static extern IntPtr CopyIcon(IntPtr hIcon);
public static extern SafeIconHandle CopyIcon(IntPtr hIcon);
[DllImport("user32", SetLastError = true)]
public static extern bool DestroyIcon(IntPtr hIcon);
[DllImport("user32", SetLastError = true)]
public static extern bool GetCursorInfo(out CursorInfo cursorInfo);
[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)]
public static extern bool DrawIcon(IntPtr hDC, int X, int Y, IntPtr hIcon);
[DllImport("user32", SetLastError = true)]