在德尔福图标螺纹装(Threaded loading of icons in Delphi)

2019-07-30 07:53发布

用Delphi 2009年,努力使发射器。 为了使“活泼”我真的想加载图标在后台线程。

我用在这里找到了解决办法: 可以48×48或64×64的图标从Vista的壳牌获得的?

这工作得很好,如果不是在一个线程中运行。 当我把它放在一个线程,一些图标都没有“取”,或者是某种通用的图标。 我甚至尝试序列化的线程(使它们obsolote,实际上),但它得到了相同的结果。

所以,问题是:如何加载图标(具有相同的可用选项的链接为例)在一个线程?

/拉尔斯

编辑:增加了一些非常基本的错误检查中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;

这不作任何diffenrence。 我仍然得到了一些通用的图标(只有当这种被称为一个线程,虽然)

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;

Answer 1:

对于文档SHGetFileInfo规定,必须在调用之前初始化COM。 由于COM初始化每个线程,你需要在线程中初始化COM。 这意味着调用CoInitializeCoInitializeExExecute的线程的方法。



Answer 2:

也许你可以通过使用德尔福2009年推出的TThread.Queue方法简化您的线程代码。

这给一些例子和背景信息的文章是在这里:

同步和队列与参数

TThread.Queue是非阻塞的。 这允许顺序创建您的所有图标的背景工作者线程,然后让他们异步加载。



Answer 3:

尝试移动这样的:

GetIconFromFile(Item.FFilename, I, SHIL_EXTRALARGE);

进入synchronize块。 你应该调用DestroyIcon()使用后SHGetFileInfo()



文章来源: Threaded loading of icons in Delphi