2012-07-09 76 views
4

使用Delphi 2009,試圖製作一個啓動器。 爲了使它「活潑」,我真的很想在後臺線程中加載圖標。在Delphi中加載圖標

我已經用在這裏找到了解決辦法: Can 48x48 or 64x64 icons be obtained from the Vista Shell?

這工作得很好,如果不是在一個線程中運行。 只要我把它放在一個線程中,一些圖標就不會被「提取」,或者是某種通用圖標。 我甚至嘗試序列化線程(使它們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; 

此不作任何diffenrence。 我仍然得到了一些通用的圖標(只有當這種被稱爲一個線程,雖然)

EDIT2: 線程代碼(很簡單):

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; 
+0

顯示你得到的沙發,所以我們可以幫助... – whosrdaddy 2012-07-09 11:38:51

+0

那麼,沒有太多顯示。我有鏈接示例中的過程。我嘗試了不同的線程方法,但每個人都給出相同的(錯誤的)結果。 – 2012-07-09 12:22:45

+0

api調用返回了哪些錯誤?你是否初始化COM? – 2012-07-09 12:24:17

回答

2

SHGetFileInfo的文檔指定在調用函數之前必須初始化COM。由於COM初始化是每個線程,因此您需要在線程中初始化COM。這意味着從線程的Execute方法調用CoInitializeCoInitializeEx

+0

你接受了答案。然後不被接受。有問題嗎? – 2012-07-10 06:48:07

+0

Nonono ...只是不小心再次點擊複選標記... – 2012-07-10 18:14:48

+0

好的。感謝你的接納! – 2012-07-10 19:27:09

0

也許你可以簡化你的線程代碼使用在2009年德爾福

的物品,其給出了一些例子和背景資料介紹,TThread.Queue方法是在這裏:

Synchronize and Queue with Parameters

TThread.Queue是非阻塞的。這允許爲所有圖標順序創建後臺工作線程,然後讓它們異步加載。

+0

我幾乎100%肯定它不是線程代碼問題。我有一個簡單的對象列表,它包含一個文件名和一個TIcon。我已經嘗試爲每個對象創建一個線程,並在上面創建線程,並在需要時手動添加對象。無論我如何從線程中調用GetIconFromFile,它最終都會給我錯誤的圖標。如果我從主線程調用,一切都很好......? – 2012-07-09 18:20:43

+0

哦,只是爲了好玩,我試着在TCriticalSection中封裝GetIconFromFile。這並沒有什麼區別...... – 2012-07-09 18:25:33

-1

嘗試移動此:

GetIconFromFile(Item.FFilename, I, SHIL_EXTRALARGE); 

synchronize塊。使用SHGetFileInfo()後,您應該致電DestroyIcon()

+1

這將打敗使用線程的整個目的,不是嗎? – 2012-07-10 04:14:42