4

Delphi 2009を使用して、ランチャーを作成しようとしています。それを「スナッピー」にするために、私は本当にバックグラウンドスレッドにアイコンをロードしたいと思います。

ここにある解決策を使用しました: Vista Shellから48x48または64x64のアイコンを取得できますか?

スレッドで実行されない場合、これは正常に機能します。スレッドに入れるとすぐに、一部のアイコンが「フェッチ」されないか、ある種の一般的なアイコンになります。スレッドをシリアル化してみましたが(事実上、それらを廃止しました)、同じ結果が得られました。

したがって、質問は次のとおりです。スレッドにアイコン(リンクされた例と同じ使用可能なオプションを使用)をロードするにはどうすればよいですか?

/ラース

編集:GetIconFromFileにいくつかの非常に基本的なエラーチェックを追加しました

if SHGetFileInfo( PChar( aFile ),
                FILE_ATTRIBUTE_NORMAL,
                SFI,
                SizeOf( TSHFileInfo ),
                SHGFI_ICON
                  or SHGFI_LARGEICON
                  or SHGFI_SHELLICONSIZE
                  or SHGFI_SYSICONINDEX
                  or SHGFI_TYPENAME
                  or SHGFI_DISPLAYNAME ) <> 0 then
begin
  if not Assigned( aIcon ) then
    aIcon := TIcon.Create;
  aImgList := GetImageListSH( SHIL_FLAG );
  aIndex := SFI.iIcon;
  if aImgList <> 0 then
    aIcon.Handle := ImageList_GetIcon( aImgList, aIndex, ILD_NORMAL );
end;

これは何の違いもありません。私はまだいくつかの一般的なアイコンを取得しています(ただし、これがスレッドで呼び出された場合のみ)

Edit2:スレッデッドコード(非常に単純):

procedure TIconLoader.Execute;
var
  Item : TGridItem;
  I : TIcon;
begin
  inherited;

  while not terminated do
  begin
    Item := nil;
    if assigned(FOnNeedGridItem) then
    begin
      Synchronize(
          procedure
          begin
            FOnNeedGridItem(Self, Item);
          end
      );
    end;

    if assigned(Item) then
    begin
      GetIconFromFile(Item.FFilename, I, SHIL_EXTRALARGE);
      Synchronize(
          procedure
          begin
            Item.SetIcon(I);
          end
      );
//      I.Free;
    end
    else
      Terminate;
  end;
end;
4

3 に答える 3

2

のドキュメントでSHGetFileInfoは、関数を呼び出す前にCOMを初期化する必要があると指定されています。COMの初期化はスレッドごとであるため、スレッドでCOMを初期化する必要があります。これは、スレッドのメソッドを呼び出すCoInitializeCoInitializeEx、メソッドから呼び出すことを意味します。Execute

于 2012-07-10T06:23:08.107 に答える
0

Delphi 2009で導入されたTThread.Queueメソッドを使用して、スレッドコードを単純化できるかもしれません。

いくつかの例と背景情報を提供する記事はここにあります:

パラメータと同期してキューに入れる

TThread.Queueは非ブロッキングです。これにより、すべてのアイコンのバックグラウンドワーカースレッドを順番に作成し、非同期で読み込むことができます。

于 2012-07-09T17:50:41.327 に答える
-1

これを動かしてみてください:

GetIconFromFile(Item.FFilename, I, SHIL_EXTRALARGE);

synchronizeブロックに。また、を使用した後はDestroyIcon()を呼び出す必要がありますSHGetFileInfo()

于 2012-07-10T01:25:49.490 に答える