Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,17 @@ internal static HighDpiMode GetThreadHighDpiMode()
return HighDpiMode.DpiUnaware;
}

/// <summary>
/// Get X, Y metrics at DPI, IF icon is not already that size, create and return a new one.
/// </summary>
internal static Icon ScaleSmallIconToDpi(Icon icon, int dpi)
{
int width = PInvoke.GetCurrentSystemMetrics(SYSTEM_METRICS_INDEX.SM_CXSMICON, (uint)dpi);
int height = PInvoke.GetCurrentSystemMetrics(SYSTEM_METRICS_INDEX.SM_CYSMICON, (uint)dpi);

return (icon.Width == width && icon.Height == height) ? icon : new(icon, width, height);
}

/// <summary>
/// Sets the requested DPI mode. If the current OS does not support the requested mode,
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,8 @@ protected override void WmDpiChangedBeforeParent(ref Message m)
}

double factor = ((double)currentDpi) / _parent._deviceDpi;
using Icon icon = _provider.Icon;
Icon icon = _provider.Icon;
_provider.CurrentDpi = currentDpi;
_provider.Icon = new Icon(icon, (int)(icon.Width * factor), (int)(icon.Height * factor));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ internal class IconRegion : IHandle<HICON>
private Region? _region;
private readonly Icon _icon;

public IconRegion(Icon icon)
public IconRegion(Icon icon, int currentDpi)
{
_icon = new Icon(icon, ScaleHelper.LogicalSmallSystemIconSize);
_icon = ScaleHelper.ScaleSmallIconToDpi(icon, currentDpi);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ public partial class ErrorProvider : Component, IExtenderProvider, ISupportIniti
{
private readonly Dictionary<Control, ControlItem> _items = [];
private readonly Dictionary<Control, ErrorWindow> _windows = [];
private Icon _icon = DefaultIcon;
private Icon? _icon;
private IconRegion? _region;
private int _currentDpi;
private int _itemIdCounter;
private int _blinkRate;
private ErrorBlinkStyle _blinkStyle;
Expand Down Expand Up @@ -80,7 +81,6 @@ public ErrorProvider(IContainer container)
: this()
{
ArgumentNullException.ThrowIfNull(container);

container.Add(this);
}

Expand Down Expand Up @@ -308,7 +308,7 @@ public object? DataSource
{
if (_parentControl is not null && _parentControl.BindingContext is not null && value is not null && !string.IsNullOrEmpty(_dataMember))
{
// Let's check if the datamember exists in the new data source
// Let's check if the data member exists in the new data source
try
{
_errorManager = _parentControl.BindingContext[value, _dataMember];
Expand Down Expand Up @@ -546,10 +546,8 @@ private static Icon DefaultIcon
if (t_defaultIcon is null)
{
// Error provider uses small Icon.
int width = PInvokeCore.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CXSMICON);
int height = PInvokeCore.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CYSMICON);
using Icon defaultIcon = new(typeof(ErrorProvider), "Error");
t_defaultIcon = new Icon(defaultIcon, width, height);
Icon defaultIcon = new(typeof(ErrorProvider), "Error");
t_defaultIcon = ScaleHelper.ScaleSmallIconToDpi(defaultIcon, ScaleHelper.InitialSystemDpi);
}
}

Expand All @@ -567,10 +565,7 @@ private static Icon DefaultIcon
[SRDescription(nameof(SR.ErrorProviderIconDescr))]
public Icon Icon
{
get
{
return _icon;
}
get => _icon ??= DefaultIcon;
set
{
_icon = value.OrThrowIfNull();
Expand All @@ -583,10 +578,21 @@ public Icon Icon
}
}

/// <summary>
/// Gets or sets the DPI at which the current error is displayed.
/// If currentDpi is not set, it defaults to _parentControl.DeviceDpi
/// or the system DPI.
/// </summary>
private int CurrentDpi
{
get => _currentDpi != 0 ? _currentDpi : _parentControl?.DeviceDpi ?? ScaleHelper.InitialSystemDpi;
set => _currentDpi = value;
}

/// <summary>
/// Create the icon region on demand.
/// </summary>
internal IconRegion Region => _region ??= new IconRegion(Icon);
internal IconRegion Region => _region ??= new IconRegion(Icon, CurrentDpi);

/// <summary>
/// Begin bulk member initialization - deferring binding to data source until EndInit is reached
Expand Down Expand Up @@ -761,7 +767,7 @@ internal ErrorWindow EnsureErrorWindow(Control parent)
[SRDescription(nameof(SR.ErrorProviderIconPaddingDescr))]
public int GetIconPadding(Control control) => EnsureControlItem(control).IconPadding;

private void ResetIcon() => Icon = DefaultIcon;
private void ResetIcon() => _icon = null;

[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnRightToLeftChanged(EventArgs e)
Expand Down Expand Up @@ -814,5 +820,5 @@ public void SetIconPadding(Control control, int padding)
EnsureControlItem(control).IconPadding = padding;
}

private bool ShouldSerializeIcon() => Icon != DefaultIcon;
private bool ShouldSerializeIcon() => _icon is not null && _icon != DefaultIcon;
}