如何在Windows中获取任何文件的关联图标(.ICO),并在Delphi中显示所有图标图像大小?

如何在Windows中获取任何文件的关联图标(.ICO),并在Delphi中显示所有图标图像大小?,delphi,file,icons,Delphi,File,Icons,我想要一个函数,它可以在Windows中获取任何文件路径(任何文件系统对象——文件、文件夹、驱动器、快捷方式等),并返回相关的.ICO文件(或具有所有图像大小表示的图标句柄)。例如,如果我在Windows 7中指定了“C:\MyTextFile.txt”,我将在.ICO文件中获得.txt文件的所有256x256、48x48、32x32和16x16表示形式,该文件位于imageres.dll的偏移量102处: ^Stardock IconPackager安装的图标选项卡,用于定位文件系统对象的图

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

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

从我目前的研究来看,这似乎不是那么容易。有
ExtractIconEx
函数,但它只给出16和32px表示。还有一个演示如何获得
SHIL_SMALL
SHIL_LARGE
SHIL_extralge
SHIL_JUMBO
大小,通常分别为16、32、48和256像素。但是,这并不一定包括存储在.ICO文件中的其他大小。例如,一些图标存储10个或更多不同的大小,而不仅仅是4个

因此,我试图:

  • 查找文件系统对象图标的位置,然后
  • 从DLL、EXE或任何封装它的资源中检索它
  • 我想一个问题是:这是Windows注册表的任务吗?如下所示,注册表的txtfile->DefaultIcon值包含.txt文件类型的图标位置

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


    最后,我希望在一个时间段内显示所有不同大小的文件,并可能将它们一起输出到一个.ICO文件中。任何帮助都将不胜感激。

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

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

    type
        TIconSize = (is16, is32, is48, is64, is96, is128, is256);
    const
        ICON_SIZE : array[TIconSize] of integer = (16,32,48,64,96,128,256);
    
    我在表单上添加了
    SizeRadioGroup:TRadioGroup
    Image1:TImage
    <代码>图像1。大小设置为256
    SizeRadioGroup
    单击事件hanlder将缩略图加载到
    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;
    

    谢谢你的这种方法。缩略图很棒,但我真的不想要缩略图。例如,对于JPEG文件,我希望使用.jpg文件类型图标,而不是.jpg图像的缩略图。其他图像、视频等文件也是如此。@spurgeon使用
    SIIGBF_图标作为文件类型图标的
    GetImage
    方法调用中的第二个参数。它只获得图标,但有透明度的问题(可能在
    TImage
    设置中有一些魔力)啊,对不起,不知怎的错过了。事实上,返回的图标大小不同,但背景黑得令人讨厌。我曾经用alpha在画布上绘制位图,效果很好。但是,该程序在XP上崩溃,即使我将代码剥离到上面的IShellItemImageFactory。错误是“外部异常c06d007f”。有什么想法吗?它适用于WindowsVista和Windows7+1作为答案,但我不能接受关于获取.ICO文件的原始问题的b/c。是的,似乎IShellItemImagefactory在WinXP中不受支持,只有Vista和更高版本;