2013-03-21 49 views
5

我使用這個代碼的動畫主題中的托盤圖標(ICON1和ICON2處於res文件):LoadIcon()是否可能發生內存泄漏?

while AnimationPending do 
begin 
    TrayIcon.Icon.Handle := LoadIcon(hInstance,'icon1'); 
    Sleep(300); 
    TrayIcon.Icon.Handle := LoadIcon(hInstance,'icon2'); 
    Sleep(300); 
end; 

我也有擔心,如果我這樣做可能會帶來一個內存泄漏在一個循環中,因爲icon1/2重新加載。

該代碼是否會產生內存泄漏,或者在循環中使用是否安全?

+0

我不知道,但我知道如何說。運行Process Explorer(www.sysinternals.com)運行10分鐘,它會告訴你是否泄漏。 – 2013-03-21 20:43:08

+1

我沒有得到使用**線程**來動畫TrayIcon的要點。我知道動畫TrayIcons的ImageList和Animate屬性設置爲True – 2013-03-22 00:07:43

+0

來自Emba的TrayIcon示例http://docwiki.embarcadero.com/CodeExamples/XE3/en/TTrayIcon_(Delphi) – 2013-03-22 00:09:43

回答

8

您正在致電LoadIcon。這返回所謂的共享圖標。這在DestroyIcon的文檔中有解釋。成爲共享圖標的後果之一是您無需致電DestroyIcon

它是隻需要調用的圖標和光標DestroyIcon創建 具有以下功能:CreateIconFromResourceEx(好象叫 沒有LR_SHARED標誌),CreateIconIndirect,並CopyIcon。不要 使用此功能銷燬共享圖標。共享圖標的有效期限爲 ,因爲它的加載模塊仍保留在內存中。以下功能獲取共享圖標。

  • LoadIcon
  • 的LoadImage(如果使用LR_SHARED標誌)
  • CopyImage(如果使用LR_COPYRETURNORG標誌和畫佳參數是共享圖標)
  • CreateIconFromResource
  • CreateIconFromResourceEx(如果你使用LR_SHARED標誌)

那麼,如何這涉及到你的代碼?那麼,當你寫

TrayIcon.Icon.Handle := LoadIcon(hInstance,'icon1'); 

您要指派給一個TIcon對象的Handle財產。如果TIcon對象已經包含圖標,則該圖標在被新圖標替換之前將被銷燬。這是因爲TIcon擁有其圖標句柄的所有權。所有這些意味着上面的代碼行會導致對DestroyIcon的共享圖標的調用。這是MSDN告訴你不要這樣做的,但實際上它是非常良性的。沒什麼可擔心的。

現在,即使您使用的是返回非共享圖標的函數,例如CreateIconIndirect然後你的代碼不會泄漏圖標句柄。這是因爲TIcon類承擔了圖標句柄的所有權。

但是由於您使用的是共享圖標,甚至無法泄漏這些句柄。無法銷燬的物品不能泄露!

一些積分:

  1. 我個人不會一遍遍打電話LoadIcon這樣。我會在程序啓動時調用它兩次,並記住共享圖標句柄。然後我會使用這些句柄分配給TrayIcon.Icon.Handle
  2. 當您致電LoadIcon時,您無法控制返回圖標的大小。我認爲你可能會得到一個大圖標而不是一個小圖標。這需要在顯示之前縮放到小圖標大小。創建通知區域圖標時,您應確保它們的尺寸爲SM_CXSMICON,尺寸爲SM_CYSMICON