我想定义一个Win32窗口的应用程序图标,例如,通过使用GCL_HICON
调用GCL_HICON
并传递一个图标的句柄(参见MSDN上的SetClassLong函数 )。
这很好,但我还没有想出我应该如何加载一个图标(从一个ICO文件),以保持所有可用的大小(例如16×16,32×32,48×48和全尺寸的PNG图标)。 当我通过LoadImage
将图标文件LoadImage
到内存中以获取HICON
,我必须指定我想要的大小(请参阅我对相关问题的回复 )。
我的ICO文件包含一个小尺寸的图像,它应该被用作窗口图标(标题栏的左上angular),并且devise得非常清晰,但是也应该在Alt-Tab对话框中显示更大的变体,但是…
加载16×16图标在标题栏中显示正确的图标,但是 – 当然 – 当我按Alt-Tab时,它是一个难看的拉伸版本。 而在任务栏中显示的那个也不是很漂亮。
加载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图标…