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

Sci*_*eur 2 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);
Run Code Online (Sandbox Code Playgroud)

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

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

我已尝试更改EXP_ICON为其中一个图标序号ID,但如果该ID不是图标的ID ,LoadImage()则不会成功.

我没有想法让LoadImage()加载成为我想要的颜色数量的图标.

Cod*_*ray 7

LoadImage用于自动加载具有您请求大小的最合适颜色位深度的图标."最合适",我指的是与当前显示设置最匹配的那个.这几乎总是你想要的,所以功能就是"Just Works"之一.告诉它你想要什么尺寸(像素尺寸)图标,它处理其余的.没有办法告诉它你想要使用哪种颜色位深度.

如果没有该尺寸的图标,则会缩小较小的图标.由于这并不理想,最新版本的Windows提供了LoadIconWithScaleDownAPI,它完全按照它在锡上所说的那样做.这会产生更好看的效果.有关用法示例,请参阅David Heffernan的答案.

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

LR_LOADREALSIZE = $80;
Run Code Online (Sandbox Code Playgroud)

要么

#define LR_LOADREALSIZE (Byte)(128)
Run Code Online (Sandbox Code Playgroud)

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

LR_VGACOLOR
0x00000080

使用真正的VGA颜色.

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

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

在极少数情况下,您实际上要从具有特定颜色位深度的资源或ICO文件加载图标,而不是系统自动确定要加载的颜色深度,您必须使用类似FindResource→ 的序列手动加载它LoadResource→交通LockResource→交通CreateIconFromResourceEx.另请参阅John Hornick在MSDN上的"图标"(一篇旧文章,但对于这些内容仍然准确),以及Raymond Chen撰写的这篇博客文章.