如何使用LoadImage选择图标颜色深度?

时间:2019-02-10 20:28:30

标签: winapi

我想加载并显示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不是图标 group 的ID,则LoadImage()不会成功。 / p>

我没办法让LoadImage()加载一个具有所需颜色数量的图标。

1 个答案:

答案 0 :(得分:7)

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

如果没有该尺寸的图标,它将放大一个较小的图标。由于这不是理想的选择,因此Windows的最新版本提供了LoadIconWithScaleDown API,其功能完全符合其提示。这样会产生更好的结果。有关用法示例,请参见David Heffernan's answer here

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

LR_LOADREALSIZE = $80;

#define LR_LOADREALSIZE (Byte)(128)

它是一个常量,十六进制值为0x80。问题是,当您查看the documentation for the LoadImage function时,发现十六进制值0x80实际上是 常数LR_VGACOLOR

  

LR_VGACOLOR
  0x00000080

     

使用真实的VGA颜色。

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

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

在极少数情况下,您实际上想从资源或ICO文件中加载具有特定颜色位深的图标,并且又没有让系统自动确定要加载的颜色深,您必须使用FindResourceLoadResourceLockResourceCreateIconFromResourceEx之类的序列。另请参见MSDN上的"Icons" by John Hornick(较旧的文章,但对于本文来说还是准确的)和this blog post by Raymond Chen