3

Windows の任意のファイル パス (任意のファイル システム オブジェクト - ファイル、フォルダー、ドライブ、ショートカットなど) を取り、関連する .ICO ファイル (またはすべての画像サイズ表現を含むアイコンへのハンドル) を返す関数が必要です。 . たとえば、Windows 7 で「C:\MyTextFile.txt」を指定した場合、.txt ファイルの 256x256、48x48、32x32、および 16x16 表現のすべてが、imageres にある .ICO ファイルに取得されます。オフセット 102 の dll:

imageres.dll のテキスト ファイル アイコン

^ Stardock IconPackager によってインストールされる [アイコン] タブ。ファイル システム オブジェクトのアイコンが表示されます。

これまでの私の研究から、それはそれほど簡単ではないようです。関数がありExtractIconExますが、16 ピクセルと 32 ピクセルの表現しか提供しません。、、、およびサイズを取得する方法を示すこの投稿もあります。これらは通常、それぞれ 16、32、48、および 256 ピクセルです。ただし、.ICO ファイルに格納される他のサイズも必ずしもカバーするとは限りません。たとえば、一部のアイコンには、4 つだけではなく 10 個以上の異なるサイズが格納されます。SHIL_SMALLSHIL_LARGESHIL_EXTRALARGESHIL_JUMBO

だから、私はしようとしています:

  1. ファイル システム オブジェクトのアイコンの場所を見つけ、
  2. DLL、EXE、またはそれをカプセル化するリソースから取得します。

これは Windows レジストリのタスクですか? 以下に示すように、レジストリの txtfile->DefaultIcon 値には、.txt ファイル タイプのアイコンの場所が含まれています。

Windows レジストリの txtfile

ただし、スタンドアロンの .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 : TImageました。Image1.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 に答える