Reputation: 2767
In particular I'd like to be able to get the small (16 x 16) icons at runtime.
I tried this:
new Icon(SystemIcons.Error, SystemInformation.SmallIconSize)
Which supposedly "attempts to find a version of the icon that matches the requested size", but it's still giving me a 32 x 32 icon. I also tried:
Size iconSize = SystemInformation.SmallIconSize;
Bitmap bitmap = new Bitmap(iconSize.Width, iconSize.Height);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.DrawIcon(SystemIcons.Error, new Rectangle(Point.Empty, iconSize));
}
But that just scales the 32 x 32 icon down into an ugly 16 x 16.
I've considered just pulling icons out of the VS Image Library, but I really want them to vary dynamically with the OS (XP icons on XP, Vista icons on Vista, etc.). I'm willing to P/Invoke if that's what it takes.
Upvotes: 18
Views: 7951
Reputation: 5727
You have to scale them yourself. The SystemIcons, as you found out, only have 32x32. You can easily scale them to 16 or 48 as needed. Use interpolation to get a nice bicubic resize. We've done this many times successfully to create very nice looking 16x16 versions and it works fine whether running XP or Vista or 7.
Size iconSize = SystemInformation.SmallIconSize;
Bitmap bitmap = new Bitmap(iconSize.Width, iconSize.Height);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(SystemIcons.Error.ToBitmap(), new Rectangle(Point.Empty, iconSize));
}
Icon smallerErrorIcon = Icon.FromHandle(bitmap.GetHicon());
Be sure to check out the MSDN example here, especially their use of the DestroyIcon
method to clean up the handle when you're done.
Upvotes: 14
Reputation: 1858
The documentation for this constructor overload says:
"Initializes a new instance of the
Icon
class and attempts to find a version of the icon that matches the requested size."If a version cannot be found that exactly matches the size, the closest match is used. If the
original
parameter is anIcon
that has a single size, this method only creates a duplicate icon."
I think that this icon has only one size (32×32); and the only way to get different sizes is to scale this icon to your size, as in your example.
Upvotes: 1
Reputation: 2767
I wound up P/Invoking. It turns out that both LoadIcon and LoadImage exhibit the same (flawed, IMO) behavior as SystemIcons
. But SHGetStockIconInfo, which is available on Vista and later, works as expected, returning the small, official, designer-crafted icons that I've been looking for.
On XP and earlier, I'm falling back to using the small icons provided in the VS Image Library.
If you're thinking about P/Invoking SHGetStockIconInfo
yourself, I recommend taking a look at the Windows API Code Pack to see how.
Upvotes: 7