代码之家  ›  专栏  ›  技术社区  ›  Pierre Arnaud

如何在窗口上设置Hicon(.ico,多个大小)?

  •  3
  • Pierre Arnaud  · 技术社区  · 15 年前

    我想定义Win32窗口的应用程序图标,例如通过调用 SetClassLong 具有 GCL_HICON 并将句柄传递给图标(请参见 SetClassLong Function 在MSDN上)。

    这很好,但我还没有弄清楚如何加载图标(从ICO文件)以保持所有可用大小(例如16x16、32x32、48x48和全尺寸PNG图标)。当我加载图标文件时 LoadImage 在记忆中得到 HICON ,我必须指定我想要的尺寸(参见 reply to a related question )

    我的ICO文件包含一个小尺寸的图像,它应该被用作窗口图标(标题栏的左上角),并且被设计成非常清晰,但也有更大的变体,应该显示在alt选项卡对话框中,但是…

    1. 加载16x16图标会在标题栏中显示正确的图标,但是-当然-当我切换选项卡时,它是一个丑陋的拉伸版本。而出现在任务栏中的那个也不是很漂亮。

    2. 加载48x48图标会在“我选择”选项卡时显示一个不错的图标,但在标题栏中显示的图标是模糊的,因为它是48x48图标的缩小版本。

    有什么方法可以告诉Windows我的Windows有一个多尺寸图标吗?是否有一些明显的API我错过了?

    3 回复  |  直到 11 年前
        1
  •  2
  •   Anders    15 年前

    gcl-hicon设置“大”图标,gcl-hicon sm设置小图标(大小通常为32x32和16x16,但您应该使用带有sm-cxicon和sm-cxsmicon的getSystemMetrics来查找实际大小(对于大图标,您也可以将lr-defaultsize传递给0大小的loadImage)。

        2
  •  4
  •   John Knoeller    15 年前

    一个.ico文件中有多个图像。但是一个希肯只是 这些图像。如果您使用lr_DefaultSize,那么可能会有一些神奇的行为保留到.ico文件的链接,并使用来自该文件的适当图像,但我对此表示怀疑。

    如果这样做不行,那就什么也做不了。

    HICON hicon = LoadImage(NULL, "filename.ico", IMAGE_ICON, 
                            0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
    

    有点背景。

    当一个.ico文件包含在一个应用程序的资源中时,该文件就会被破解打开,文件中的每个图像都会变成一个 分离 资源。文件头将被修改,并成为图标资源。因此,当loadicon/loadimage传递图标资源的资源ID时,它实际上是传递给其他资源的目录。它选择符合请求的图像 在那个时候 把它变成一个希肯。实际执行此操作的函数被调用 LookupIconIdFromDirectory

    这就是为什么当你 GetIconInfo 对于一个希肯人,你只能得到一个ICONINFO结构。

    typedef struct _ICONINFO {
        BOOL fIcon;
        DWORD xHotspot;
        DWORD yHotspot;
        HBITMAP hbmMask;
        HBITMAP hbmColor;
    } ICONINFO;
    
        3
  •  1
  •   Pierre Arnaud    11 年前

    如果 .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选项卡,使用16x16版本作为窗口标题。

    因此,在将PNG图标与WinForms一起使用时要小心它。 Form.Icon