Delphi中图标的线程加载

Delphi中图标的线程加载,delphi,icons,delphi-2009,Delphi,Icons,Delphi 2009,使用Delphi2009,尝试制作一个启动器。 为了使它“快”我真的想加载一个背景线程图标 我使用了以下解决方案: 如果不是在线程中运行的话,这可以正常工作。 一旦我把它放到一个线程中,一些图标就不会被“抓取”,或者是某种通用图标。 我甚至尝试序列化线程(实际上,使其成为obsolote),但结果相同 因此,问题是: 如何在线程中加载图标(使用与链接示例相同的可用选项) /拉尔斯 编辑: 在GetIconFromFile中添加了一些非常基本的错误检查 if SHGetFileInfo( PCh

使用Delphi2009,尝试制作一个启动器。 为了使它“快”我真的想加载一个背景线程图标

我使用了以下解决方案:

如果不是在线程中运行的话,这可以正常工作。 一旦我把它放到一个线程中,一些图标就不会被“抓取”,或者是某种通用图标。 我甚至尝试序列化线程(实际上,使其成为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;

也许可以使用Delphi2009中引入的TThread.Queue方法简化线程代码

这里有一篇文章给出了一些例子和背景信息:

队列是非阻塞的。这允许为所有图标顺序创建后台工作线程,然后让它们异步加载

尝试移动此:

GetIconFromFile(Item.FFilename, I, SHIL_EXTRALARGE);

进入
同步
块。您应该在使用
SHGetFileInfo()
后调用
SHGetFileInfo
的文档指定在调用函数之前必须初始化COM。因为COM初始化是每个线程的,所以需要在线程中初始化COM。这意味着从线程的
Execute
方法调用
CoInitialize
CoInitializeEx

显示您目前得到的信息,这样我们可以帮助您…您添加了代码,但没有调用
CoInitialize
。文档清楚地说明您必须。你在上面的评论中说你已经这样做了。您是否意识到对
CoInitialize
的调用必须由调用
SHGetFileInfo
的线程执行?TThread构造函数在主线程中运行!这意味着您必须在执行部分调用CoInitialize。@LURD是正确的。您需要在线程中初始化com。这意味着内部执行。我几乎100%确定这不是线程代码问题。我有一些简单对象的简单列表,其中包含一个文件名和一个TIcon。我尝试过为每个对象制作一个线程,上面是创建线程的地方,并在需要时手动馈送对象。无论我如何从线程中调用GetIconFromFile,它最终都会给我错误的图标。如果我从主线程打电话,一切都很好??哦,只是为了好玩,我试着在TCriticalSection中包装GetIconFromFile。那没什么区别…那会破坏使用线程的全部目的,不是吗?你接受了答案。然后不被接受。有什么问题吗?
GetIconFromFile(Item.FFilename, I, SHIL_EXTRALARGE);