2017-11-27 13:11:20 -05:00
using System ;
2018-11-28 14:33:55 -05:00
using System.Runtime.InteropServices ;
2017-11-27 13:11:20 -05:00
namespace Vanara.PInvoke
{
public static partial class Gdi32
{
2018-09-22 00:35:34 -04:00
/// <summary>Provides a selection context for graphics objects.</summary>
/// <example>
/// <code language="cs" title="Using a pen and brush">
/// using (var screenDC = SafeHDC.ScreenCompatibleDCHandle)
/// {
2018-10-26 14:24:07 -04:00
/// 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
/// }
2018-09-22 00:35:34 -04:00
/// }
/// </code>
/// </example>
/// <seealso cref="System.IDisposable"/>
public class GdiObjectContext : IDisposable
2017-11-27 13:11:20 -05:00
{
2018-09-22 00:35:34 -04:00
private readonly HDC hDC ;
private readonly HGDIOBJ hOld ;
/// <summary>Initializes a new instance of the <see cref="GdiObjectContext"/> class.</summary>
/// <param name="hdc">The HDC into which <paramref name="hObj"/> is selected.</param>
/// <param name="hObj">The graphics object to select.</param>
/// <exception cref="ArgumentNullException">hdc - Device context cannot be null.</exception>
public GdiObjectContext ( HDC hdc , HGDIOBJ hObj )
{
2018-10-26 14:24:07 -04:00
if ( hdc . IsNull ) throw new ArgumentNullException ( nameof ( hdc ) , "Device context cannot be null." ) ;
2018-09-22 00:35:34 -04:00
hDC = hdc ;
hOld = SelectObject ( hdc , hObj ) ;
}
/// <inheritdoc/>
void IDisposable . Dispose ( ) = > SelectObject ( hDC , hOld ) ;
}
2018-10-26 14:24:07 -04:00
/// <summary>
2018-11-28 14:33:55 -05:00
/// Provides a <see cref="System.Runtime.InteropServices.SafeHandle"/> to a graphics bitmap object that releases a created HBITMAP instance at disposal using DeleteObject.
2018-10-26 14:24:07 -04:00
/// </summary>
2020-11-05 09:11:49 -05:00
public class SafeHBITMAP : SafeHANDLE , IGraphicsObjectHandle
2018-10-26 14:24:07 -04:00
{
/// <summary>Initializes a new instance of the <see cref="SafeHBITMAP"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHBITMAP ( IntPtr preexistingHandle , bool ownsHandle = true ) : base ( preexistingHandle , ownsHandle ) { }
private SafeHBITMAP ( ) : base ( ) { }
/// <summary>Performs an implicit conversion from <see cref="SafeHBITMAP"/> to <see cref="HBITMAP"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HBITMAP ( SafeHBITMAP h ) = > h . handle ;
/// <summary>Performs an implicit conversion from <see cref="SafeHBITMAP"/> to <see cref="HGDIOBJ"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HGDIOBJ ( SafeHBITMAP h ) = > h . handle ;
/// <inheritdoc/>
protected override bool InternalReleaseHandle ( ) = > DeleteObject ( this ) ;
}
/// <summary>
/// Provides a <see cref="SafeHandle"/> to a graphics bitmap object that releases a created HBRUSH instance at disposal using DeleteObject.
/// </summary>
2020-11-05 09:11:49 -05:00
public class SafeHBRUSH : SafeHANDLE , IGraphicsObjectHandle
2018-10-26 14:24:07 -04:00
{
/// <summary>Initializes a new instance of the <see cref="SafeHBRUSH"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHBRUSH ( IntPtr preexistingHandle , bool ownsHandle = true ) : base ( preexistingHandle , ownsHandle ) { }
private SafeHBRUSH ( ) : base ( ) { }
/// <summary>Performs an implicit conversion from <see cref="SafeHBRUSH"/> to <see cref="HBRUSH"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HBRUSH ( SafeHBRUSH h ) = > h . handle ;
/// <summary>Performs an implicit conversion from <see cref="SafeHBRUSH"/> to <see cref="HGDIOBJ"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HGDIOBJ ( SafeHBRUSH h ) = > h . handle ;
/// <inheritdoc/>
protected override bool InternalReleaseHandle ( ) = > DeleteObject ( this ) ;
}
2018-09-22 00:35:34 -04:00
/// <summary>A SafeHandle to track DC handles.</summary>
2019-02-04 11:51:08 -05:00
public class SafeHDC : SafeHANDLE
2018-09-22 00:35:34 -04:00
{
/// <summary>Initializes a new instance of the <see cref="SafeHDC"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
2017-11-27 13:11:20 -05:00
/// <param name="ownsHandle">
2018-09-22 00:35:34 -04:00
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
2017-11-27 13:11:20 -05:00
/// </param>
2018-09-22 00:35:34 -04:00
public SafeHDC ( IntPtr preexistingHandle , bool ownsHandle = true ) : base ( preexistingHandle , ownsHandle ) { }
2017-11-27 13:11:20 -05:00
2018-10-26 14:24:07 -04:00
private SafeHDC ( ) : base ( ) { }
2017-11-27 13:11:20 -05:00
/// <summary>Gets the screen compatible device context handle.</summary>
/// <value>The screen compatible device context handle.</value>
2018-10-26 14:24:07 -04:00
public static SafeHDC ScreenCompatibleDCHandle = > CreateCompatibleDC ( HDC . NULL ) ;
2017-11-27 13:11:20 -05:00
2018-10-26 14:24:07 -04:00
/// <summary>Performs an implicit conversion from <see cref="SafeHDC"/> to <see cref="HDC"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HDC ( SafeHDC h ) = > h . handle ;
2017-11-27 13:11:20 -05:00
/// <summary>Gets the compatible device context handle.</summary>
2019-10-01 19:45:45 -04:00
/// <returns>A device context handle.</returns>
2022-01-14 09:32:51 -05:00
public SafeHDC GetCompatibleDCHandle ( ) = > CreateCompatibleDC ( handle ) ;
2018-09-22 00:35:34 -04:00
/// <summary>Creates a context into which a graphics object is selected.</summary>
/// <param name="hObject">The graphics object to select.</param>
/// <returns>A selection context for the graphics object.</returns>
2022-01-14 09:32:51 -05:00
public GdiObjectContext SelectObject ( HGDIOBJ hObject ) = > new GdiObjectContext ( handle , hObject ) ;
2017-11-27 13:11:20 -05:00
/// <inheritdoc/>
2018-09-22 00:35:34 -04:00
protected override bool InternalReleaseHandle ( )
2017-11-27 13:11:20 -05:00
{
2022-01-14 09:32:51 -05:00
return DeleteDC ( handle ) ;
2017-11-27 13:11:20 -05:00
}
}
2018-09-22 00:35:34 -04:00
/// <summary>
2018-10-26 14:24:07 -04:00
/// Provides a <see cref="SafeHandle"/> to a graphics bitmap object that releases a created HFONT instance at disposal using DeleteObject.
2018-09-22 00:35:34 -04:00
/// </summary>
2020-11-05 09:11:49 -05:00
public class SafeHFONT : SafeHANDLE , IGraphicsObjectHandle
2017-11-27 13:11:20 -05:00
{
2018-10-26 14:24:07 -04:00
/// <summary>Initializes a new instance of the <see cref="SafeHFONT"/> class and assigns an existing handle.</summary>
2018-09-22 00:35:34 -04:00
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
2018-10-26 14:24:07 -04:00
public SafeHFONT ( IntPtr preexistingHandle , bool ownsHandle = true ) : base ( preexistingHandle , ownsHandle ) { }
2017-11-27 13:11:20 -05:00
2018-10-26 14:24:07 -04:00
private SafeHFONT ( ) : base ( ) { }
2018-09-22 00:35:34 -04:00
2018-10-26 14:24:07 -04:00
/// <summary>Performs an implicit conversion from <see cref="SafeHFONT"/> to <see cref="HFONT"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HFONT ( SafeHFONT h ) = > h . handle ;
2018-09-22 00:35:34 -04:00
2018-10-26 14:24:07 -04:00
/// <summary>Performs an implicit conversion from <see cref="SafeHFONT"/> to <see cref="HGDIOBJ"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HGDIOBJ ( SafeHFONT h ) = > h . handle ;
2018-09-22 00:35:34 -04:00
2018-10-26 14:24:07 -04:00
/// <inheritdoc/>
protected override bool InternalReleaseHandle ( ) = > DeleteObject ( this ) ;
2018-09-22 00:35:34 -04:00
}
2017-11-27 13:11:20 -05:00
2018-09-22 00:35:34 -04:00
/// <summary>
2018-10-26 14:24:07 -04:00
/// Provides a <see cref="SafeHandle"/> to a graphics color palette object that releases a created HPALETTE instance at disposal
/// using DeleteObject.
2018-09-22 00:35:34 -04:00
/// </summary>
2020-11-05 09:11:49 -05:00
public class SafeHPALETTE : SafeHANDLE , IGraphicsObjectHandle
2018-09-22 00:35:34 -04:00
{
2018-10-26 14:24:07 -04:00
/// <summary>Initializes a new instance of the <see cref="SafeHPALETTE"/> class and assigns an existing handle.</summary>
2018-09-22 00:35:34 -04:00
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
2018-10-26 14:24:07 -04:00
public SafeHPALETTE ( IntPtr preexistingHandle , bool ownsHandle = true ) : base ( preexistingHandle , ownsHandle ) { }
2018-09-22 00:35:34 -04:00
2018-10-26 14:24:07 -04:00
private SafeHPALETTE ( ) : base ( ) { }
2018-09-22 00:35:34 -04:00
2018-10-26 14:24:07 -04:00
/// <summary>Performs an implicit conversion from <see cref="SafeHPALETTE"/> to <see cref="HGDIOBJ"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HGDIOBJ ( SafeHPALETTE h ) = > h . handle ;
2018-01-21 00:28:00 -05:00
2018-10-26 14:24:07 -04:00
/// <summary>Performs an implicit conversion from <see cref="SafeHPALETTE"/> to <see cref="HPALETTE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HPALETTE ( SafeHPALETTE h ) = > h . handle ;
2018-09-22 00:35:34 -04:00
2018-10-26 14:24:07 -04:00
/// <inheritdoc/>
protected override bool InternalReleaseHandle ( ) = > DeleteObject ( this ) ;
2018-09-22 00:35:34 -04:00
}
/// <summary>
/// Provides a <see cref="SafeHandle"/> to a graphics bitmap object that releases a created HPEN instance at disposal using DeleteObject.
/// </summary>
2020-11-05 09:11:49 -05:00
public class SafeHPEN : SafeHANDLE , IGraphicsObjectHandle
2018-01-21 00:28:00 -05:00
{
2018-09-22 00:35:34 -04:00
/// <summary>Initializes a new instance of the <see cref="SafeHPEN"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHPEN ( IntPtr preexistingHandle , bool ownsHandle = true ) : base ( preexistingHandle , ownsHandle ) { }
2018-10-26 14:24:07 -04:00
private SafeHPEN ( ) : base ( ) { }
/// <summary>Performs an implicit conversion from <see cref="SafeHPEN"/> to <see cref="HGDIOBJ"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HGDIOBJ ( SafeHPEN h ) = > h . handle ;
/// <summary>Performs an implicit conversion from <see cref="SafeHPEN"/> to <see cref="HPEN"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HPEN ( SafeHPEN h ) = > h . handle ;
/// <inheritdoc/>
protected override bool InternalReleaseHandle ( ) = > DeleteObject ( this ) ;
2018-09-22 00:35:34 -04:00
}
/// <summary>
/// Provides a <see cref="SafeHandle"/> to a graphics bitmap object that releases a created HRGN instance at disposal using DeleteObject.
/// </summary>
2020-11-05 09:11:49 -05:00
public class SafeHRGN : SafeHANDLE , IGraphicsObjectHandle
2018-09-22 00:35:34 -04:00
{
/// <summary>Initializes a new instance of the <see cref="SafeHRGN"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHRGN ( IntPtr preexistingHandle , bool ownsHandle = true ) : base ( preexistingHandle , ownsHandle ) { }
2018-10-26 14:24:07 -04:00
private SafeHRGN ( ) : base ( ) { }
/// <summary>Performs an implicit conversion from <see cref="SafeHRGN"/> to <see cref="HGDIOBJ"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HGDIOBJ ( SafeHRGN h ) = > h . handle ;
/// <summary>Performs an implicit conversion from <see cref="SafeHRGN"/> to <see cref="HRGN"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HRGN ( SafeHRGN h ) = > h . handle ;
/// <inheritdoc/>
protected override bool InternalReleaseHandle ( ) = > DeleteObject ( this ) ;
2018-01-21 00:28:00 -05:00
}
2017-11-27 13:11:20 -05:00
}
}