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