如何在窗口上设置HICON(多种尺寸的.ICO)?

我想定义一个Win32窗口的应用程序图标,例如,通过使用GCL_HICON调用GCL_HICON并传递一个图标的句柄(参见MSDN上的SetClassLong函数 )。

这很好,但我还没有想出我应该如何加载一个图标(从一个ICO文件),以保持所有可用的大小(例如16×16,32×32,48×48和全尺寸的PNG图标)。 当我通过LoadImage将图标文件LoadImage到内存中以获取HICON ,我必须指定我想要的大小(请参阅我对相关问题的回复 )。

我的ICO文件包含一个小尺寸的图像,它应该被用作窗口图标(标题栏的左上angular),并且devise得非常清晰,但是也应该在Alt-Tab对话框中显示更大的变体,但是…

  1. 加载16×16图标在标题栏中显示正确的图标,但是 – 当然 – 当我按Alt-Tab时,它是一个难看的拉伸版本。 而在任务栏中显示的那个也不是很漂亮。

  2. 加载48×48图标时,按Alt-Tab时会显示一个漂亮的图标,但标题栏中显示的图标是模糊的,因为它是48×48图标的缩小版本。

有什么办法告诉Windows,我的Windows有一个多尺寸的图标? 有没有我错过的一些明显的API?

GCL_HICON设置“大”图标,GCL_HICONSM设置小图标(大小通常是32×32和16×16,但是您应该使用GetSystemMetrics和SM_CXICON和SM_CXSMICON来查找实际大小(对于大图标,您也可以将LR_DEFAULTSIZE传递给LoadImage) 0尺寸))

.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; 

如果.ico文件不包含256×256全尺寸的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将使用32×32版本的图像作为任务栏,并使用Alt-Tab切换任务,和窗口标题的16×16版本。

所以,当使用WinForms的Form.Icon时要小心PNG图标…