using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
public static partial class Gdi32
{
/// Provides a selection context for graphics objects.
///
///
/// using (var screenDC = SafeHDC.ScreenCompatibleDCHandle)
/// {
/// var brush = CreateSolidBrush(Color.Red);
/// using (new GdiObjectContext(screenDC, brush))
/// {
/// // Do brush stuff
/// }
///
/// var pen = CreatePen(PS_SOLID, 1, Color.Black);
/// // Alternatively, call the SelectObject method on the SafeHDC object
/// using (screenDC.SelectObject(pen))
/// {
/// // Do pen stuff
/// }
/// }
///
///
///
public class GdiObjectContext : IDisposable
{
private readonly HDC hDC;
private readonly HGDIOBJ hOld;
/// Initializes a new instance of the class.
/// The HDC into which is selected.
/// The graphics object to select.
/// hdc - Device context cannot be null.
public GdiObjectContext(HDC hdc, HGDIOBJ hObj)
{
if (hdc.IsNull) throw new ArgumentNullException(nameof(hdc), "Device context cannot be null.");
hDC = hdc;
hOld = SelectObject(hdc, hObj);
}
///
void IDisposable.Dispose() => SelectObject(hDC, hOld);
}
///
/// Provides a to a graphics bitmap object that releases a created HBITMAP instance at disposal using DeleteObject.
///
public class SafeHBITMAP : SafeHANDLE, IGraphicsObjectHandle
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHBITMAP(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeHBITMAP() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HBITMAP(SafeHBITMAP h) => h.handle;
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HGDIOBJ(SafeHBITMAP h) => h.handle;
///
protected override bool InternalReleaseHandle() => DeleteObject(this);
}
///
/// Provides a to a graphics bitmap object that releases a created HBRUSH instance at disposal using DeleteObject.
///
public class SafeHBRUSH : SafeHANDLE, IGraphicsObjectHandle
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHBRUSH(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeHBRUSH() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HBRUSH(SafeHBRUSH h) => h.handle;
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HGDIOBJ(SafeHBRUSH h) => h.handle;
///
protected override bool InternalReleaseHandle() => DeleteObject(this);
}
/// A SafeHandle to track DC handles.
public class SafeHDC : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHDC(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeHDC() : base() { }
/// Gets the screen compatible device context handle.
/// The screen compatible device context handle.
public static SafeHDC ScreenCompatibleDCHandle => CreateCompatibleDC(HDC.NULL);
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HDC(SafeHDC h) => h.handle;
/// Gets the compatible device context handle.
/// A device context handle.
public SafeHDC GetCompatibleDCHandle() => CreateCompatibleDC(handle);
/// Creates a context into which a graphics object is selected.
/// The graphics object to select.
/// A selection context for the graphics object.
public GdiObjectContext SelectObject(HGDIOBJ hObject) => new GdiObjectContext(handle, hObject);
///
protected override bool InternalReleaseHandle()
{
return DeleteDC(handle);
}
}
///
/// Provides a to a graphics bitmap object that releases a created HFONT instance at disposal using DeleteObject.
///
public class SafeHFONT : SafeHANDLE, IGraphicsObjectHandle
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHFONT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeHFONT() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HFONT(SafeHFONT h) => h.handle;
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HGDIOBJ(SafeHFONT h) => h.handle;
///
protected override bool InternalReleaseHandle() => DeleteObject(this);
}
///
/// Provides a to a graphics color palette object that releases a created HPALETTE instance at disposal
/// using DeleteObject.
///
public class SafeHPALETTE : SafeHANDLE, IGraphicsObjectHandle
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHPALETTE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeHPALETTE() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HGDIOBJ(SafeHPALETTE h) => h.handle;
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HPALETTE(SafeHPALETTE h) => h.handle;
///
protected override bool InternalReleaseHandle() => DeleteObject(this);
}
///
/// Provides a to a graphics bitmap object that releases a created HPEN instance at disposal using DeleteObject.
///
public class SafeHPEN : SafeHANDLE, IGraphicsObjectHandle
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHPEN(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeHPEN() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HGDIOBJ(SafeHPEN h) => h.handle;
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HPEN(SafeHPEN h) => h.handle;
///
protected override bool InternalReleaseHandle() => DeleteObject(this);
}
///
/// Provides a to a graphics bitmap object that releases a created HRGN instance at disposal using DeleteObject.
///
public class SafeHRGN : SafeHANDLE, IGraphicsObjectHandle
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHRGN(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeHRGN() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HGDIOBJ(SafeHRGN h) => h.handle;
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HRGN(SafeHRGN h) => h.handle;
///
protected override bool InternalReleaseHandle() => DeleteObject(this);
}
}
}