首页 > 解决方案 > 如何使用 LoadImage 选择图标颜色深度?

问题描述

我想加载并显示其中一个explorer.exe图标。

我使用以下代码(缩写):

// resource id definition    

EXP_ICON    = MAKEINTRESOURCE(101);      { Explorer's Icon resource ID      }

// load explorer.exe

ExpInstance := LoadLibraryEx(ExpDirectory,
                             0,
                             LOAD_LIBRARY_AS_IMAGE_RESOURCE);

// load the icon from it

ExpIcon := LoadImage(ExpInstance,
                     MAKEINTRESOURCE(EXP_ICON),
                     IMAGE_ICON,            { load the icon  }
                     32,
                     32,
                     LR_LOADREALSIZE);

该代码加载它找到的第一个图标,它恰好是一个 16 色图标。该组中还有其他具有更多颜色的图标(256 和 1600 万)。

我的问题是:是否可以告诉LoadImage()加载其中一个图标(使用更多颜色的图标),如果可以,如何加载?

我尝试更改EXP_ICON为图标序号 ID 之一,但如果 ID 不是图标的 ID ,LoadImage()则不会成功。

我没有想法LoadImage()用我想要的颜色数量加载一个图标。

标签: winapi

解决方案


LoadImage旨在自动加载具有您请求大小的最合适颜色位深度的图标。“最合适”是指与您当前的显示设置最匹配的那个。这几乎总是您想要的,因此该功能是“Just Works”的功能之一。告诉它你想要什么尺寸(像素尺寸)图标,它会处理其余的。无法告诉它您要使用哪种颜色位深度。

如果没有那个大小的图标,它会放大一个较小的图标。由于这并不理想,最近版本的 Windows 提供了LoadIconWithScaleDownAPI,它完全按照它在锡上所说的那样做。这会产生更好看的结果。有关用法示例,请参见此处的 David Heffernan 的回答。

反正。您的问题与LoadImage功能无关。问题是LR_LOADREALSIZE您传递给函数的标志。我在 Windows SDK 头文件中找不到该常量的定义,但它看起来像是由 Delphi 或 C++ Builder 库定义的。定义类似于:

LR_LOADREALSIZE = $80;

或者

#define LR_LOADREALSIZE (Byte)(128)

它是一个十六进制值为 0x80 的常数。问题是,当您查看function的文档LoadImage时,您会看到 0x80 的十六进制值实际上是常量LR_VGACOLOR

LR_VGACOLOR
0x00000080

使用真正的 VGA 颜色。

这里的描述有点倾斜——你必须知道什么是“真正的 VGA 颜色”。最初的 VGA 是 16 色显示系统,这就是这里的意思。因此,您将获得 16 色版本的图标,因为您特别需要它。删除LR_LOADREALSIZE标志(实际上是LR_VGACOLOR标志),一切都会正常工作。只需0作为标志传递(或LR_DEFAULTCOLOR,定义为 0)。

注意:您不应该像 32 那样硬编码像素尺寸。相反,您应该使用and标志调用GetSystemMetrics函数。这些将为您提供系统上“正常”大小图标的实际大小。“通常”,这些图标的大小为 32x32 像素,但这并不能保证,尤其是在当前的高 DPI 显示器时代。它们可能更大。如果您想要小图标(通常为 16x16),请改用and 。SM_CXICONSM_CYICONSM_CXSMICONSM_CYSMICON

在极少数情况下,您实际上想要从具有特定颜色位深度的资源或 ICO 文件加载图标,并且不让系统自动确定要加载的颜色深度,您必须使用如下顺序手动加载它FindResourceLoadResourceLockResourceCreateIconFromResourceEx。另请参阅MSDN 上John Hornick的“Icons”(一篇旧文章,但仍然准确),以及Raymond Chen 的这篇博文。


推荐阅读