3

我想要一个函数,它采用 Windows 中的任何文件路径(任何文件系统对象——文件、文件夹、驱动器、快捷方式等)并返回关联的 .ICO 文件(或带有所有图像大小表示的图标的一些句柄) . 例如,如果我在 Windows 7 中指定了“C:\MyTextFile.txt”,我将在位于 imageres 的 .ICO 文件中获得 .txt 文件的所有 256x256、48x48、32x32 和 16x16 表示。偏移量 102 处的 dll:

imageres.dll 中的文本文件图标

^ Stardock IconPackager 安装的图标选项卡,用于定位文件系统对象的图标

从我目前的研究来看,这似乎并不容易。有这个ExtractIconEx功能,但它只给出 16 和 32 像素的表示。还有这篇文章展示了如何获取SHIL_SMALLSHIL_LARGESHIL_EXTRALARGESHIL_JUMBO尺寸,它们通常分别为 16、32、48 和 256 像素。但是,这并不一定涵盖将存储在 .ICO 文件中的其他大小。例如,一些图标存储 10 个或更多不同的大小,而不仅仅是四个。

所以,我试图:

  1. 找到文件系统对象图标的位置,然后
  2. 从 DLL、EXE 或任何封装它的资源中检索它。

我想一个问题是:这是 Windows 注册表的任务吗?如下所示,注册表的 txtfile->DefaultIcon 值包含 .txt 文件类型的图标位置。

Windows 注册表中的 txt 文件

但是,也有独立的 .exe 文件,例如,它包含一个不会存储在注册表中的图标。

最终,我想在一个 TImage 中显示所有不同的大小,并可能将它们一起输出到一个 .ICO 文件中。任何帮助,将不胜感激。

4

1 回答 1

4

作为一个选项,有一个IShellItemImageFactory界面提供有关IShellItem(文件)缩略图的信息。这个界面可以返回所需的大小,但它需要一些图标透明度的魔力。有 2 个选项 - 缩略图或图标。因为Folder 它总是返回相同的图像(更新:不是真的,文件夹缩略图还包含文件的小预览,它包含)。但例如,png它返回带有标志的小预览图像和带有thumbnail标志的 png-image-icon icon(0 是默认值)。对于您的任务,您应该使用SIIGBF_ICONONLY标志来获取文件/文件夹/驱动器系统图标。

这是示例代码,它加载不同大小的图像。

type
    TIconSize = (is16, is32, is48, is64, is96, is128, is256);
const
    ICON_SIZE : array[TIconSize] of integer = (16,32,48,64,96,128,256);

我在表格上添加了SizeRadioGroup : TRadioGroupImage1 : TImageImage1.Size设置为 256。SizeRadioGroup 单击事件处理程序将缩略图加载到Image1

procedure TForm7.SizeRadioGroupClick(Sender: TObject);
const FILE_NAME = 'd:\_projects\';
var icoSize : TIconSize;
    wh : integer;
    siif : IShellItemImageFactory;
    size : TSize;
    icon_handle : HBitmap;
    bm : TBitmap;
begin
    icoSize := TIconSize(SizeRadioGroup.ItemIndex);
    wh := ICON_SIZE[icoSize];

    SHCreateItemFromParsingName(FILE_NAME, nil, IID_IShellItemImageFactory, siif);

    size.cx := wh;
    size.cy := wh;

    siif.GetImage(size, 0 {SIIGBF_THUMBNAILONLY}{SIIGBF_ICONONLY}, icon_handle);
    bm := TBitmap.Create();
    bm.PixelFormat := pf32bit;
    try
        bm.Handle := icon_handle;
        Image1.Picture.Assign(bm);
    finally
        bm.Free();
    end;
end;
于 2013-02-27T07:34:00.730 回答