I have used the library v 6.6.0 in a WinForm application, in which I have enabled the DPI awareness.
The app is running on Windows 11.
Both IconButton and IconPictureBox suffer of the same issue when the form is displayed on a screen with scaling >250% (in my case a 6K screen at 400% and a 4K screen at 300%), while there are no issues with scaling <=250%.
The issue is that when there is such high scaling, the font that should be drawn on screen within the DrawIcon() function
has a width = 0 hence nothing is plotted. (within the GetTopLeft() function the var iconSize = graphics.GetIconSize(text, font, size); has width = 0).
I have downloaded the github source code and I have tried making this change to the code into the function (FormsIconHelper.cs) to try to fix it. The result could be better (depending on the size used for the font in GetAdjustedIconFont), but at least the icon is displayed.
public static Bitmap ToBitmap(this FontFamily fontFamily, TEnum icon,
int width, int height, Color? color = null,
double rotation = 0.0, FlipOrientation flip = FlipOrientation.Normal)
where TEnum : struct, IConvertible, IComparable, IFormattable
{
float f = NativeMethods.GetDpiRatio(IntPtr.Zero);
int wf = width;
int hf = height;
if (f >= 3.0) // scaling >= 300%
{
f *= 2; // empirically determined;
wf = (int)(((float)wf) / f);
hf = (int)(((float)hf) / f);
}
var bitmap = new Bitmap(width, height);
using (var graphics = Graphics.FromImage(bitmap))
{
var text = icon.ToChar();
Font font;
SizeF iconSize;
// find the first font with a non zero size <= of the requested size
do
{
font = graphics.GetAdjustedIconFont(fontFamily, text, new SizeF(wf, hf));
iconSize = graphics.GetIconSize(text, font, new SizeF(wb, hb));
//System.Windows.Forms.MessageBox.Show(string.Format("f {2}, width = {0}, wf = {1}", iconSize.Width, wf, f));
wf = (int)(((float)wf) / f);
hf = (int)(((float)hf) / f);
} while ((iconSize.Width == 0) || (iconSize.Height == 0));
graphics.Rotate(rotation, width, height);
var brush = color.HasValue ? new SolidBrush(color.Value) : DefaultBrush;
DrawIcon(graphics, font, text, width, height, brush);
}
bitmap.Flip(flip);
return bitmap;
}
the dpi ratio is evaluated using the following code I have added to nativemethods.cs
public enum DpiType
{
Effective = 0,
Angular = 1,
Raw = 2,
}
I have used the library v 6.6.0 in a WinForm application, in which I have enabled the DPI awareness. The app is running on Windows 11.
Both IconButton and IconPictureBox suffer of the same issue when the form is displayed on a screen with scaling >250% (in my case a 6K screen at 400% and a 4K screen at 300%), while there are no issues with scaling <=250%.
The issue is that when there is such high scaling, the font that should be drawn on screen within the DrawIcon() function has a width = 0 hence nothing is plotted. (within the GetTopLeft() function the var iconSize = graphics.GetIconSize(text, font, size); has width = 0).
I have downloaded the github source code and I have tried making this change to the code into the function (FormsIconHelper.cs) to try to fix it. The result could be better (depending on the size used for the font in GetAdjustedIconFont), but at least the icon is displayed.
public static Bitmap ToBitmap(this FontFamily fontFamily, TEnum icon,
int width, int height, Color? color = null,
double rotation = 0.0, FlipOrientation flip = FlipOrientation.Normal)
where TEnum : struct, IConvertible, IComparable, IFormattable
{
float f = NativeMethods.GetDpiRatio(IntPtr.Zero);
}
the dpi ratio is evaluated using the following code I have added to nativemethods.cs
public enum DpiType { Effective = 0, Angular = 1, Raw = 2, }
public static uint GetDpi(IntPtr hwnd, DpiType dpiType) { var screen = Screen.FromHandle(hwnd); var pnt = new Point(screen.Bounds.Left + 1, screen.Bounds.Top + 1); var mon = MonitorFromPoint(pnt, 2 /MONITOR_DEFAULTTONEAREST/);
}
public static float GetDpiRatio(IntPtr hwnd) { var dpi = GetDpi(hwnd, DpiType.Effective); float ratio = 1; if (dpi > 96) ratio = (float)dpi / 96F;
}