Skip to content

Commit aed3a39

Browse files
committed
Fi the issue that the icon of errorProvider is not scaled well on HDPI screen
1 parent dc00bb2 commit aed3a39

File tree

4 files changed

+35
-19
lines changed

4 files changed

+35
-19
lines changed

src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/DpiHelper.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,17 @@ public static void ScaleBitmapLogicalToDevice(ref Bitmap logicalBitmap, int devi
353353
}
354354
}
355355

356+
/// <summary>
357+
/// Get X, Y metrics at DPI, IF icon is not already that size, create and return a new one.
358+
/// </summary>
359+
internal static Icon ScaleSmallIconToDpi(Icon icon, int dpi)
360+
{
361+
int width = PInvoke.GetCurrentSystemMetrics(SYSTEM_METRICS_INDEX.SM_CXSMICON, (uint)dpi);
362+
int height = PInvoke.GetCurrentSystemMetrics(SYSTEM_METRICS_INDEX.SM_CYSMICON, (uint)dpi);
363+
364+
return (icon.Width == width && icon.Height == height) ? icon : new(icon, width, height);
365+
}
366+
356367
/// <summary>
357368
/// Indicates whether the first (Parking)Window has been created. From that moment on,
358369
/// we will not be able nor allowed to change the Process' DpiMode.

src/System.Windows.Forms/src/System/Windows/Forms/ErrorProvider.ErrorWindow.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,8 @@ protected override void WmDpiChangedBeforeParent(ref Message m)
484484
}
485485

486486
double factor = ((double)currentDpi) / _parent._deviceDpi;
487-
using Icon icon = _provider.Icon;
487+
Icon icon = _provider.Icon;
488+
_provider.CurrentDpi = currentDpi;
488489
_provider.Icon = new Icon(icon, (int)(icon.Width * factor), (int)(icon.Height * factor));
489490
}
490491
}

src/System.Windows.Forms/src/System/Windows/Forms/ErrorProvider.IconRegion.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ internal class IconRegion : IHandle<HICON>
1515
private Region? _region;
1616
private readonly Icon _icon;
1717

18-
public IconRegion(Icon icon)
18+
public IconRegion(Icon icon, int currentDpi)
1919
{
20-
_icon = new Icon(icon, DefaultIcon.Size);
20+
_icon = DpiHelper.ScaleSmallIconToDpi(icon, currentDpi);
2121
}
2222

2323
/// <summary>

src/System.Windows.Forms/src/System/Windows/Forms/ErrorProvider.cs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ public partial class ErrorProvider : Component, IExtenderProvider, ISupportIniti
2525
{
2626
private readonly Dictionary<Control, ControlItem> _items = new();
2727
private readonly Dictionary<Control, ErrorWindow> _windows = new();
28-
private Icon _icon = DefaultIcon;
28+
private Icon _icon;
2929
private IconRegion? _region;
3030
private int _itemIdCounter;
3131
private int _blinkRate;
32+
private int _currentDpi;
3233
private ErrorBlinkStyle _blinkStyle;
3334
private bool _showIcon = true; // used for blinking
3435
private bool _inSetErrorManager;
@@ -314,7 +315,7 @@ public object? DataSource
314315
{
315316
if (_parentControl is not null && _parentControl.BindingContext is not null && value is not null && !string.IsNullOrEmpty(_dataMember))
316317
{
317-
// Let's check if the datamember exists in the new data source
318+
// Let's check if the data member exists in the new data source
318319
try
319320
{
320321
_errorManager = _parentControl.BindingContext[value, _dataMember];
@@ -552,13 +553,8 @@ private static Icon DefaultIcon
552553
if (t_defaultIcon is null)
553554
{
554555
// Error provider uses small Icon.
555-
Size LogicalSmallSystemIconSize = OsVersion.IsWindows10_1607OrGreater()
556-
? new(
557-
PInvoke.GetSystemMetricsForDpi(SYSTEM_METRICS_INDEX.SM_CXSMICON, 96),
558-
PInvoke.GetSystemMetricsForDpi(SYSTEM_METRICS_INDEX.SM_CXSMICON, 96))
559-
: new(16, 16);
560-
using Icon defaultIcon = new(typeof(ErrorProvider), "Error");
561-
t_defaultIcon = new Icon(defaultIcon, LogicalSmallSystemIconSize);
556+
Icon defaultIcon = new(typeof(ErrorProvider), "Error");
557+
t_defaultIcon = DpiHelper.ScaleSmallIconToDpi(defaultIcon, DpiHelper.DeviceDpi);
562558
}
563559
}
564560

@@ -576,10 +572,7 @@ private static Icon DefaultIcon
576572
[SRDescription(nameof(SR.ErrorProviderIconDescr))]
577573
public Icon Icon
578574
{
579-
get
580-
{
581-
return _icon;
582-
}
575+
get => _icon ??= DefaultIcon;
583576
set
584577
{
585578
_icon = value.OrThrowIfNull();
@@ -592,10 +585,21 @@ public Icon Icon
592585
}
593586
}
594587

588+
/// <summary>
589+
/// Gets or sets the DPI at which the current error is displayed.
590+
/// If currentDpi is not set, it defaults to _parentControl.DeviceDpi
591+
/// or the system DPI.
592+
/// </summary>
593+
private int CurrentDpi
594+
{
595+
get => _currentDpi != 0 ? _currentDpi : _parentControl?.DeviceDpi ?? DpiHelper.DeviceDpi;
596+
set => _currentDpi = value;
597+
}
598+
595599
/// <summary>
596600
/// Create the icon region on demand.
597601
/// </summary>
598-
internal IconRegion Region => _region ??= new IconRegion(Icon);
602+
internal IconRegion Region => _region ??= new IconRegion(Icon, CurrentDpi);
599603

600604
/// <summary>
601605
/// Begin bulk member initialization - deferring binding to data source until EndInit is reached
@@ -769,7 +773,7 @@ internal ErrorWindow EnsureErrorWindow(Control parent)
769773
[SRDescription(nameof(SR.ErrorProviderIconPaddingDescr))]
770774
public int GetIconPadding(Control control) => EnsureControlItem(control).IconPadding;
771775

772-
private void ResetIcon() => Icon = DefaultIcon;
776+
private void ResetIcon() => _icon = null;
773777

774778
[EditorBrowsable(EditorBrowsableState.Advanced)]
775779
protected virtual void OnRightToLeftChanged(EventArgs e)
@@ -814,5 +818,5 @@ public void SetIconPadding(Control control, int padding)
814818
EnsureControlItem(control).IconPadding = padding;
815819
}
816820

817-
private bool ShouldSerializeIcon() => Icon != DefaultIcon;
821+
private bool ShouldSerializeIcon() => _icon is not null && _icon != DefaultIcon;
818822
}

0 commit comments

Comments
 (0)