Reputation: 1112
I would like a function that takes any file path in Windows (any file system object--file, folder, drive, shortcut, etc.) and returns the associated .ICO file (or some handle to the icon with all image size representations). For example, if I specified C:\MyTextFile.txt
in Windows 7, I would get all of the 256x256, 48x48, 32x32, and 16x16 representations for the .txt file in an .ICO file, which is located in imageres.dll at offset 102:
^ The Icon tab installed by Stardock IconPackager, which locates the icon for the file system object
From my research so far, it doesn't appear to be that easy. There's the ExtractIconEx
function, but it only gives the 16 and 32px representations. There's also this post that shows how to get the SHIL_SMALL
, SHIL_LARGE
, SHIL_EXTRALARGE
, and SHIL_JUMBO
sizes, which are generally 16, 32, 48, and 256 pixels respectively. However, that doesn't necessarily cover other sizes that would be stored in the .ICO file as well. For example, some icons store 10 or more different sizes rather than just four.
So, I'm trying to:
I guess one question would be: Is this a task for the Windows registry? As you can see below, the registry's txtfile->DefaultIcon value contains the location of the icon for the .txt file type.
But, there are also standalone .exe files, for example, that self-contain an icon that wouldn't be stored in the registry.
Ultimately, I'd like to display all of the different sizes within a TImage
and potentially output them together in an .ICO file. Any help would be appreciated.
Upvotes: 5
Views: 3493
Reputation: 3234
As an option, there is an IShellItemImageFactory
interface which provides information about IShellItem
(file) thumbnails. This interface can return desired sized, but it needs some magic with icons transparency. there are 2 options - thumbnails or icons. For Folder
it always return the same image (update: that not true, folder thumbnail also contains small previews of files, wich it contains). But for example for png
it returns small preview image with thumbnail
flag and png-image-icon with icon
flag (0 is default value). For your task you should use SIIGBF_ICONONLY
flag to get file/folder/drive system icons.
Here is sample code, which loads different sizes of image.
type
TIconSize = (is16, is32, is48, is64, is96, is128, is256);
const
ICON_SIZE : array[TIconSize] of integer = (16,32,48,64,96,128,256);
I added SizeRadioGroup : TRadioGroup
and Image1 : TImage
on the form. Image1.Size
is set to 256. SizeRadioGroup
click event hanlder loads thumbnail to 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;
Upvotes: 5