在Delphi中线程加载图标 [英] Threaded loading of icons in Delphi
问题描述
使用Delphi 2009,试图做一个启动器。
为了使它snappy我真的想加载图标在后台线程。
Using Delphi 2009, trying to make a launcher. In order to make it "snappy" I would really like to load icons in a background thread.
我已经使用这里找到的解决方案:
可以从中获取48x48或64x64图标Vista Shell?
I have used the solution found here : Can 48x48 or 64x64 icons be obtained from the Vista Shell?
如果不在一个线程中运行,这工作正常。
一旦我把它放在一个线程中,一些图标就不会被获取,或者是某种通用的图标。
我甚至尝试序列化线程(使它们有效),但它产生相同的结果。
This works fine, if NOT run in a thread. As soon as I put it in a thread, some icons are not "fetched", or being some kind of generic icon. I even tried serializing the threads (making them obsolote, in effect) but it yields the same results.
所以,问题是:
如何在线程中加载图标(与链接示例相同的可用选项)?
So, the question is: How do I load icons (with the same available options as the linked example) in a thread?
/ Lars
编辑:
在GetIconFromFile中添加了一些非常基本的错误检查
Added some very basic error-checking in 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;
这不会有任何差异。
我仍然得到一些通用图标(只有当这个在线程中调用时)
This doesn't make any diffenrence. I am still getting some generic icons (only when this is called in a thread, though)
Edit2:
线程代码(非常简单):
Edit2 : Threading-code (very simple) :
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;
推荐答案
SHGetFileInfo
指定在调用函数之前必须初始化COM。由于COM初始化是每个线程,您需要在线程中初始化COM。这意味着从执行
方法调用 CoInitialize
或 CoInitializeEx
线程。
The documentation for SHGetFileInfo
specifies that you must initialize COM before calling the function. Since COM initialization is per-thread, you need to initialise COM in the thread. That means calling CoInitialize
or CoInitializeEx
from the Execute
method of the thread.
这篇关于在Delphi中线程加载图标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!