<PackageReference Include="System.Drawing.Common" Version="9.0.10" />

RegionScope

struct RegionScope
Helper to scope creating regions. Deletes the region when disposed.
using System; using System.Drawing; using System.Runtime.CompilerServices; using Windows.Win32.Foundation; using Windows.Win32.Graphics.GdiPlus; namespace Windows.Win32.Graphics.Gdi { [CompilerFeatureRequired("RefStructs")] internal ref struct RegionScope { public HRGN Region { [IsReadOnly] get; private set; } public bool IsNull { [IsReadOnly] get { return Region.IsNull; } } public RegionScope(Rectangle rectangle) { Region = PInvokeCore.CreateRectRgn(rectangle.X, rectangle.Y, rectangle.Right, rectangle.Bottom); } public RegionScope(int x1, int y1, int x2, int y2) { Region = PInvokeCore.CreateRectRgn(x1, y1, x2, y2); } public RegionScope(HDC hdc) { HRGN hRGN = PInvokeCore.CreateRectRgn(0, 0, 0, 0); if (PInvokeCore.GetClipRgn(hdc, hRGN) == 1) Region = hRGN; else { PInvokeCore.DeleteObject(hRGN); Region = default(HRGN); } } [NullableContext(1)] public unsafe RegionScope(IPointer<GpRegion> region, IPointer<GpGraphics> graphics) { Region = default(HRGN); InitializeFromGdiPlus(region.GetPointer(), graphics.GetPointer()); GC.KeepAlive(region); GC.KeepAlive(graphics); } private unsafe void InitializeFromGdiPlus(GpRegion* region, GpGraphics* graphics) { BOOL value = default(BOOL); PInvokeCore.GdipIsInfiniteRegion(region, graphics, &value).ThrowIfFailed(); if ((bool)value) Region = default(HRGN); else { HRGN region2 = default(HRGN); PInvokeCore.GdipGetRegionHRgn(region, graphics, &region2).ThrowIfFailed(); Region = region2; } } [NullableContext(1)] public unsafe RegionScope(IPointer<GpRegion> region, HWND hwnd) { Region = default(HRGN); GpGraphics* graphics = null; PInvokeCore.GdipCreateFromHWND(hwnd, &graphics).ThrowIfFailed(); InitializeFromGdiPlus(region.GetPointer(), graphics); GC.KeepAlive(region); } public static implicit operator HRGN(RegionScope regionScope) { return regionScope.Region; } public void RelinquishOwnership() { Region = default(HRGN); } [IsReadOnly] public void Dispose() { if (!IsNull) PInvokeCore.DeleteObject(Region); } } }