使用Delphi 2009,尝试制作一个启动器。为了使它更加“敏捷”,我真的很想在后台线程中加载图标。
我已经使用在这里找到的解决方案:Can 48x48 or 64x64 icons be obtained from the Vista Shell? 如果不在线程中运行,这个方法很好用。但是一旦我把它放在一个线程中,有些图标就不能被获取,或者成为某种通用图标。我甚至尝试序列化线程(使它们过时),但结果仍然相同。
所以问题是:如何在线程中加载图标(具有与链接示例相同的可用选项)?
/Lars
编辑: 在GetIconFromFile中添加了一些非常基本的错误检查
这没有任何区别。 我仍然会得到一些通用图标(只有在调用线程时才会出现)。
编辑2: 线程代码(非常简单):
我已经使用在这里找到的解决方案:Can 48x48 or 64x64 icons be obtained from the Vista Shell? 如果不在线程中运行,这个方法很好用。但是一旦我把它放在一个线程中,有些图标就不能被获取,或者成为某种通用图标。我甚至尝试序列化线程(使它们过时),但结果仍然相同。
所以问题是:如何在线程中加载图标(具有与链接示例相同的可用选项)?
/Lars
编辑: 在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;
这没有任何区别。 我仍然会得到一些通用图标(只有在调用线程时才会出现)。
编辑2: 线程代码(非常简单):
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;
CoInitialize
。文档明确说明你必须这样做。你在上面的评论中说过你已经这样做了。你是否意识到调用CoInitialize
的操作必须来自调用SHGetFileInfo
的线程? - David Heffernan