我想用SystemIcons.Warning它,但它太大了我的需要.我想调整它的大小.
我试过了 :
Icon sizedIcon = new Icon(SystemIcons.Warning, new Size(10,10));
Run Code Online (Sandbox Code Playgroud)
但它不起作用,图标保持不变.
有什么建议?
在.NET Icon类是相当残缺,它是停留在过去十年中由于一次相关支持Windows 98和Windows 2000在此之上,Windows不支持任何尺寸装载系统图标其他较系统的默认图标大小.通常为32x32.调整它的大小将不可避免地看起来很糟糕.
请记住,没有任何图标在10x10时看起来不错.它只是现代显示器上的一个斑点.你可以通过一个接近所需最终尺寸的图标大小开始,但是所需调整大小越小,它看起来仍然合理的几率就越大.如果可以,请选择可能出现在图标中的尺寸.像16x16,32x32,48x48.
Anyhoo,这是可以修复的.请记住,这需要相当多的hack-o-rama,因为Windows不直接支持这一点.所需要的是直接从系统DLL资源中读取图标.使用更现代的winapi,LoadImage()而不是.NET使用的那个,LoadIcon().适用于XP及以上版本.
在项目中添加一个新类并粘贴此代码:
using System;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
public class IconEx : IDisposable {
public enum SystemIcons {
Application = 100,
Asterisk = 104,
Error = 103,
Exclamation = 101,
Hand = 103,
Information = 104,
Question = 102,
Shield = 106,
Warning = 101,
WinLogo = 100
}
public IconEx(string path, Size size) {
IntPtr hIcon = LoadImage(IntPtr.Zero, path, IMAGE_ICON, size.Width, size.Height, LR_LOADFROMFILE);
if (hIcon == IntPtr.Zero) throw new System.ComponentModel.Win32Exception();
attach(hIcon);
}
public IconEx(SystemIcons sysicon, Size size) {
IntPtr hUser = GetModuleHandle("user32");
IntPtr hIcon = LoadImage(hUser, (IntPtr)sysicon, IMAGE_ICON, size.Width, size.Height, 0);
if (hIcon == IntPtr.Zero) throw new System.ComponentModel.Win32Exception();
attach(hIcon);
}
public Icon Icon {
get { return this.icon; }
}
public void Dispose() {
if (icon != null) icon.Dispose();
}
private Icon icon;
private void attach(IntPtr hIcon) {
// Invoke the private constructor so we can get the Icon object to own the handle
var ci = typeof(Icon).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance,
null, new Type[] { typeof(IntPtr), typeof(bool) }, null);
this.icon = (Icon)ci.Invoke(new object[] { hIcon, true});
}
private const int IMAGE_ICON = 1;
private const int LR_LOADFROMFILE = 0x10;
private const int LR_SHARED = 0x8000;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr GetModuleHandle(string name);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr LoadImage(IntPtr hinst, string lpszName, int uType,
int cxDesired, int cyDesired, int fuLoad);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr LoadImage(IntPtr hinst, IntPtr resId, int uType,
int cxDesired, int cyDesired, int fuLoad);
}
Run Code Online (Sandbox Code Playgroud)
样品用法:
using (var icon = new IconEx(IconEx.SystemIcons.Warning, new Size(10, 10))) {
e.Graphics.DrawIcon(icon.Icon, 0, 0);
}
Run Code Online (Sandbox Code Playgroud)
它确实看起来比SystemIcons.Warning更好.当你使用16x16时,它是干净的.
| 归档时间: |
|
| 查看次数: |
2175 次 |
| 最近记录: |