我想定义Win32窗口的应用程序图标,例如通过使用SetClassLong
调用GCL_HICON
并将句柄传递给图标(请参阅MSDN上的SetClassLong Function)。
这很好用,但我还没弄明白我应该如何加载图标(来自ICO文件)以保持所有可用尺寸(例如16x16,32x32,48x48和全尺寸PNG图标)。当我通过LoadImage
将图标文件加载到内存中以获取HICON
时,我必须指定我想要的尺寸(请参阅我的reply to a related question)。
我的ICO文件包含一个小尺寸的图像,应该用作窗口图标(标题栏的左上角),并且设计得非常清晰,但也应该在Alt-Tab中显示更大的变体对话,但......
加载16x16图标会在标题栏中显示正确的图标,但是 - 当然 - 当我使用Alt-Tab时,它是一个丑陋的拉伸版本。任务栏中显示的那个也不是很漂亮。
加载48x48图标会在我的Alt-Tab时显示一个漂亮的图标,但标题栏中显示的图标模糊,因为它是48x48图标的缩小版本。
< / LI> 醇>有没有办法告诉Windows我的Windows有一个多尺寸的图标?是否有一些我错过的明显的API?
答案 0 :(得分:4)
.ICO文件中包含多个图像。但是HICON只是这些图像的一个。如果您使用LR_DEFAULTSIZE,那么可能会有一些神奇的行为保留到.ico文件的链接并使用相应的图像,但我对此表示怀疑。
如果不这样做,那么什么都不会。
HICON hicon = LoadImage(NULL, "filename.ico", IMAGE_ICON,
0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
一点背景。
当.ico文件包含在应用程序的资源中时,该文件将被打开,文件中的每个图像都将成为单独的资源。文件头被修改,它成为ICON资源。因此,当LoadIcon / LoadImage传递ICON资源的资源ID时,它实际上是传递其他资源的目录。它会在该时间点选择符合请求的图像并将其转换为HICON。实际执行此操作的函数称为LookupIconIdFromDirectory
这就是为什么当你为{HICON GetIconInfo时,你只能获得一个ICONINFO结构。
typedef struct _ICONINFO {
BOOL fIcon;
DWORD xHotspot;
DWORD yHotspot;
HBITMAP hbmMask;
HBITMAP hbmColor;
} ICONINFO;
答案 1 :(得分:2)
GCL_HICON设置“大”图标,GCL_HICONSM设置小图标(大小通常为32x32和16x16,但你应该使用带有SM_CXICON和SM_CXSMICON的GetSystemMetrics来查找实际大小(对于大图标,你也可以只传递LR_DEFAULTSIZE到0大小的LoadImage))
答案 2 :(得分:1)
如果.ico
文件不包含256x256全尺寸PNG图标,那么当我写简单时,Windows似乎很高兴:
var assembly = typeof (Xyz).Assembly;
var stream = assembly.GetManifestResourceStream ("Foo.Resources.Form.ico");
var icon = new System.Drawing.Icon (stream);
form.Icon = icon;
有了这个,并且名为Form.ico
的图标放在我的程序集的Resources
文件夹中,其Foo
作为其默认名称空间,Windows将使用32x32版本的使用Alt-Tab进行任务栏和任务切换的图像,以及窗口标题的16x16版本。
因此,在使用WinForms'Form.Icon
时要小心PNG图标......