зеркало из https://github.com/dotnet/winforms.git
Add more HGDIOBJ handles and scopes (#3528)
This cuts a number of uneccesary allocations and sets up to remove much more. The goal is to remove WindowsGraphics and DeviceContext (and other related classes) which are extremely slow and allocate a lot. Getting rid of these classes will also improve code clarity. - Introduce more scopes and handle extensions to move away from DeviceContext, WindowsGraphics, etc. - Introduce HDC, HFONT, HBRUSH, HPEN and other HGDIOBJ objects - Add IHandle to DeviceContext, WindowsGraphics for the HDC - Add IHandle to WindowsBrush for the HBRUSH - Add a referemce to this to the end of message processing to root Control - Remove MarshalByRefObject from internal classes - Improve perf of background drawing - Move ApplyGraphicProperties to Primitives - Cut dead code - Note: Did not change COM interface defintions
This commit is contained in:
Родитель
4c1c9d66bb
Коммит
dfd8105aa6
|
@ -12,7 +12,6 @@ using System.Drawing.Drawing2D;
|
|||
using System.Drawing.Imaging;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Forms.Design;
|
||||
|
@ -1937,6 +1936,7 @@ namespace System.ComponentModel.Design
|
|||
IntegralHeight = false,
|
||||
Font = ActionPanel.Font
|
||||
};
|
||||
|
||||
listBox.KeyDown += new KeyEventHandler(OnListBoxKeyDown);
|
||||
TypeConverter.StandardValuesCollection standardValues = GetStandardValues();
|
||||
if (standardValues != null)
|
||||
|
@ -1955,20 +1955,22 @@ namespace System.ComponentModel.Design
|
|||
|
||||
// All measurement code borrowed from WinForms PropertyGridView.cs
|
||||
int maxWidth = 0;
|
||||
|
||||
// The listbox draws with GDI, not GDI+. So, we use a normal DC here.
|
||||
IntPtr hdc = User32.GetDC(new HandleRef(listBox, listBox.Handle));
|
||||
IntPtr hFont = listBox.Font.ToHfont();
|
||||
var tm = new Gdi32.TEXTMETRICW();
|
||||
try
|
||||
using (var hdc = new User32.GetDcScope(listBox.Handle))
|
||||
{
|
||||
hFont = Gdi32.SelectObject(hdc, hFont);
|
||||
using var hFont = new Gdi32.ObjectScope(listBox.Font.ToHFONT());
|
||||
using var fontSelection = new Gdi32.SelectObjectScope(hdc, hFont);
|
||||
|
||||
var tm = new Gdi32.TEXTMETRICW();
|
||||
|
||||
if (listBox.Items.Count > 0)
|
||||
{
|
||||
foreach (string s in listBox.Items)
|
||||
{
|
||||
var textSize = new Size();
|
||||
Gdi32.GetTextExtentPoint32W(new HandleRef(listBox, hdc), s, s.Length, ref textSize);
|
||||
maxWidth = Math.Max((int)textSize.Width, maxWidth);
|
||||
Gdi32.GetTextExtentPoint32W(hdc, s, s.Length, ref textSize);
|
||||
maxWidth = Math.Max(textSize.Width, maxWidth);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1976,17 +1978,12 @@ namespace System.ComponentModel.Design
|
|||
|
||||
// border + padding + scrollbar
|
||||
maxWidth += 2 + tm.tmMaxCharWidth + SystemInformation.VerticalScrollBarWidth;
|
||||
hFont = Gdi32.SelectObject(hdc, hFont);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Gdi32.DeleteObject(hFont);
|
||||
User32.ReleaseDC(new HandleRef(listBox, listBox.Handle), hdc);
|
||||
|
||||
listBox.Height = Math.Max(tm.tmHeight + 2, Math.Min(ListBoxMaximumHeight, listBox.PreferredHeight));
|
||||
listBox.Width = Math.Max(maxWidth, EditRegionSize.Width);
|
||||
_ignoreDropDownValue = false;
|
||||
}
|
||||
|
||||
listBox.Height = Math.Max(tm.tmHeight + 2, Math.Min(ListBoxMaximumHeight, listBox.PreferredHeight));
|
||||
listBox.Width = Math.Max(maxWidth, EditRegionSize.Width);
|
||||
_ignoreDropDownValue = false;
|
||||
try
|
||||
{
|
||||
ShowDropDown(listBox, SystemColors.ControlDark);
|
||||
|
|
|
@ -227,7 +227,7 @@ namespace System.ComponentModel.Design
|
|||
get
|
||||
{
|
||||
using var hdc = User32.GetDcScope.ScreenDC;
|
||||
using var font = new Gdi32.ObjectScope(Font.ToHfont());
|
||||
using var font = new Gdi32.ObjectScope(Font.ToHFONT());
|
||||
using var fontSelection = new Gdi32.SelectObjectScope(hdc, font);
|
||||
|
||||
RECT rect = new RECT();
|
||||
|
|
|
@ -11,7 +11,6 @@ using System.Drawing;
|
|||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms.Design.Behavior;
|
||||
using static Interop;
|
||||
|
||||
|
@ -28,10 +27,10 @@ namespace System.Windows.Forms.Design
|
|||
//brush used to draw the resizeable selection borders around controls/components
|
||||
private static HatchBrush s_selectionBorderBrush = new HatchBrush(HatchStyle.Percent50, SystemColors.ControlDarkDark, Color.Transparent);
|
||||
//Pens and Brushes used via GDI to render our grabhandles
|
||||
private static IntPtr s_grabHandleFillBrushPrimary = Gdi32.CreateSolidBrush(ColorTranslator.ToWin32(SystemColors.Window));
|
||||
private static IntPtr s_grabHandleFillBrush = Gdi32.CreateSolidBrush(ColorTranslator.ToWin32(SystemColors.ControlText));
|
||||
private static IntPtr s_grabHandlePenPrimary = Gdi32.CreatePen(Gdi32.PS.SOLID, 1, ColorTranslator.ToWin32(SystemColors.ControlText));
|
||||
private static IntPtr s_grabHandlePen = Gdi32.CreatePen(Gdi32.PS.SOLID, 1, ColorTranslator.ToWin32(SystemColors.Window));
|
||||
private static Gdi32.HBRUSH s_grabHandleFillBrushPrimary = Gdi32.CreateSolidBrush(ColorTranslator.ToWin32(SystemColors.Window));
|
||||
private static Gdi32.HBRUSH s_grabHandleFillBrush = Gdi32.CreateSolidBrush(ColorTranslator.ToWin32(SystemColors.ControlText));
|
||||
private static Gdi32.HPEN s_grabHandlePenPrimary = Gdi32.CreatePen(Gdi32.PS.SOLID, 1, ColorTranslator.ToWin32(SystemColors.ControlText));
|
||||
private static Gdi32.HPEN s_grabHandlePen = Gdi32.CreatePen(Gdi32.PS.SOLID, 1, ColorTranslator.ToWin32(SystemColors.Window));
|
||||
|
||||
//The box-like image used as the user is dragging comps from the toolbox
|
||||
private static Bitmap s_boxImage = null;
|
||||
|
@ -282,24 +281,14 @@ namespace System.Windows.Forms.Design
|
|||
/// </summary>
|
||||
public static void DrawGrabHandle(Graphics graphics, Rectangle bounds, bool isPrimary, Glyph glyph)
|
||||
{
|
||||
IntPtr hDC = graphics.GetHdc();
|
||||
try
|
||||
{
|
||||
//set our pen and brush based on primary selection
|
||||
IntPtr oldBrush = Gdi32.SelectObject(hDC, isPrimary ? s_grabHandleFillBrushPrimary : s_grabHandleFillBrush);
|
||||
IntPtr oldPen = Gdi32.SelectObject(hDC, isPrimary ? s_grabHandlePenPrimary : s_grabHandlePen);
|
||||
using var hDC = new DeviceContextHdcScope(graphics);
|
||||
|
||||
//draw our rounded rect grabhandle
|
||||
Gdi32.RoundRect(hDC, bounds.Left, bounds.Top, bounds.Right, bounds.Bottom, 2, 2);
|
||||
// Set our pen and brush based on primary selection
|
||||
using var brushSelection = new Gdi32.SelectObjectScope(hDC, isPrimary ? s_grabHandleFillBrushPrimary : s_grabHandleFillBrush);
|
||||
using var penSelection = new Gdi32.SelectObjectScope(hDC, isPrimary ? s_grabHandlePenPrimary : s_grabHandlePen);
|
||||
|
||||
//restore old pen and brush
|
||||
Gdi32.SelectObject(hDC, oldBrush);
|
||||
Gdi32.SelectObject(hDC, oldPen);
|
||||
}
|
||||
finally
|
||||
{
|
||||
graphics.ReleaseHdcInternal(hDC);
|
||||
}
|
||||
// Draw our rounded rect grabhandle
|
||||
Gdi32.RoundRect(hDC, bounds.Left, bounds.Top, bounds.Right, bounds.Bottom, 2, 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -307,23 +296,14 @@ namespace System.Windows.Forms.Design
|
|||
/// </summary>
|
||||
public static void DrawNoResizeHandle(Graphics graphics, Rectangle bounds, bool isPrimary, Glyph glyph)
|
||||
{
|
||||
IntPtr hDC = graphics.GetHdc();
|
||||
try
|
||||
{
|
||||
//set our pen and brush based on primary selection
|
||||
IntPtr oldBrush = Gdi32.SelectObject(hDC, isPrimary ? s_grabHandleFillBrushPrimary : s_grabHandleFillBrush);
|
||||
IntPtr oldPen = Gdi32.SelectObject(hDC, s_grabHandlePenPrimary);
|
||||
using var hDC = new DeviceContextHdcScope(graphics);
|
||||
|
||||
//draw our rect no-resize handle
|
||||
Gdi32.Rectangle(hDC, bounds.Left, bounds.Top, bounds.Right, bounds.Bottom);
|
||||
//restore old pen and brush
|
||||
Gdi32.SelectObject(hDC, oldBrush);
|
||||
Gdi32.SelectObject(hDC, oldPen);
|
||||
}
|
||||
finally
|
||||
{
|
||||
graphics.ReleaseHdcInternal(hDC);
|
||||
}
|
||||
// Set our pen and brush based on primary selection
|
||||
using var brushSelection = new Gdi32.SelectObjectScope(hDC, isPrimary ? s_grabHandleFillBrushPrimary : s_grabHandleFillBrush);
|
||||
using var penSelection = new Gdi32.SelectObjectScope(hDC, s_grabHandlePenPrimary);
|
||||
|
||||
// Draw our rect no-resize handle
|
||||
Gdi32.Rectangle(hDC, bounds.Left, bounds.Top, bounds.Right, bounds.Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -331,26 +311,17 @@ namespace System.Windows.Forms.Design
|
|||
/// </summary>
|
||||
public static void DrawLockedHandle(Graphics graphics, Rectangle bounds, bool isPrimary, Glyph glyph)
|
||||
{
|
||||
IntPtr hDC = graphics.GetHdc();
|
||||
try
|
||||
{
|
||||
IntPtr oldPen = Gdi32.SelectObject(hDC, s_grabHandlePenPrimary);
|
||||
// Upper rect - upper rect is always filled with the primary brush
|
||||
IntPtr oldBrush = Gdi32.SelectObject(hDC, s_grabHandleFillBrushPrimary);
|
||||
Gdi32.RoundRect(hDC, bounds.Left + LOCKHANDLEUPPER_OFFSET, bounds.Top, bounds.Left + LOCKHANDLEUPPER_OFFSET + LOCKHANDLESIZE_UPPER, bounds.Top + LOCKHANDLESIZE_UPPER, 2, 2);
|
||||
using var hDC = new DeviceContextHdcScope(graphics);
|
||||
|
||||
// Lower rect - its fillbrush depends on the primary selection
|
||||
Gdi32.SelectObject(hDC, isPrimary ? s_grabHandleFillBrushPrimary : s_grabHandleFillBrush);
|
||||
Gdi32.Rectangle(hDC, bounds.Left, bounds.Top + LOCKHANDLELOWER_OFFSET, bounds.Right, bounds.Bottom);
|
||||
using var penSelection = new Gdi32.SelectObjectScope(hDC, s_grabHandlePenPrimary);
|
||||
|
||||
//restore old pen and brush
|
||||
Gdi32.SelectObject(hDC, oldBrush);
|
||||
Gdi32.SelectObject(hDC, oldPen);
|
||||
}
|
||||
finally
|
||||
{
|
||||
graphics.ReleaseHdcInternal(hDC);
|
||||
}
|
||||
// Upper rect - upper rect is always filled with the primary brush
|
||||
using var brushSelection = new Gdi32.SelectObjectScope(hDC, s_grabHandleFillBrushPrimary);
|
||||
Gdi32.RoundRect(hDC, bounds.Left + LOCKHANDLEUPPER_OFFSET, bounds.Top, bounds.Left + LOCKHANDLEUPPER_OFFSET + LOCKHANDLESIZE_UPPER, bounds.Top + LOCKHANDLESIZE_UPPER, 2, 2);
|
||||
|
||||
// Lower rect - its fillbrush depends on the primary selection
|
||||
Gdi32.SelectObject(hDC, isPrimary ? s_grabHandleFillBrushPrimary : s_grabHandleFillBrush);
|
||||
Gdi32.Rectangle(hDC, bounds.Left, bounds.Top + LOCKHANDLELOWER_OFFSET, bounds.Right, bounds.Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -455,39 +426,33 @@ namespace System.Windows.Forms.Design
|
|||
/// </summary>
|
||||
public static void GenerateSnapShotWithBitBlt(Control control, ref Image image)
|
||||
{
|
||||
//get the DC's and create our image
|
||||
HandleRef hWnd = new HandleRef(control, control.Handle);
|
||||
IntPtr controlDC = User32.GetDC(hWnd);
|
||||
image = new Bitmap(Math.Max(control.Width, MINCONTROLBITMAPSIZE), Math.Max(control.Height, MINCONTROLBITMAPSIZE), PixelFormat.Format32bppPArgb);
|
||||
// Get the DC's and create our image
|
||||
using var controlDC = new User32.GetDcScope(control.Handle);
|
||||
image = new Bitmap(
|
||||
Math.Max(control.Width, MINCONTROLBITMAPSIZE),
|
||||
Math.Max(control.Height, MINCONTROLBITMAPSIZE),
|
||||
PixelFormat.Format32bppPArgb);
|
||||
|
||||
using (Graphics gDest = Graphics.FromImage(image))
|
||||
using Graphics gDest = Graphics.FromImage(image);
|
||||
|
||||
if (control.BackColor == Color.Transparent)
|
||||
{
|
||||
if (control.BackColor == Color.Transparent)
|
||||
{
|
||||
gDest.Clear(SystemColors.Control);
|
||||
}
|
||||
|
||||
IntPtr destDC = gDest.GetHdc();
|
||||
try
|
||||
{
|
||||
// Perform our bitblit operation to push the image into the dest bitmap
|
||||
Gdi32.BitBlt(
|
||||
destDC,
|
||||
0,
|
||||
0,
|
||||
image.Width,
|
||||
image.Height,
|
||||
controlDC,
|
||||
0,
|
||||
0,
|
||||
Gdi32.ROP.SRCCOPY);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Clean up all our handles and what not
|
||||
gDest.ReleaseHdc(destDC);
|
||||
}
|
||||
gDest.Clear(SystemColors.Control);
|
||||
}
|
||||
|
||||
using var destDC = new DeviceContextHdcScope(gDest);
|
||||
|
||||
// Perform our bitblit operation to push the image into the dest bitmap
|
||||
Gdi32.BitBlt(
|
||||
destDC,
|
||||
0,
|
||||
0,
|
||||
image.Width,
|
||||
image.Height,
|
||||
controlDC,
|
||||
0,
|
||||
0,
|
||||
Gdi32.ROP.SRCCOPY);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -613,29 +578,20 @@ namespace System.Windows.Forms.Design
|
|||
//get the font metrics via gdi
|
||||
int fontAscent = 0;
|
||||
int fontHeight = 0;
|
||||
using (Graphics g = ctrl.CreateGraphics())
|
||||
{
|
||||
IntPtr dc = g.GetHdc();
|
||||
IntPtr hFont = ctrl.Font.ToHfont();
|
||||
IntPtr hFontOld;
|
||||
try
|
||||
{
|
||||
hFontOld = Gdi32.SelectObject(dc, hFont);
|
||||
var metrics = new Gdi32.TEXTMETRICW();
|
||||
Gdi32.GetTextMetricsW(new HandleRef(ctrl, dc), ref metrics);
|
||||
//add the font ascent to the baseline
|
||||
fontAscent = metrics.tmAscent + 1;
|
||||
fontHeight = metrics.tmHeight;
|
||||
Gdi32.SelectObject(dc, hFontOld);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Gdi32.DeleteObject(hFont);
|
||||
g.ReleaseHdc(dc);
|
||||
}
|
||||
}
|
||||
|
||||
//now add it all up
|
||||
using Graphics g = ctrl.CreateGraphics();
|
||||
using var dc = new DeviceContextHdcScope(g);
|
||||
using var hFont = new Gdi32.ObjectScope(ctrl.Font.ToHFONT());
|
||||
using var hFontOld = new Gdi32.SelectObjectScope(dc, hFont);
|
||||
|
||||
var metrics = new Gdi32.TEXTMETRICW();
|
||||
Gdi32.GetTextMetricsW(dc, ref metrics);
|
||||
|
||||
// Add the font ascent to the baseline
|
||||
fontAscent = metrics.tmAscent + 1;
|
||||
fontHeight = metrics.tmHeight;
|
||||
|
||||
// Now add it all up
|
||||
if ((alignment & anyTopAlignment) != 0)
|
||||
{
|
||||
return face.Top + fontAscent;
|
||||
|
|
|
@ -10,8 +10,8 @@ internal partial class Interop
|
|||
{
|
||||
public struct IMAGEINFO
|
||||
{
|
||||
public IntPtr hbmImage;
|
||||
public IntPtr hbmMask;
|
||||
public Gdi32.HBITMAP hbmImage;
|
||||
public Gdi32.HBITMAP hbmMask;
|
||||
public int Unused1;
|
||||
public int Unused2;
|
||||
public RECT rcImage;
|
||||
|
|
|
@ -13,9 +13,9 @@ internal partial class Interop
|
|||
public static partial class ImageList
|
||||
{
|
||||
[DllImport(Libraries.Comctl32, ExactSpelling = true, EntryPoint = "ImageList_Add")]
|
||||
public static extern int Add(IntPtr himl, IntPtr hbmImage, IntPtr hbmMask);
|
||||
public static extern int Add(IntPtr himl, Gdi32.HBITMAP hbmImage, Gdi32.HBITMAP hbmMask);
|
||||
|
||||
public static int Add(IHandle himl, IntPtr hbmImage, IntPtr hbmMask)
|
||||
public static int Add(IHandle himl, Gdi32.HBITMAP hbmImage, Gdi32.HBITMAP hbmMask)
|
||||
{
|
||||
int result = Add(himl.Handle, hbmImage, hbmMask);
|
||||
GC.KeepAlive(himl);
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
internal partial class Interop
|
||||
{
|
||||
|
@ -13,9 +12,9 @@ internal partial class Interop
|
|||
public static partial class ImageList
|
||||
{
|
||||
[DllImport(Libraries.Comctl32, ExactSpelling = true, EntryPoint = "ImageList_Draw")]
|
||||
public static extern BOOL Draw(IntPtr himl, int i, IntPtr hdcDst, int x, int y, ILD fStyle);
|
||||
public static extern BOOL Draw(IntPtr himl, int i, Gdi32.HDC hdcDst, int x, int y, ILD fStyle);
|
||||
|
||||
public static BOOL Draw(IHandle himl, int i, IntPtr hdcDst, int x, int y, ILD fStyle)
|
||||
public static BOOL Draw(IHandle himl, int i, Gdi32.HDC hdcDst, int x, int y, ILD fStyle)
|
||||
{
|
||||
BOOL result = Draw(himl.Handle, i, hdcDst, x, y, fStyle);
|
||||
GC.KeepAlive(himl);
|
||||
|
|
|
@ -12,7 +12,7 @@ internal static partial class Interop
|
|||
{
|
||||
public User32.NMHDR nmcd;
|
||||
public CDDS dwDrawStage;
|
||||
public IntPtr hdc;
|
||||
public Gdi32.HDC hdc;
|
||||
public RECT rc;
|
||||
public IntPtr dwItemSpec;
|
||||
public CDIS uItemState;
|
||||
|
|
|
@ -11,40 +11,65 @@ internal static partial class Interop
|
|||
{
|
||||
[DllImport(Libraries.Gdi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
|
||||
public static extern BOOL BitBlt(
|
||||
IntPtr hdc,
|
||||
HDC hdc,
|
||||
int x,
|
||||
int y,
|
||||
int cx,
|
||||
int cy,
|
||||
IntPtr hdcSrc,
|
||||
HDC hdcSrc,
|
||||
int x1,
|
||||
int y1,
|
||||
ROP rop);
|
||||
|
||||
public static BOOL BitBlt(
|
||||
HandleRef hdc,
|
||||
IHandle hdc,
|
||||
int x,
|
||||
int y,
|
||||
int cx,
|
||||
int cy,
|
||||
HandleRef hdcSrc,
|
||||
HDC hdcSrc,
|
||||
int x1,
|
||||
int y1,
|
||||
ROP rop)
|
||||
{
|
||||
BOOL result = BitBlt(
|
||||
hdc.Handle,
|
||||
(HDC)hdc.Handle,
|
||||
x,
|
||||
y,
|
||||
cx,
|
||||
cy,
|
||||
hdcSrc.Handle,
|
||||
hdcSrc,
|
||||
x1,
|
||||
y1,
|
||||
rop
|
||||
);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
GC.KeepAlive(hdcSrc.Wrapper);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static BOOL BitBlt(
|
||||
HDC hdc,
|
||||
int x,
|
||||
int y,
|
||||
int cx,
|
||||
int cy,
|
||||
IHandle hdcSrc,
|
||||
int x1,
|
||||
int y1,
|
||||
ROP rop)
|
||||
{
|
||||
BOOL result = BitBlt(
|
||||
hdc,
|
||||
x,
|
||||
y,
|
||||
cx,
|
||||
cy,
|
||||
(HDC)hdcSrc.Handle,
|
||||
x1,
|
||||
y1,
|
||||
rop
|
||||
);
|
||||
GC.KeepAlive(hdcSrc);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static unsafe extern IntPtr CreateBitmap(int nWidth, int nHeight, uint nPlanes, uint nBitCount, void* lpvBits);
|
||||
public static unsafe extern HBITMAP CreateBitmap(int nWidth, int nHeight, uint nPlanes, uint nBitCount, void* lpvBits);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
// 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 lifetime of a <see cref="HBITMAP"/> created via <see cref="CreateBitmap"/>
|
||||
/// Deletes the <see cref="HBITMAP"/> (if any) 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 risking a double delete.
|
||||
/// </remarks>
|
||||
public ref struct CreateBitmapScope
|
||||
{
|
||||
public HBITMAP HBitmap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a bitmap using <see cref="CreateBitmap"/>
|
||||
/// </summary>
|
||||
public unsafe CreateBitmapScope(int nWidth, int nHeight, uint nPlanes, uint nBitCount, void* lpvBits)
|
||||
{
|
||||
HBitmap = CreateBitmap(nWidth, nHeight, nPlanes, nBitCount, lpvBits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a bitmap compatible with the given <see cref="HDC"/> via <see cref="CreateCompatibleBitmap"/>
|
||||
/// </summary>
|
||||
public CreateBitmapScope(HDC hdc, int cx, int cy)
|
||||
{
|
||||
HBitmap = CreateCompatibleBitmap(hdc, cx, cy);
|
||||
}
|
||||
|
||||
public static implicit operator HBITMAP(CreateBitmapScope scope) => scope.HBitmap;
|
||||
public static implicit operator HGDIOBJ(CreateBitmapScope scope) => scope.HBitmap;
|
||||
public static explicit operator IntPtr(CreateBitmapScope scope) => scope.HBitmap.Handle;
|
||||
|
||||
public bool IsNull => HBitmap.IsNull;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!HBitmap.IsNull)
|
||||
{
|
||||
DeleteObject(HBitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr CreateBrushIndirect(ref LOGBRUSH lb);
|
||||
public static extern HBRUSH CreateBrushIndirect(ref LOGBRUSH lb);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
// 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 the lifetime of a <see cref="HBRUSH"/>.
|
||||
/// </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 risking a double delete.
|
||||
/// </remarks>
|
||||
public ref struct CreateBrushScope
|
||||
{
|
||||
public HBRUSH HBrush { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a solid brush based on the <paramref name="color"/> using <see cref="CreateSolidBrush(int)"/>.
|
||||
/// </summary>
|
||||
public CreateBrushScope(Color color)
|
||||
{
|
||||
HBrush = CreateSolidBrush(ColorTranslator.ToWin32(color));
|
||||
}
|
||||
|
||||
public static implicit operator HBRUSH(CreateBrushScope scope) => scope.HBrush;
|
||||
public static implicit operator HGDIOBJ(CreateBrushScope scope) => scope.HBrush;
|
||||
|
||||
public bool IsNull => HBrush.IsNull;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!HBrush.IsNull)
|
||||
{
|
||||
DeleteObject(HBrush);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,13 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int cx, int cy);
|
||||
|
||||
public static IntPtr CreateCompatibleBitmap(HandleRef hdc, int cx, int cy)
|
||||
{
|
||||
IntPtr result = CreateCompatibleBitmap(hdc.Handle, cx, cy);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
return result;
|
||||
}
|
||||
public static extern HBITMAP CreateCompatibleBitmap(HDC hdc, int cx, int cy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
|
||||
public static extern HDC CreateCompatibleDC(HDC hDC);
|
||||
|
||||
public static IntPtr CreateCompatibleDC(HandleRef hDC)
|
||||
public static HDC CreateCompatibleDC(HandleRef hDC)
|
||||
{
|
||||
IntPtr result = CreateCompatibleDC(hDC.Handle);
|
||||
HDC result = CreateCompatibleDC((HDC)hDC.Handle);
|
||||
GC.KeepAlive(hDC.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,10 +10,10 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
/// <remarks>
|
||||
/// Use <see cref="DeleteDC(IntPtr)"/> when finished with the returned DC.
|
||||
/// Use <see cref="DeleteDC(HDC)"/> when finished with the returned DC.
|
||||
/// Calling with ("DISPLAY", null, null, IntPtr.Zero) will retrieve a DC for the entire desktop.
|
||||
/// </remarks>
|
||||
[DllImport(Libraries.Gdi32, SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr CreateDC(string lpszDriver, string? lpszDeviceName, string? lpszOutput, IntPtr devMode);
|
||||
public static extern HDC CreateDC(string lpszDriver, string? lpszDeviceName, string? lpszOutput, IntPtr devMode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern IntPtr CreateDIBSection(IntPtr hdc, IntPtr pbmi, DIB usage, byte[] ppvBits, IntPtr hSection, uint offset);
|
||||
public static extern HBITMAP CreateDIBSection(HDC hdc, IntPtr pbmi, DIB usage, byte[] ppvBits, IntPtr hSection, uint offset);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,19 +18,40 @@ internal static partial class Interop
|
|||
/// </remarks>
|
||||
public ref struct CreateDcScope
|
||||
{
|
||||
public IntPtr HDC { get; }
|
||||
public HDC HDC { get; }
|
||||
|
||||
/// <param name="hdc">Creates a compatible DC based off this.</param>
|
||||
public CreateDcScope(IntPtr hdc)
|
||||
/// <summary>
|
||||
/// Creates a compatible HDC for <paramref name="hdc"/> using <see cref="CreateCompatibleDC(HDC)"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Passing a null HDC will use the current screen.
|
||||
/// </remarks>
|
||||
public CreateDcScope(HDC hdc)
|
||||
{
|
||||
HDC = CreateCompatibleDC(hdc);
|
||||
}
|
||||
|
||||
public static implicit operator IntPtr(CreateDcScope dcScope) => dcScope.HDC;
|
||||
public CreateDcScope(
|
||||
string lpszDriverName,
|
||||
string? lpszDeviceName = null,
|
||||
string? lpszOutput = null,
|
||||
IntPtr lpInitData = default,
|
||||
bool informationOnly = true)
|
||||
{
|
||||
HDC = informationOnly
|
||||
? CreateICW(lpszDriverName, lpszDeviceName, lpszOutput, lpInitData)
|
||||
: CreateDC(lpszDriverName, lpszDeviceName, lpszOutput, lpInitData);
|
||||
}
|
||||
|
||||
public static implicit operator HDC(CreateDcScope dcScope) => dcScope.HDC;
|
||||
public static implicit operator HGDIOBJ(CreateDcScope dcScope) => dcScope.HDC;
|
||||
public static explicit operator IntPtr(CreateDcScope dcScope) => dcScope.HDC.Handle;
|
||||
|
||||
public bool IsNull => HDC.IsNull;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (HDC != IntPtr.Zero)
|
||||
if (!HDC.IsNull)
|
||||
{
|
||||
DeleteDC(HDC);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern IntPtr CreateFontIndirectW(ref User32.LOGFONTW lplf);
|
||||
public static extern HFONT CreateFontIndirectW(ref User32.LOGFONTW lplf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern IntPtr CreateHalftonePalette(IntPtr hdc);
|
||||
public static extern HPALETTE CreateHalftonePalette(HDC hdc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern unsafe IntPtr CreateICW(char* lpszDriverName, char* lpszDeviceName, char* lpszOutput, IntPtr /*DEVMODE*/ lpInitData);
|
||||
private static extern unsafe HDC CreateICW(char* lpszDriverName, char* lpszDeviceName, char* lpszOutput, IntPtr /*DEVMODE*/ lpInitData);
|
||||
|
||||
public static unsafe IntPtr CreateICW(string lpszDriverName, string lpszDeviceName, string lpszOutput, IntPtr /*DEVMODE*/ lpInitData)
|
||||
public static unsafe HDC CreateICW(string lpszDriverName, string? lpszDeviceName, string? lpszOutput, IntPtr /*DEVMODE*/ lpInitData)
|
||||
{
|
||||
fixed (char* driverName = lpszDriverName)
|
||||
fixed (char* deviceName = lpszDeviceName)
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr CreatePatternBrush(IntPtr hbm);
|
||||
public static extern HBRUSH CreatePatternBrush(HBITMAP hbm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern IntPtr CreatePen(PS nStyle, int nWidth, int crColor);
|
||||
public static extern HPEN CreatePen(PS nStyle, int nWidth, int crColor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// 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 the lifetime of a <see cref="HPEN"/>.
|
||||
/// </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 risking a double delete.
|
||||
/// </remarks>
|
||||
public ref struct CreatePenScope
|
||||
{
|
||||
public HPEN HPen { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a solid pen based on the <paramref name="color"/> and <paramref name="width"/>.
|
||||
/// </summary>
|
||||
public CreatePenScope(Color color, int width = 1)
|
||||
{
|
||||
// From MSDN: if width > 1, the style must be PS_NULL, PS_SOLID, or PS_INSIDEFRAME.
|
||||
HPen = CreatePen(
|
||||
width > 1 ? PS.GEOMETRIC | PS.SOLID : default,
|
||||
width,
|
||||
ColorTranslator.ToWin32(color));
|
||||
}
|
||||
|
||||
public static implicit operator HPEN(CreatePenScope scope) => scope.HPen;
|
||||
|
||||
public bool IsNull => HPen.IsNull;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!HPen.IsNull)
|
||||
{
|
||||
DeleteObject(HPen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr CreateSolidBrush(int crColor);
|
||||
public static extern HBRUSH CreateSolidBrush(int crColor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, SetLastError = true, ExactSpelling = true)]
|
||||
public static extern BOOL DeleteDC(IntPtr hDC);
|
||||
public static extern BOOL DeleteDC(Gdi32.HDC hDC);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public unsafe static extern IntPtr ExtCreatePen(PS fnStyle, int dwWidth, ref LOGBRUSH lplb, uint dwStyleCount, uint* lpStyle);
|
||||
public unsafe static extern HPEN ExtCreatePen(PS fnStyle, int dwWidth, ref LOGBRUSH lplb, uint dwStyleCount, uint* lpStyle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = false, CharSet = CharSet.Unicode)]
|
||||
public unsafe static extern BOOL ExtTextOutW(IntPtr hdc, int x, int y, ETO options, ref RECT lprect, string lpString, int c, int* lpDx);
|
||||
public unsafe static extern BOOL ExtTextOutW(HDC hdc, int x, int y, ETO options, ref RECT lprect, string lpString, int c, int* lpDx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern int GetBkColor(IntPtr hdc);
|
||||
public static extern int GetBkColor(HDC hdc);
|
||||
|
||||
public static int GetBkColor(IHandle hdc)
|
||||
{
|
||||
int result = GetBkColor(hdc.Handle);
|
||||
int result = GetBkColor((HDC)hdc.Handle);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern int GetClipRgn(IntPtr hdc, HRGN hrgn);
|
||||
public static extern int GetClipRgn(HDC hdc, HRGN hrgn);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern IntPtr GetCurrentObject(IntPtr hdc, ObjectType type);
|
||||
public static extern HGDIOBJ GetCurrentObject(HDC hdc, ObjectType type);
|
||||
|
||||
public static IntPtr GetCurrentObject(HandleRef hdc, ObjectType type)
|
||||
public static HGDIOBJ GetCurrentObject(IHandle hdc, ObjectType type)
|
||||
{
|
||||
IntPtr result = GetCurrentObject(hdc.Handle, type);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
HGDIOBJ result = GetCurrentObject((HDC)hdc.Handle, type);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,13 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32)]
|
||||
public static extern int GetDIBits(IntPtr hdc, IntPtr hbm, uint start, uint cLines, byte[] lpvBits, ref BITMAPINFO lpbmi, DIB usage);
|
||||
public static extern int GetDIBits(
|
||||
HDC hdc,
|
||||
HBITMAP hbm,
|
||||
uint start,
|
||||
uint cLines,
|
||||
byte[] lpvBits,
|
||||
ref BITMAPINFO lpbmi,
|
||||
DIB usage);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@ internal static partial class Interop
|
|||
}
|
||||
|
||||
[DllImport(Libraries.Gdi32, SetLastError = true, ExactSpelling = true)]
|
||||
public static extern int GetDeviceCaps(IntPtr hDC, DeviceCapability nIndex);
|
||||
public static extern int GetDeviceCaps(HDC hDC, DeviceCapability nIndex);
|
||||
|
||||
public static int GetDeviceCaps(HandleRef hDC, DeviceCapability nIndex)
|
||||
public static int GetDeviceCaps(IHandle hDC, DeviceCapability nIndex)
|
||||
{
|
||||
int caps = GetDeviceCaps(hDC.Handle, nIndex);
|
||||
GC.KeepAlive(hDC.Wrapper);
|
||||
int caps = GetDeviceCaps((HDC)hDC.Handle, nIndex);
|
||||
GC.KeepAlive(hDC);
|
||||
return caps;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,18 +4,17 @@
|
|||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern MM GetMapMode(IntPtr hdc);
|
||||
public static extern MM GetMapMode(HDC hdc);
|
||||
|
||||
public static MM GetMapMode(IHandle hdc)
|
||||
{
|
||||
MM result = GetMapMode(hdc.Handle);
|
||||
MM result = GetMapMode((HDC)hdc.Handle);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern int GetNearestColor(IntPtr hdc, int color);
|
||||
public static extern int GetNearestColor(HDC hdc, int color);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern ObjectType GetObjectType(IntPtr h);
|
||||
public static extern ObjectType GetObjectType(HGDIOBJ h);
|
||||
|
||||
public static ObjectType GetObjectType(HandleRef h)
|
||||
{
|
||||
ObjectType result = GetObjectType(h.Handle);
|
||||
ObjectType result = GetObjectType((HGDIOBJ)h.Handle);
|
||||
GC.KeepAlive(h.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,10 +10,12 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
private unsafe static extern int GetObjectW(IntPtr h, int c, void* pv);
|
||||
private unsafe static extern int GetObjectW(HGDIOBJ h, int c, void* pv);
|
||||
|
||||
public unsafe static bool GetObjectW<T>(IntPtr h, out T @object) where T : unmanaged
|
||||
public unsafe static bool GetObjectW<T>(HGDIOBJ h, out T @object) where T : unmanaged
|
||||
{
|
||||
// HGDIOBJ isn't technically correct, but close enough to filter out bigger mistakes (HWND, etc.).
|
||||
|
||||
@object = default;
|
||||
fixed (void* pv = &@object)
|
||||
{
|
||||
|
@ -23,7 +25,7 @@ internal static partial class Interop
|
|||
|
||||
public static bool GetObjectW<T>(HandleRef h, out T @object) where T : unmanaged
|
||||
{
|
||||
bool result = GetObjectW(h.Handle, out @object);
|
||||
bool result = GetObjectW((HGDIOBJ)h.Handle, out @object);
|
||||
GC.KeepAlive(h.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, SetLastError = true, ExactSpelling = true)]
|
||||
private unsafe static extern uint GetPaletteEntries(IntPtr hpal, uint iStart, uint nEntries, PALETTEENTRY* lppe);
|
||||
private unsafe static extern uint GetPaletteEntries(HPALETTE hpal, uint iStart, uint nEntries, PALETTEENTRY* lppe);
|
||||
|
||||
public unsafe static uint GetPaletteEntries(IntPtr hpal, Span<PALETTEENTRY> entries)
|
||||
public unsafe static uint GetPaletteEntries(HPALETTE hpal, Span<PALETTEENTRY> entries)
|
||||
{
|
||||
fixed (PALETTEENTRY* entry = &MemoryMarshal.GetReference(entries))
|
||||
{
|
||||
|
|
|
@ -11,11 +11,11 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern R2 GetROP2(IntPtr hdc);
|
||||
public static extern R2 GetROP2(HDC hdc);
|
||||
|
||||
public static R2 GetROP2(IHandle hdc)
|
||||
{
|
||||
R2 result = GetROP2(hdc.Handle);
|
||||
R2 result = GetROP2((HDC)hdc.Handle);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,6 @@ internal static partial class Interop
|
|||
}
|
||||
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern IntPtr GetStockObject(StockObject nIndex);
|
||||
public static extern HGDIOBJ GetStockObject(StockObject nIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern uint GetSystemPaletteEntries(IntPtr hdc, uint iStart, uint cEntries, byte[] pPalEntries);
|
||||
public static extern uint GetSystemPaletteEntries(HDC hdc, uint iStart, uint cEntries, byte[] pPalEntries);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern int GetTextColor(IntPtr hdc);
|
||||
public static extern int GetTextColor(HDC hdc);
|
||||
|
||||
public static int GetTextColor(IHandle hdc)
|
||||
{
|
||||
int result = GetTextColor(hdc.Handle);
|
||||
int result = GetTextColor((HDC)hdc.Handle);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
||||
public static extern BOOL GetTextExtentPoint32W(IntPtr hdc, string lpString, int c, ref Size psizl);
|
||||
public static extern BOOL GetTextExtentPoint32W(HDC hdc, string lpString, int c, ref Size psizl);
|
||||
|
||||
public static BOOL GetTextExtentPoint32W(HandleRef hdc, string lpString, int c, ref Size psizl)
|
||||
{
|
||||
BOOL result = GetTextExtentPoint32W(hdc.Handle, lpString, c, ref psizl);
|
||||
BOOL result = GetTextExtentPoint32W((HDC)hdc.Handle, lpString, c, ref psizl);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
||||
public static extern BOOL GetTextMetricsW(IntPtr hdc, ref TEXTMETRICW lptm);
|
||||
public static extern BOOL GetTextMetricsW(HDC hdc, ref TEXTMETRICW lptm);
|
||||
|
||||
public static BOOL GetTextMetricsW(HandleRef hdc, ref TEXTMETRICW lptm)
|
||||
public static BOOL GetTextMetricsW(IHandle hdc, ref TEXTMETRICW lptm)
|
||||
{
|
||||
BOOL result = GetTextMetricsW(hdc.Handle, ref lptm);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
BOOL result = GetTextMetricsW((HDC)hdc.Handle, ref lptm);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,11 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern BOOL GetViewportExtEx(IntPtr hdc, out Size lpsize);
|
||||
public static extern BOOL GetViewportExtEx(HDC hdc, out Size lpsize);
|
||||
|
||||
public static BOOL GetViewportExtEx(IHandle hdc, out Size lpsize)
|
||||
{
|
||||
BOOL result = GetViewportExtEx(hdc.Handle, out lpsize);
|
||||
BOOL result = GetViewportExtEx((HDC)hdc.Handle, out lpsize);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -12,11 +12,11 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public unsafe static extern BOOL GetViewportOrgEx(IntPtr hdc, out Point lppoint);
|
||||
public unsafe static extern BOOL GetViewportOrgEx(HDC hdc, out Point lppoint);
|
||||
|
||||
public unsafe static BOOL GetViewportOrgEx(IHandle hdc, out Point lppoint)
|
||||
{
|
||||
BOOL result = GetViewportOrgEx(hdc.Handle, out lppoint);
|
||||
BOOL result = GetViewportOrgEx((HDC)hdc.Handle, out lppoint);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// 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
|
||||
{
|
||||
public readonly struct HBITMAP
|
||||
{
|
||||
public IntPtr Handle { get; }
|
||||
|
||||
public HBITMAP(IntPtr handle) => Handle = handle;
|
||||
|
||||
public bool IsNull => Handle == IntPtr.Zero;
|
||||
|
||||
public static implicit operator HGDIOBJ(HBITMAP hbitmap) => new HGDIOBJ(hbitmap.Handle);
|
||||
public static explicit operator HBITMAP(HGDIOBJ hbitmap) => new HBITMAP(hbitmap.Handle);
|
||||
public static explicit operator HBITMAP(IntPtr hbitmap) => new HBITMAP(hbitmap);
|
||||
public static explicit operator IntPtr(HBITMAP hbitmap) => hbitmap.Handle;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// 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
|
||||
{
|
||||
public readonly struct HBRUSH
|
||||
{
|
||||
public IntPtr Handle { get; }
|
||||
|
||||
public HBRUSH(IntPtr handle) => Handle = handle;
|
||||
|
||||
public bool IsNull => Handle == IntPtr.Zero;
|
||||
|
||||
public static explicit operator IntPtr(HBRUSH hbrush) => hbrush.Handle;
|
||||
public static explicit operator HBRUSH(IntPtr hbrush) => new HBRUSH(hbrush);
|
||||
public static implicit operator HGDIOBJ(HBRUSH hbrush) => new HGDIOBJ(hbrush.Handle);
|
||||
public static explicit operator HBRUSH(HGDIOBJ hbrush) => new HBRUSH(hbrush.Handle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// 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
|
||||
{
|
||||
public readonly struct HDC
|
||||
{
|
||||
public IntPtr Handle { get; }
|
||||
|
||||
public HDC(IntPtr handle) => Handle = handle;
|
||||
|
||||
public bool IsNull => Handle == IntPtr.Zero;
|
||||
|
||||
public static explicit operator IntPtr(HDC hdc) => hdc.Handle;
|
||||
public static explicit operator HDC(IntPtr hdc) => new HDC(hdc);
|
||||
public static implicit operator HGDIOBJ(HDC hdc) => new HGDIOBJ(hdc.Handle);
|
||||
|
||||
public static bool operator ==(HDC value1, HDC value2) => value1.Handle == value2.Handle;
|
||||
public static bool operator !=(HDC value1, HDC value2) => value1.Handle != value2.Handle;
|
||||
public override bool Equals(object? obj) => obj is HDC hdc && hdc.Handle == Handle;
|
||||
public override int GetHashCode() => Handle.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// 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
|
||||
{
|
||||
public readonly struct HFONT
|
||||
{
|
||||
public IntPtr Handle { get; }
|
||||
|
||||
public HFONT(IntPtr handle) => Handle = handle;
|
||||
|
||||
public bool IsNull => Handle == IntPtr.Zero;
|
||||
|
||||
public static implicit operator HGDIOBJ(HFONT hfont) => new HGDIOBJ(hfont.Handle);
|
||||
public static explicit operator HFONT(HGDIOBJ hfont) => new HFONT(hfont.Handle);
|
||||
public static explicit operator HFONT(IntPtr hfont) => new HFONT(hfont);
|
||||
public static explicit operator IntPtr(HFONT hfont) => hfont.Handle;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,11 +8,21 @@ internal static partial class Interop
|
|||
{
|
||||
internal static partial class Gdi32
|
||||
{
|
||||
public ref struct HGDIOBJ
|
||||
public struct HGDIOBJ
|
||||
{
|
||||
public IntPtr Handle { get; }
|
||||
|
||||
public HGDIOBJ(IntPtr handle) => Handle = handle;
|
||||
|
||||
public bool IsNull => Handle == IntPtr.Zero;
|
||||
|
||||
public static explicit operator IntPtr(HGDIOBJ hgdiobj) => hgdiobj.Handle;
|
||||
public static explicit operator HGDIOBJ(IntPtr hgdiobj) => new HGDIOBJ(hgdiobj);
|
||||
|
||||
public static bool operator ==(HGDIOBJ value1, HGDIOBJ value2) => value1.Handle == value2.Handle;
|
||||
public static bool operator !=(HGDIOBJ value1, HGDIOBJ value2) => value1.Handle != value2.Handle;
|
||||
public override bool Equals(object? obj) => obj is HGDIOBJ hgdiobj && hgdiobj.Handle == Handle;
|
||||
public override int GetHashCode() => Handle.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// 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
|
||||
{
|
||||
public readonly struct HPALETTE
|
||||
{
|
||||
public IntPtr Handle { get; }
|
||||
|
||||
public HPALETTE(IntPtr handle) => Handle = handle;
|
||||
|
||||
public bool IsNull => Handle == IntPtr.Zero;
|
||||
|
||||
public static explicit operator IntPtr(HPALETTE hpalette) => hpalette.Handle;
|
||||
public static explicit operator HPALETTE(IntPtr hpalette) => new HPALETTE(hpalette);
|
||||
public static implicit operator HGDIOBJ(HPALETTE hpalette) => new HGDIOBJ(hpalette.Handle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// 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
|
||||
{
|
||||
public readonly struct HPEN
|
||||
{
|
||||
public IntPtr Handle { get; }
|
||||
|
||||
public HPEN(IntPtr handle) => Handle = handle;
|
||||
|
||||
public bool IsNull => Handle == IntPtr.Zero;
|
||||
|
||||
public static explicit operator IntPtr(HPEN hpen) => hpen.Handle;
|
||||
public static explicit operator HPEN(IntPtr hpen) => new HPEN(hpen);
|
||||
public static implicit operator HGDIOBJ(HPEN hpen) => new HGDIOBJ(hpen.Handle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern BOOL LPtoDP(IntPtr hdc, ref RECT lppt, int c);
|
||||
public static extern BOOL LPtoDP(HDC hdc, ref RECT lppt, int c);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,10 @@ internal static partial class Interop
|
|||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern BOOL LineTo(IntPtr hdc, int x, int y);
|
||||
|
||||
public static BOOL LineTo(HandleRef hdc, int x, int y)
|
||||
public static BOOL LineTo(IHandle hdc, int x, int y)
|
||||
{
|
||||
BOOL result = LineTo(hdc.Handle, x, y);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,10 +13,10 @@ internal static partial class Interop
|
|||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public unsafe static extern BOOL MoveToEx(IntPtr hdc, int x, int y, Point* lppt);
|
||||
|
||||
public unsafe static BOOL MoveToEx(HandleRef hdc, int x, int y, Point* lppt)
|
||||
public unsafe static BOOL MoveToEx(IHandle hdc, int x, int y, Point* lppt)
|
||||
{
|
||||
BOOL result = MoveToEx(hdc.Handle, x, y, lppt);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@ internal static partial class Interop
|
|||
public HGDIOBJ Object { get; }
|
||||
|
||||
/// <param name="object">The object to be deleted when the scope closes.</param>
|
||||
public ObjectScope(IntPtr @object)
|
||||
public ObjectScope(HGDIOBJ @object)
|
||||
{
|
||||
Object = new HGDIOBJ(@object);
|
||||
Object = @object;
|
||||
}
|
||||
|
||||
public static implicit operator IntPtr(ObjectScope objectScope) => objectScope.Object.Handle;
|
||||
public static implicit operator HGDIOBJ(ObjectScope objectScope) => objectScope.Object;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
|
@ -11,12 +11,12 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern BOOL OffsetViewportOrgEx(IntPtr hdc, int x, int y, ref Point lppt);
|
||||
public static extern BOOL OffsetViewportOrgEx(HDC hdc, int x, int y, ref Point lppt);
|
||||
|
||||
public static BOOL OffsetViewportOrgEx(HandleRef hdc, int x, int y, ref Point lppt)
|
||||
public static BOOL OffsetViewportOrgEx(IHandle hdc, int x, int y, ref Point lppt)
|
||||
{
|
||||
BOOL result = OffsetViewportOrgEx(hdc.Handle, x, y, ref lppt);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
BOOL result = OffsetViewportOrgEx((HDC)hdc.Handle, x, y, ref lppt);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern BOOL PatBlt(IntPtr hdc, int x, int y, int w, int h, ROP rop);
|
||||
public static extern BOOL PatBlt(HDC hdc, int x, int y, int w, int h, ROP rop);
|
||||
|
||||
public static BOOL PatBlt(HandleRef hdc, int x, int y, int w, int h, ROP rop)
|
||||
{
|
||||
BOOL result = PatBlt(hdc.Handle, x, y, w, h, rop);
|
||||
BOOL result = PatBlt((HDC)hdc.Handle, x, y, w, h, rop);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern BOOL Rectangle(IntPtr hdc, int left, int top, int right, int bottom);
|
||||
public static extern BOOL Rectangle(HDC hdc, int left, int top, int right, int bottom);
|
||||
|
||||
public static BOOL Rectangle(HandleRef hdc, int left, int top, int right, int bottom)
|
||||
{
|
||||
BOOL result = Rectangle(hdc.Handle, left, top, right, bottom);
|
||||
BOOL result = Rectangle((HDC)hdc.Handle, left, top, right, bottom);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -38,10 +38,10 @@ internal static partial class Interop
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a clipping region copy via <see cref="GetClipRgn(IntPtr, HRGN)"/> for the given device context.
|
||||
/// Creates a clipping region copy via <see cref="GetClipRgn(HDC, HRGN)"/> for the given device context.
|
||||
/// </summary>
|
||||
/// <param name="hdc">Handle to a device context to copy the clipping region from.</param>
|
||||
public RegionScope(IntPtr hdc)
|
||||
public RegionScope(HDC hdc)
|
||||
{
|
||||
HRGN region = CreateRectRgn(0, 0, 0, 0);
|
||||
int result = GetClipRgn(hdc, region);
|
||||
|
|
|
@ -10,12 +10,12 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern BOOL RestoreDC(IntPtr hdc, int nSavedDC);
|
||||
public static extern BOOL RestoreDC(HDC hdc, int nSavedDC);
|
||||
|
||||
public static BOOL RestoreDC(HandleRef hdc, int nSavedDC)
|
||||
public static BOOL RestoreDC(IHandle hdc, int nSavedDC)
|
||||
{
|
||||
BOOL result = RestoreDC(hdc.Handle, nSavedDC);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
BOOL result = RestoreDC((HDC)hdc.Handle, nSavedDC);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern BOOL RoundRect(IntPtr hdc, int left, int top, int right, int bottom, int width, int height);
|
||||
public static extern BOOL RoundRect(HDC hdc, int left, int top, int right, int bottom, int width, int height);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern int SaveDC(IntPtr hdc);
|
||||
public static extern int SaveDC(HDC hdc);
|
||||
|
||||
public static int SaveDC(HandleRef hdc)
|
||||
public static int SaveDC(IHandle hdc)
|
||||
{
|
||||
int result = SaveDC(hdc.Handle);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
int result = SaveDC((HDC)hdc.Handle);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,15 +12,25 @@ internal static partial class Interop
|
|||
/// Helper to scope lifetime of a saved device context state.
|
||||
/// </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 risking a double restore.
|
||||
/// 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 risking a double restore.
|
||||
///
|
||||
/// The state that is saved includes ICM (color management), palette, path drawing state, and other objects
|
||||
/// that are selected into the DC (bitmap, brush, pen, clipping region, font).
|
||||
///
|
||||
/// Ideally saving the entire DC state can be avoided for simple drawing operations and relying on restoring
|
||||
/// individual state pieces can be done instead (putting back the original pen, etc.).
|
||||
/// </remarks>
|
||||
public ref struct SaveDcScope
|
||||
{
|
||||
public IntPtr HDC { get; }
|
||||
public HDC HDC { get; }
|
||||
private readonly int _savedState;
|
||||
|
||||
public SaveDcScope(IntPtr hdc)
|
||||
/// <summary>
|
||||
/// Saves the device context state using <see cref="SaveDC(HDC)"/>.
|
||||
/// </summary>
|
||||
/// <param name="hdc"></param>
|
||||
public SaveDcScope(HDC hdc)
|
||||
{
|
||||
_savedState = SaveDC(hdc);
|
||||
HDC = hdc;
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, SetLastError = true, ExactSpelling = true)]
|
||||
public static extern RegionType SelectClipRgn(IntPtr hdc, HRGN hrgn);
|
||||
public static extern RegionType SelectClipRgn(HDC hdc, HRGN hrgn);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,20 +10,19 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, SetLastError = true, ExactSpelling = true)]
|
||||
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr h);
|
||||
public static extern HGDIOBJ SelectObject(HDC hdc, HGDIOBJ h);
|
||||
|
||||
public static IntPtr SelectObject(HandleRef hdc, IntPtr h)
|
||||
public static HGDIOBJ SelectObject(IHandle hdc, HGDIOBJ h)
|
||||
{
|
||||
IntPtr lastObject = SelectObject(hdc.Handle, h);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
HGDIOBJ lastObject = SelectObject((HDC)hdc.Handle, h);
|
||||
GC.KeepAlive(hdc);
|
||||
return lastObject;
|
||||
}
|
||||
|
||||
public static IntPtr SelectObject(HandleRef hdc, HandleRef h)
|
||||
public static HGDIOBJ SelectObject(HandleRef hdc, HGDIOBJ h)
|
||||
{
|
||||
IntPtr lastObject = SelectObject(hdc.Handle, h.Handle);
|
||||
HGDIOBJ lastObject = SelectObject((HDC)hdc.Handle, h);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
GC.KeepAlive(h.Wrapper);
|
||||
return lastObject;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr SelectPalette(IntPtr hdc, IntPtr hPal, BOOL bForceBkgd);
|
||||
|
||||
public static IntPtr SelectPalette(HandleRef hdc, HandleRef hPal, BOOL bForceBkgd)
|
||||
{
|
||||
IntPtr result = SelectPalette(hdc.Handle, hPal.Handle, bForceBkgd);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
GC.KeepAlive(hPal.Wrapper);
|
||||
return result;
|
||||
}
|
||||
public static extern HPALETTE SelectPalette(HDC hdc, HPALETTE hPal, BOOL bForceBkgd);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// 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 palette selection.
|
||||
/// </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 risking a double pallete reset.
|
||||
/// </remarks>
|
||||
public ref struct SelectPaletteScope
|
||||
{
|
||||
public HDC HDC { get; }
|
||||
public HPALETTE HPalette { get; }
|
||||
|
||||
public SelectPaletteScope(HDC hdc, HPALETTE hpalette, bool forceBackground, bool realizePalette)
|
||||
{
|
||||
HDC = hdc;
|
||||
HPalette = SelectPalette(hdc, hpalette, forceBackground.ToBOOL());
|
||||
if (!HPalette.IsNull && realizePalette)
|
||||
{
|
||||
RealizePalette((IntPtr)hdc);
|
||||
}
|
||||
}
|
||||
|
||||
public static SelectPaletteScope HalftonePalette(HDC hdc, bool forceBackground, bool realizePalette)
|
||||
=> new SelectPaletteScope(hdc, (HPALETTE)Graphics.GetHalftonePalette(), forceBackground, realizePalette);
|
||||
|
||||
public static implicit operator HPALETTE(SelectPaletteScope paletteScope) => paletteScope.HPalette;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!HPalette.IsNull)
|
||||
{
|
||||
SelectPalette(HDC, HPalette, bForceBkgd: BOOL.FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,13 +18,13 @@ internal static partial class Interop
|
|||
/// </remarks>
|
||||
internal ref struct SelectObjectScope
|
||||
{
|
||||
private readonly IntPtr _hdc;
|
||||
public IntPtr PreviousObject;
|
||||
private readonly HDC _hdc;
|
||||
public HGDIOBJ PreviousObject;
|
||||
|
||||
/// <summary>
|
||||
/// Selects <paramref name="object"/> into the given <paramref name="hdc"/>.
|
||||
/// </summary>
|
||||
public SelectObjectScope(IntPtr hdc, IntPtr @object)
|
||||
public SelectObjectScope(HDC hdc, HGDIOBJ @object)
|
||||
{
|
||||
_hdc = hdc;
|
||||
PreviousObject = SelectObject(hdc, @object);
|
||||
|
|
|
@ -4,25 +4,24 @@
|
|||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern int SetBkColor(IntPtr hdc, int color);
|
||||
public static extern int SetBkColor(HDC hdc, int color);
|
||||
|
||||
public static int SetBkColor(IHandle hdc, int color)
|
||||
{
|
||||
int result = SetBkColor(hdc.Handle, color);
|
||||
int result = SetBkColor((HDC)hdc.Handle, color);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int SetBkColor(HandleRef hdc, int color)
|
||||
{
|
||||
int result = SetBkColor(hdc.Handle, color);
|
||||
int result = SetBkColor((HDC)hdc.Handle, color);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -4,25 +4,24 @@
|
|||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern BKMODE SetBkMode(IntPtr hdc, BKMODE mode);
|
||||
public static extern BKMODE SetBkMode(HDC hdc, BKMODE mode);
|
||||
|
||||
public static BKMODE SetBkMode(IHandle hdc, BKMODE mode)
|
||||
{
|
||||
BKMODE result = SetBkMode(hdc.Handle, mode);
|
||||
BKMODE result = SetBkMode((HDC)hdc.Handle, mode);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static BKMODE SetBkMode(HandleRef hdc, BKMODE mode)
|
||||
{
|
||||
BKMODE result = SetBkMode(hdc.Handle, mode);
|
||||
BKMODE result = SetBkMode((HDC)hdc.Handle, mode);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern MM SetMapMode(IntPtr hdc, MM mode);
|
||||
public static extern MM SetMapMode(HDC hdc, MM mode);
|
||||
|
||||
public static MM SetMapMode(IHandle hdc, MM mode)
|
||||
{
|
||||
MM result = SetMapMode(hdc.Handle, mode);
|
||||
MM result = SetMapMode((HDC)hdc.Handle, mode);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -4,18 +4,17 @@
|
|||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern Gdi32.R2 SetROP2(IntPtr hdc, R2 rop2);
|
||||
public static extern R2 SetROP2(HDC hdc, R2 rop2);
|
||||
|
||||
public static Gdi32.R2 SetROP2(IHandle hdc, R2 rop2)
|
||||
public static R2 SetROP2(IHandle hdc, R2 rop2)
|
||||
{
|
||||
Gdi32.R2 result = SetROP2(hdc.Handle, rop2);
|
||||
R2 result = SetROP2((HDC)hdc.Handle, rop2);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -16,15 +16,15 @@ internal static partial class Interop
|
|||
/// 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 ref struct Rop2Scope
|
||||
internal ref struct SetRop2Scope
|
||||
{
|
||||
private readonly R2 _previousRop;
|
||||
private readonly IntPtr _hdc;
|
||||
private readonly HDC _hdc;
|
||||
|
||||
/// <summary>
|
||||
/// Selects <paramref name="rop2"/> into the given <paramref name="hdc"/>.
|
||||
/// </summary>
|
||||
public Rop2Scope(IntPtr hdc, R2 rop2)
|
||||
public SetRop2Scope(HDC hdc, R2 rop2)
|
||||
{
|
||||
_hdc = hdc;
|
||||
_previousRop = SetROP2(hdc, rop2);
|
|
@ -4,25 +4,24 @@
|
|||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern int SetTextColor(IntPtr hdc, int color);
|
||||
public static extern int SetTextColor(HDC hdc, int color);
|
||||
|
||||
public static int SetTextColor(IHandle hdc, int color)
|
||||
{
|
||||
int result = SetTextColor(hdc.Handle, color);
|
||||
int result = SetTextColor((HDC)hdc.Handle, color);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int SetTextColor(HandleRef hdc, int color)
|
||||
{
|
||||
int result = SetTextColor(hdc.Handle, color);
|
||||
int result = SetTextColor((HDC)hdc.Handle, color);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -5,18 +5,17 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public unsafe static extern BOOL SetViewportExtEx(IntPtr hdc, int x, int y, Size *lpsz);
|
||||
public unsafe static extern BOOL SetViewportExtEx(HDC hdc, int x, int y, Size *lpsz);
|
||||
|
||||
public unsafe static BOOL SetViewportExtEx(IHandle hdc, int x, int y, Size *lpsz)
|
||||
{
|
||||
BOOL result = SetViewportExtEx(hdc.Handle, x, y, lpsz);
|
||||
BOOL result = SetViewportExtEx((HDC)hdc.Handle, x, y, lpsz);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -5,18 +5,17 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public unsafe static extern BOOL SetViewportOrgEx(IntPtr hdc, int x, int y, Point *lppt);
|
||||
public unsafe static extern BOOL SetViewportOrgEx(HDC hdc, int x, int y, Point *lppt);
|
||||
|
||||
public unsafe static BOOL SetViewportOrgEx(IHandle hdc, int x, int y, Point *lppt)
|
||||
{
|
||||
BOOL result = SetViewportOrgEx(hdc.Handle, x, y, lppt);
|
||||
BOOL result = SetViewportOrgEx((HDC)hdc.Handle, x, y, lppt);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public unsafe static extern BOOL SetWindowExtEx(IntPtr hdc, int x, int y, Size *lpsz);
|
||||
public unsafe static extern BOOL SetWindowExtEx(HDC hdc, int x, int y, Size *lpsz);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public unsafe static extern BOOL SetWindowOrgEx(IntPtr hdc, int x, int y, Point *lppt);
|
||||
public unsafe static extern BOOL SetWindowOrgEx(HDC hdc, int x, int y, Point *lppt);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,19 @@ internal static partial class Interop
|
|||
internal static partial class Gdi32
|
||||
{
|
||||
[DllImport(Libraries.Gdi32, ExactSpelling = true)]
|
||||
public static extern int StretchDIBits(IntPtr hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc, int SrcWidth, int SrcHeight, byte[] lpBits, ref BITMAPINFO lpbmi, DIB usage, ROP rop);
|
||||
public static extern int StretchDIBits(
|
||||
HDC hdc,
|
||||
int xDest,
|
||||
int yDest,
|
||||
int DestWidth,
|
||||
int DestHeight,
|
||||
int xSrc,
|
||||
int ySrc,
|
||||
int SrcWidth,
|
||||
int SrcHeight,
|
||||
byte[] lpBits,
|
||||
ref BITMAPINFO lpbmi,
|
||||
DIB usage,
|
||||
ROP rop);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,22 +17,25 @@ internal static partial class Interop
|
|||
/// </remarks>
|
||||
public ref struct BeginPaintScope
|
||||
{
|
||||
public IntPtr HDC { get; }
|
||||
public PAINTSTRUCT _paintStruct;
|
||||
|
||||
public Gdi32.HDC HDC { get; }
|
||||
public IntPtr HWND { get; }
|
||||
private PAINTSTRUCT _paintStruct;
|
||||
|
||||
public PAINTSTRUCT PaintStruct => _paintStruct;
|
||||
|
||||
public BeginPaintScope(IntPtr hwnd)
|
||||
{
|
||||
_paintStruct = default;
|
||||
HDC = BeginPaint(hwnd, ref _paintStruct);
|
||||
HDC = (Gdi32.HDC)BeginPaint(hwnd, ref _paintStruct);
|
||||
HWND = hwnd;
|
||||
}
|
||||
|
||||
public static implicit operator IntPtr(BeginPaintScope paintScope) => paintScope.HDC;
|
||||
public static implicit operator Gdi32.HDC(BeginPaintScope paintScope) => paintScope.HDC;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (HDC != IntPtr.Zero)
|
||||
if (!HDC.IsNull)
|
||||
{
|
||||
EndPaint(HWND, ref _paintStruct);
|
||||
}
|
||||
|
|
|
@ -11,18 +11,19 @@ internal static partial class Interop
|
|||
[Flags]
|
||||
public enum DCX : uint
|
||||
{
|
||||
WINDOW = 0x00000001,
|
||||
CACHE = 0x00000002,
|
||||
NORESETATTRS = 0x00000004,
|
||||
CLIPCHILDREN = 0x00000008,
|
||||
CLIPSIBLINGS = 0x00000010,
|
||||
PARENTCLIP = 0x00000020,
|
||||
EXCLUDERGN = 0x00000040,
|
||||
INTERSECTRGN = 0x00000080,
|
||||
EXCLUDEUPDATE = 0x00000100,
|
||||
INTERSECTUPDATE = 0x00000200,
|
||||
LOCKWINDOWUPDATE = 0x00000400,
|
||||
VALIDATE = 0x00200000,
|
||||
WINDOW = 0x00000001,
|
||||
CACHE = 0x00000002,
|
||||
NORESETATTRS = 0x00000004,
|
||||
CLIPCHILDREN = 0x00000008,
|
||||
CLIPSIBLINGS = 0x00000010,
|
||||
PARENTCLIP = 0x00000020,
|
||||
EXCLUDERGN = 0x00000040,
|
||||
INTERSECTRGN = 0x00000080,
|
||||
EXCLUDEUPDATE = 0x00000100,
|
||||
INTERSECTUPDATE = 0x00000200,
|
||||
LOCKWINDOWUPDATE = 0x00000400,
|
||||
USESTYLE = 0x00010000,
|
||||
VALIDATE = 0x00200000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
|
@ -17,7 +16,7 @@ internal static partial class Interop
|
|||
public ODA itemAction;
|
||||
public ODS itemState;
|
||||
public IntPtr hwndItem;
|
||||
public IntPtr hDC;
|
||||
public Gdi32.HDC hDC;
|
||||
public RECT rcItem;
|
||||
public IntPtr itemData;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ internal static partial class Interop
|
|||
internal static partial class User32
|
||||
{
|
||||
/// <summary>
|
||||
/// Text format flags for <see cref="DrawTextExW(IntPtr, string, int, ref RECT, DT, ref DRAWTEXTPARAMS)"/> and
|
||||
/// <see cref="DrawTextW(IntPtr, string, int, ref RECT, DT)"/>
|
||||
/// Text format flags for <see cref="DrawTextExW(Gdi32.HDC, string, int, ref RECT, DT, ref DRAWTEXTPARAMS)"/> and
|
||||
/// <see cref="DrawTextW(Gdi32.HDC, string, int, ref RECT, DT)"/>
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum DT : uint
|
||||
|
|
|
@ -10,13 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class User32
|
||||
{
|
||||
[DllImport(Libraries.User32, ExactSpelling = true)]
|
||||
private static extern BOOL DrawEdge(IntPtr hdc, ref RECT qrc, EDGE edge, BF grfFlags);
|
||||
|
||||
public static BOOL DrawEdge(HandleRef hdc, ref RECT qrc, EDGE edge, BF grfFlags)
|
||||
{
|
||||
BOOL result = DrawEdge(hdc.Handle, ref qrc, edge, grfFlags);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
return result;
|
||||
}
|
||||
public static extern BOOL DrawEdge(Gdi32.HDC hdc, ref RECT qrc, EDGE edge, BF grfFlags);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,18 @@ internal static partial class Interop
|
|||
internal static partial class User32
|
||||
{
|
||||
[DllImport(Libraries.User32, ExactSpelling = true)]
|
||||
public static extern BOOL DrawFrameControl(IntPtr hdc, ref RECT rect, DFC type, DFCS state);
|
||||
public static extern BOOL DrawFrameControl(Gdi32.HDC hdc, ref RECT rect, DFC type, DFCS state);
|
||||
|
||||
public static BOOL DrawFrameControl(IHandle hdc, ref RECT rect, DFC type, DFCS state)
|
||||
{
|
||||
BOOL result = DrawFrameControl((Gdi32.HDC)hdc.Handle, ref rect, type, state);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static BOOL DrawFrameControl(HandleRef hdc, ref RECT rect, DFC type, DFCS state)
|
||||
{
|
||||
BOOL result = DrawFrameControl(hdc.Handle, ref rect, type, state);
|
||||
BOOL result = DrawFrameControl((Gdi32.HDC)hdc.Handle, ref rect, type, state);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ internal static partial class Interop
|
|||
internal static partial class User32
|
||||
{
|
||||
[DllImport(Libraries.User32, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
||||
public static extern int DrawTextW(IntPtr hdc, string lpchText, int nCount, ref RECT lprc, DT format);
|
||||
public static extern int DrawTextW(Gdi32.HDC hdc, string lpchText, int nCount, ref RECT lprc, DT format);
|
||||
|
||||
public static int DrawTextW(HandleRef hdc, string lpchText, int cchText, ref RECT lprc, DT format)
|
||||
{
|
||||
int result = DrawTextW(hdc.Handle, lpchText, cchText, ref lprc, format);
|
||||
int result = DrawTextW((Gdi32.HDC)hdc.Handle, lpchText, cchText, ref lprc, format);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@ internal static partial class Interop
|
|||
internal static partial class User32
|
||||
{
|
||||
[DllImport(Libraries.User32, EntryPoint = "DrawTextExW", ExactSpelling = true, CharSet = CharSet.Unicode)]
|
||||
private static extern int DrawTextExWInternal(IntPtr hdc, string lpchText, int cchText, ref RECT lprc, DT format, ref DRAWTEXTPARAMS lpdtp);
|
||||
private static extern int DrawTextExWInternal(Gdi32.HDC hdc, string lpchText, int cchText, ref RECT lprc, DT format, ref DRAWTEXTPARAMS lpdtp);
|
||||
|
||||
public static unsafe int DrawTextExW(IntPtr hdc, string lpchText, int cchText, ref RECT lprc, DT format, ref DRAWTEXTPARAMS lpdtp)
|
||||
public static unsafe int DrawTextExW(Gdi32.HDC hdc, string lpchText, int cchText, ref RECT lprc, DT format, ref DRAWTEXTPARAMS lpdtp)
|
||||
{
|
||||
lpdtp.cbSize = (uint)sizeof(DRAWTEXTPARAMS);
|
||||
return DrawTextExWInternal(hdc, lpchText, cchText, ref lprc, format, ref lpdtp);
|
||||
|
@ -21,7 +21,7 @@ internal static partial class Interop
|
|||
|
||||
public static int DrawTextExW(IHandle hdc, string lpchText, int cchText, ref RECT lprc, DT format, ref DRAWTEXTPARAMS lpdtp)
|
||||
{
|
||||
int result = DrawTextExW(hdc.Handle, lpchText, cchText, ref lprc, format, ref lpdtp);
|
||||
int result = DrawTextExW((Gdi32.HDC)hdc.Handle, lpchText, cchText, ref lprc, format, ref lpdtp);
|
||||
GC.KeepAlive(hdc);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,13 +10,12 @@ internal static partial class Interop
|
|||
internal static partial class User32
|
||||
{
|
||||
[DllImport(Libraries.User32, ExactSpelling = true)]
|
||||
public static extern int FillRect(IntPtr hDC, ref RECT lprc, IntPtr hbr);
|
||||
public static extern int FillRect(Gdi32.HDC hDC, ref RECT lprc, Gdi32.HBRUSH hbr);
|
||||
|
||||
public static int FillRect(HandleRef hDC, ref RECT lprc, HandleRef hbr)
|
||||
public static int FillRect(IHandle hDC, ref RECT lprc, Gdi32.HBRUSH hbr)
|
||||
{
|
||||
int result = FillRect(hDC.Handle, ref lprc, hbr.Handle);
|
||||
GC.KeepAlive(hDC.Wrapper);
|
||||
GC.KeepAlive(hbr.Wrapper);
|
||||
int result = FillRect((Gdi32.HDC)hDC.Handle, ref lprc, hbr);
|
||||
GC.KeepAlive(hDC);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ internal static partial class Interop
|
|||
internal static partial class User32
|
||||
{
|
||||
[DllImport(Libraries.User32, ExactSpelling = true)]
|
||||
public static extern IntPtr GetDC(IntPtr hWnd);
|
||||
public static extern Gdi32.HDC GetDC(IntPtr hWnd);
|
||||
|
||||
public static IntPtr GetDC(HandleRef hWnd)
|
||||
public static Gdi32.HDC GetDC(HandleRef hWnd)
|
||||
{
|
||||
IntPtr dc = GetDC(hWnd.Handle);
|
||||
Gdi32.HDC dc = GetDC(hWnd.Handle);
|
||||
GC.KeepAlive(hWnd.Wrapper);
|
||||
return dc;
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ internal static partial class Interop
|
|||
internal static partial class User32
|
||||
{
|
||||
[DllImport(Libraries.User32, ExactSpelling = true)]
|
||||
public static extern IntPtr GetDCEx(IntPtr hWnd, IntPtr hrgnClip, DCX flags);
|
||||
public static extern Gdi32.HDC GetDCEx(IntPtr hWnd, IntPtr hrgnClip, DCX flags);
|
||||
|
||||
public static IntPtr GetDCEx(IHandle hWnd, IntPtr hrgnClip, DCX flags)
|
||||
public static Gdi32.HDC GetDCEx(IHandle hWnd, IntPtr hrgnClip, DCX flags)
|
||||
{
|
||||
IntPtr result = GetDCEx(hWnd.Handle, hrgnClip, flags);
|
||||
Gdi32.HDC result = GetDCEx(hWnd.Handle, hrgnClip, flags);
|
||||
GC.KeepAlive(hWnd);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -3,21 +3,23 @@
|
|||
// 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 User32
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper to scope lifetime of an HDC retrieved via GetDC/Ex. Releases the HDC (if any) when disposed.
|
||||
/// Helper to scope lifetime of an <see cref="Gdi32.HDC"/> retrieved via <see cref="GetDC(IntPtr)"/> and
|
||||
/// <see cref="GetDCEx(IntPtr, IntPtr, DCX)"/>. Releases the <see cref="Gdi32.HDC"/> (if any) 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 risking a double release.
|
||||
/// 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 risking a double release.
|
||||
/// </remarks>
|
||||
public ref struct GetDcScope
|
||||
{
|
||||
public IntPtr HDC { get; }
|
||||
public Gdi32.HDC HDC { get; }
|
||||
public IntPtr HWND { get; }
|
||||
|
||||
public GetDcScope(IntPtr hwnd)
|
||||
|
@ -26,6 +28,15 @@ internal static partial class Interop
|
|||
HDC = GetDC(hwnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="Gdi32.HDC"/> using <see cref="GetDCEx(IntPtr, IntPtr, DCX)"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// GetWindowDC calls GetDCEx(hwnd, null, DCX_WINDOW | DCX_USESTYLE).
|
||||
///
|
||||
/// GetDC calls GetDCEx(hwnd, null, DCX_USESTYLE) when given a handle. (When given null it has additional
|
||||
/// logic, and can't be replaced directly by GetDCEx.
|
||||
/// </remarks>
|
||||
public GetDcScope(IntPtr hwnd, IntPtr hrgnClip, DCX flags)
|
||||
{
|
||||
HWND = hwnd;
|
||||
|
@ -36,17 +47,19 @@ internal static partial class Interop
|
|||
/// Creates a DC scope for the primary monitor (not the entire desktop).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see cref="Gdi32.CreateDC(string, string, string, IntPtr)" /> is
|
||||
/// the API to get the DC for the entire desktop.
|
||||
/// <see cref="Gdi32.CreateDC(string, string, string, IntPtr)" /> is the API to get the DC for the
|
||||
/// entire desktop.
|
||||
/// </remarks>
|
||||
public static GetDcScope ScreenDC
|
||||
=> new GetDcScope(IntPtr.Zero);
|
||||
public static GetDcScope ScreenDC => new GetDcScope(IntPtr.Zero);
|
||||
|
||||
public static implicit operator IntPtr(GetDcScope dcScope) => dcScope.HDC;
|
||||
public bool IsNull => HDC.IsNull;
|
||||
|
||||
public static implicit operator IntPtr(GetDcScope dcScope) => dcScope.HDC.Handle;
|
||||
public static implicit operator Gdi32.HDC(GetDcScope dcScope) => dcScope.HDC;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (HDC != IntPtr.Zero)
|
||||
if (!HDC.IsNull)
|
||||
{
|
||||
ReleaseDC(HWND, HDC);
|
||||
}
|
||||
|
|
|
@ -32,21 +32,21 @@ internal static partial class Interop
|
|||
public BOOL fIcon;
|
||||
public uint xHotspot;
|
||||
public uint yHotspot;
|
||||
public IntPtr hbmMask;
|
||||
public IntPtr hbmColor;
|
||||
public Gdi32.HBITMAP hbmMask;
|
||||
public Gdi32.HBITMAP hbmColor;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (hbmMask != IntPtr.Zero)
|
||||
if (!hbmMask.IsNull)
|
||||
{
|
||||
Gdi32.DeleteObject(hbmMask);
|
||||
hbmMask = IntPtr.Zero;
|
||||
hbmMask = default;
|
||||
}
|
||||
|
||||
if (hbmColor != IntPtr.Zero)
|
||||
if (!hbmColor.IsNull)
|
||||
{
|
||||
Gdi32.DeleteObject(hbmColor);
|
||||
hbmColor = IntPtr.Zero;
|
||||
hbmColor = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ internal static partial class Interop
|
|||
internal static partial class User32
|
||||
{
|
||||
[DllImport(Libraries.User32, ExactSpelling = true)]
|
||||
public static extern IntPtr GetSysColorBrush(int nIndex);
|
||||
public static extern Gdi32.HBRUSH GetSysColorBrush(int nIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
// 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 User32
|
||||
{
|
||||
[DllImport(Libraries.User32, ExactSpelling = true)]
|
||||
private static extern IntPtr GetWindowDC(IntPtr hWnd);
|
||||
|
||||
public static IntPtr GetWindowDC(HandleRef hWnd)
|
||||
{
|
||||
IntPtr result = GetWindowDC(hWnd.Handle);
|
||||
GC.KeepAlive(hWnd.Wrapper);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,6 @@ internal static partial class Interop
|
|||
{
|
||||
internal static partial class User32
|
||||
{
|
||||
public delegate BOOL MONITORENUMPROC(IntPtr monitor, IntPtr hdc, IntPtr lprcMonitor, IntPtr lParam);
|
||||
public delegate BOOL MONITORENUMPROC(IntPtr monitor, Gdi32.HDC hdc, IntPtr lprcMonitor, IntPtr lParam);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,21 +10,13 @@ internal static partial class Interop
|
|||
internal static partial class User32
|
||||
{
|
||||
[DllImport(Libraries.User32, ExactSpelling = true)]
|
||||
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
|
||||
public static extern int ReleaseDC(IntPtr hWnd, Gdi32.HDC hDC);
|
||||
|
||||
public static int ReleaseDC(HandleRef hWnd, IntPtr hDC)
|
||||
public static int ReleaseDC(HandleRef hWnd, Gdi32.HDC hDC)
|
||||
{
|
||||
int result = ReleaseDC(hWnd.Handle, hDC);
|
||||
GC.KeepAlive(hWnd.Wrapper);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int ReleaseDC(HandleRef hWnd, HandleRef hDC)
|
||||
{
|
||||
int result = ReleaseDC(hWnd.Handle, hDC.Handle);
|
||||
GC.KeepAlive(hWnd.Wrapper);
|
||||
GC.KeepAlive(hDC.Wrapper);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ internal static partial class Interop
|
|||
public IntPtr hInstance;
|
||||
public IntPtr hIcon;
|
||||
public IntPtr hCursor;
|
||||
public IntPtr hbrBackground;
|
||||
public Gdi32.HBRUSH hbrBackground;
|
||||
public char* lpszMenuName;
|
||||
public char* lpszClassName;
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ internal static partial class Interop
|
|||
internal static partial class User32
|
||||
{
|
||||
[DllImport(Libraries.User32, ExactSpelling = true)]
|
||||
public static extern IntPtr WindowFromDC(IntPtr hDC);
|
||||
public static extern IntPtr WindowFromDC(Gdi32.HDC hDC);
|
||||
|
||||
public static IntPtr WindowFromDC(HandleRef hDC)
|
||||
public static IntPtr WindowFromDC(IHandle hDC)
|
||||
{
|
||||
IntPtr result = WindowFromDC(hDC.Handle);
|
||||
GC.KeepAlive(hDC.Wrapper);
|
||||
IntPtr result = WindowFromDC((Gdi32.HDC)hDC.Handle);
|
||||
GC.KeepAlive(hDC);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,13 +10,13 @@ internal static partial class Interop
|
|||
public static partial class UxTheme
|
||||
{
|
||||
[DllImport(Libraries.UxTheme, ExactSpelling = true)]
|
||||
public static extern unsafe HRESULT DrawThemeBackground(IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, ref RECT pRect, RECT* pClipRect);
|
||||
public static extern unsafe HRESULT DrawThemeBackground(IntPtr hTheme, Gdi32.HDC hdc, int iPartId, int iStateId, ref RECT pRect, RECT* pClipRect);
|
||||
|
||||
public static unsafe HRESULT DrawThemeBackground(IHandle hTheme, HandleRef hdc, int iPartId, int iStateId, ref RECT pRect, RECT* pClipRect)
|
||||
public static unsafe HRESULT DrawThemeBackground(IHandle hTheme, IHandle hdc, int iPartId, int iStateId, ref RECT pRect, RECT* pClipRect)
|
||||
{
|
||||
HRESULT hr = DrawThemeBackground(hTheme.Handle, hdc.Handle, iPartId, iStateId, ref pRect, pClipRect);
|
||||
HRESULT hr = DrawThemeBackground(hTheme.Handle, (Gdi32.HDC)hdc.Handle, iPartId, iStateId, ref pRect, pClipRect);
|
||||
GC.KeepAlive(hTheme);
|
||||
GC.KeepAlive(hdc.Wrapper);
|
||||
GC.KeepAlive(hdc);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче