Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove WindowsGraphics and DeviceContext #3553

Merged
merged 7 commits into from
Jul 18, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ internal static partial class Gdi32
/// </summary>
public CreateBrushScope(Color color)
{
HBrush = CreateSolidBrush(ColorTranslator.ToWin32(color));
}
HBrush = color.IsSystemColor
? User32.GetSysColorBrush(ColorTranslator.ToOle(color) & 0xFF)
: CreateSolidBrush(ColorTranslator.ToWin32(color));
}

public static implicit operator HBRUSH(in CreateBrushScope scope) => scope.HBrush;
public static implicit operator HGDIOBJ(in CreateBrushScope scope) => scope.HBrush;
Expand All @@ -37,6 +39,7 @@ public void Dispose()
{
if (!HBrush.IsNull)
{
// Note that this is a no-op if the original brush was a system brush
DeleteObject(HBrush);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,5 @@ internal static partial class Gdi32
{
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
public static extern HDC CreateCompatibleDC(HDC hDC);

public static HDC CreateCompatibleDC(HandleRef hDC)
{
HDC result = CreateCompatibleDC((HDC)hDC.Handle);
GC.KeepAlive(hDC.Wrapper);
return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public CreatePenScope(Color color, int width = 1)
}

public static implicit operator HPEN(in CreatePenScope scope) => scope.HPen;
public static implicit operator HGDIOBJ(in CreatePenScope scope) => scope.HPen;

public bool IsNull => HPen.IsNull;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Gdi32
{
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
public static extern RegionType GetClipBox(HDC hdc, ref RECT lprect);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,8 @@ public enum DeviceCapability : int
LOGPIXELSY = 90
}

[SuppressGCTransition]
[DllImport(Libraries.Gdi32, SetLastError = true, ExactSpelling = true)]
public static extern int GetDeviceCaps(HDC hDC, DeviceCapability nIndex);

public static int GetDeviceCaps(IHandle hDC, DeviceCapability nIndex)
{
int caps = GetDeviceCaps((HDC)hDC.Handle, nIndex);
GC.KeepAlive(hDC);
return caps;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,26 @@ public SelectPaletteScope(HDC hdc, HPALETTE hpalette, bool forceBackground, bool
}

public static SelectPaletteScope HalftonePalette(HDC hdc, bool forceBackground, bool realizePalette)
=> new SelectPaletteScope(hdc, (HPALETTE)Graphics.GetHalftonePalette(), forceBackground, realizePalette);
{
if (GetDeviceCaps(hdc, DeviceCapability.BITSPIXEL) > 8)
{
// https://docs.microsoft.com/windows/win32/api/Gdiplusgraphics/nf-gdiplusgraphics-graphics-gethalftonepalette
// The purpose of the Graphics::GetHalftonePalette method is to enable GDI+ to produce a better
// quality halftone when the display uses 8 bits per pixel. This method allocates a palette of
// 256 entries (each of which are 4 bytes a piece).
//
// Doing this is a bit pointless when the color depth is much higher (the normal scenario). As such
// we'll skip doing this unless we see 8bpp or less.

return default;
}

return new SelectPaletteScope(
hdc,
(HPALETTE)Graphics.GetHalftonePalette(),
forceBackground,
realizePalette);
}

public static implicit operator HPALETTE(in SelectPaletteScope paletteScope) => paletteScope.HPalette;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,30 @@ internal static partial class Gdi32
public HGDIOBJ PreviousObject { get; }

/// <summary>
/// Selects <paramref name="object"/> into the given <paramref name="hdc"/>.
/// Selects <paramref name="object"/> into the given <paramref name="hdc"/> using
/// <see cref="SelectObject(HDC, HGDIOBJ)"/>.
/// </summary>
public SelectObjectScope(HDC hdc, HGDIOBJ @object)
{
_hdc = hdc;
PreviousObject = SelectObject(hdc, @object);
// Selecting null doesn't mean anything

if (@object.IsNull)
{
this = default;
}
else
{
_hdc = hdc;
PreviousObject = SelectObject(hdc, @object);
}
}

public void Dispose()
{
SelectObject(_hdc, PreviousObject);
if (!_hdc.IsNull)
{
SelectObject(_hdc, PreviousObject);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Drawing;

internal static partial class Interop
{
internal static partial class Gdi32
{
/// <summary>
/// Helper to scope selecting a given background color into a HDC. Restores the original background color into
/// the HDC when disposed.
/// </summary>
/// <remarks>
/// Use in a <see langword="using" /> statement. If you must pass this around, always pass by
/// <see langword="ref" /> to avoid duplicating the handle and resetting multiple times.
/// </remarks>
internal readonly ref struct SetBackgroundColorScope
{
private readonly int _previousColor;
private readonly HDC _hdc;

/// <summary>
/// Sets text color <paramref name="color"/> in the given <paramref name="hdc"/> using
/// <see cref="SetBkColor(HDC, int)"/>.
/// </summary>
public SetBackgroundColorScope(HDC hdc, Color color)
{
int colorref = ColorTranslator.ToWin32(color);
_previousColor = SetBkColor(hdc, colorref);

// If we didn't actually change the color, don't keep the HDC so we skip putting back the same state.
_hdc = colorref == _previousColor ? default : hdc;
}

public void Dispose()
{
if (!_hdc.IsNull)
{
SetBkColor(_hdc, _previousColor);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Drawing;

internal static partial class Interop
{
internal static partial class Gdi32
{
/// <summary>
/// Helper to scope selecting a given mapping mode into a HDC. Restores the original mapping mode into the HDC
/// when disposed.
/// </summary>
/// <remarks>
/// Use in a <see langword="using" /> statement. If you must pass this around, always pass by
/// <see langword="ref" /> to avoid duplicating the handle and resetting multiple times.
/// </remarks>
internal readonly ref struct SetMapModeScope
{
private readonly MM _previousMapMode;
private readonly HDC _hdc;

/// <summary>
/// Sets the <paramref name="mapMode"/> in the given <paramref name="hdc"/> using
/// <see cref="SetMapMode(HDC, MM)"/>.
/// </summary>
public SetMapModeScope(HDC hdc, MM mapMode)
{
_previousMapMode = SetMapMode(hdc, mapMode);

// If we didn't actually change the map mode, don't keep the HDC so we skip putting back the same state.
_hdc = mapMode == _previousMapMode ? default : hdc;
}

public void Dispose()
{
if (!_hdc.IsNull)
{
SetMapMode(_hdc, _previousMapMode);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ internal static partial class Interop
internal static partial class Gdi32
{
/// <summary>
/// Helper to scope selecting a given foreground mix mode into a HDC. Restores the original
/// mix mode into the HDC when disposed.
/// Helper to scope selecting a given foreground mix mode into a HDC. Restores the original mix mode into the
/// HDC when disposed.
/// </summary>
/// <remarks>
/// Use in a <see langword="using" /> statement. If you must pass this around, always pass
/// by <see langword="ref" /> to avoid duplicating the handle and resetting multiple times.
/// Use in a <see langword="using" /> statement. If you must pass this around, always pass by
/// <see langword="ref" /> to avoid duplicating the handle and resetting multiple times.
/// </remarks>
internal readonly ref struct SetRop2Scope
{
private readonly R2 _previousRop;
private readonly HDC _hdc;

/// <summary>
/// Selects <paramref name="rop2"/> into the given <paramref name="hdc"/>.
/// Selects <paramref name="rop2"/> into the given <paramref name="hdc"/> using <see cref="SetROP2(HDC, R2)"/>.
/// </summary>
public SetRop2Scope(HDC hdc, R2 rop2)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ internal static partial class Interop
internal static partial class Gdi32
{
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
public static extern TA SetTextAlign(IntPtr hdc, TA align);
public static extern TA SetTextAlign(Gdi32.HDC hdc, TA align);

public static TA SetTextAlign(IHandle hdc, TA align)
{
TA result = SetTextAlign(hdc.Handle, align);
TA result = SetTextAlign((Gdi32.HDC)hdc.Handle, align);
GC.KeepAlive(hdc);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;

internal static partial class Interop
{
internal static partial class Gdi32
{
/// <summary>
/// Helper to scope selecting a given text alignment mode into a HDC. Restores the original text alignment
/// mode into the HDC when disposed.
/// </summary>
/// <remarks>
/// Use in a <see langword="using" /> statement. If you must pass this around, always pass by
/// <see langword="ref" /> to avoid duplicating the handle and resetting multiple times.
/// </remarks>
internal readonly ref struct SetTextAlignmentScope
{
private readonly TA _previousTa;
private readonly HDC _hdc;

/// <summary>
/// Sets <paramref name="ta"/> in the given <paramref name="hdc"/> using <see cref="SetTextAlign(HDC, TA)"/>.
/// </summary>
public SetTextAlignmentScope(HDC hdc, TA ta)
{
_previousTa = SetTextAlign(hdc, ta);

// If we didn't actually change the TA, don't keep the HDC so we skip putting back the same state.
_hdc = _previousTa == ta ? default : hdc;
}

public void Dispose()
{
if (!_hdc.IsNull)
{
SetTextAlign(_hdc, _previousTa);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Drawing;

internal static partial class Interop
{
internal static partial class Gdi32
{
/// <summary>
/// Helper to scope selecting a given foreground text color into a HDC. Restores the original text color into
/// into the HDC when disposed.
/// </summary>
/// <remarks>
/// Use in a <see langword="using" /> statement. If you must pass this around, always pass by
/// <see langword="ref" /> to avoid duplicating the handle and resetting multiple times.
/// </remarks>
internal readonly ref struct SetTextColorScope
{
private readonly int _previousColor;
private readonly HDC _hdc;

/// <summary>
/// Sets text color <paramref name="color"/> in the given <paramref name="hdc"/> using
/// <see cref="SetTextColor(HDC, int)"/>.
/// </summary>
public SetTextColorScope(HDC hdc, Color color)
{
int colorref = ColorTranslator.ToWin32(color);
_previousColor = SetTextColor(hdc, colorref);

// If we didn't actually change the color, don't keep the HDC so we skip putting back the same state.
_hdc = colorref == _previousColor ? default : hdc;
}

public void Dispose()
{
if (!_hdc.IsNull)
{
SetTextColor(_hdc, _previousColor);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

internal static partial class Interop
{
internal static partial class User32
{
[DllImport(Libraries.User32, ExactSpelling = true)]
public static extern BOOL DrawIconEx(
IntPtr hDC,
Gdi32.HDC hDC,
int xLeft,
int yTop,
IntPtr hIcon,
Expand All @@ -23,7 +22,7 @@ internal static partial class User32
DI diFlags);

public static BOOL DrawIconEx(
IntPtr hDC,
Gdi32.HDC hDC,
int xLeft,
int yTop,
IHandle hIcon,
Expand All @@ -43,7 +42,7 @@ internal static partial class User32
int cxWidth,
int cyWidth)
{
BOOL result = DrawIconEx(hDC.Handle, xLeft, yTop, hIcon.Handle, cxWidth, cyWidth, 0, IntPtr.Zero, DI.NORMAL);
BOOL result = DrawIconEx((Gdi32.HDC)hDC.Handle, xLeft, yTop, hIcon.Handle, cxWidth, cyWidth, 0, IntPtr.Zero, DI.NORMAL);
GC.KeepAlive(hIcon);
GC.KeepAlive(hDC);
return result;
Expand Down