在Delphi中线程加载图标 [英] Threaded loading of icons in Delphi

查看:209
本文介绍了在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆