2013-03-21 7 views
5

Ich verwende diesen Code ein Tray-Icon in einem Thread (icon1 und icon2 sind in einer Re-Datei) zu animieren:Ist mit LoadIcon() ein Speicherleck möglich?

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

ich die Angst haben, dass es ein Speicherleck schaffen kann, wenn ich es tun in einer Schleife, weil icon1/2 wieder vollständig geladen werden.

Erstellt der Code ein Speicherleck oder ist es sicher in einer Schleife zu verwenden?

+0

Ich weiß es nicht, aber ich weiß, wie man es erzählt. Führen Sie es für 10 Minuten mit Process Explorer (www.sysinternals.com) ausgeführt wird, und es wird Ihnen zeigen, wenn Sie ein Leck haben oder nicht. –

+1

Ich habe es nicht verstanden, einen ** Thread ** zu verwenden, um ein TrayIcon zu animieren. Ich kenne animierte TrayIcons mit einer ImageList und Animate Eigenschaft, die auf True gesetzt sind. –

+0

TrayIcon Beispiel von Emba http://docwiki.embarcadero.com/CodeExamples/XE3/en/TTrayIcon_(Delphi) –

Antwort

8

Sie rufen LoadIcon an. Dadurch werden sogenannte freigegebene Symbole zurückgegeben. Dies wird in der Dokumentation für DestroyIcon erläutert. Eine der Folgen eines gemeinsamen Symbols ist, dass Sie nicht DestroyIcon anrufen müssen.

Es ist nur notwendig, DestroyIcon für Icons aufrufen und Cursor erstellt mit den folgenden Funktionen: CreateIconFromResourceEx (falls genannt ohne LR_SHARED Flagge), CreateIconIndirect und CopyIcon. Verwenden Sie diese Funktion nicht, um ein freigegebenes Symbol zu zerstören. Ein geteiltes Symbol ist als gültig, solange das Modul, von dem es geladen wurde, im Speicher verbleibt. Die folgenden Funktionen erhalten ein gemeinsames Symbol.

  • LoadIcon
  • Loadimage (wenn Sie die LR_SHARED Flag verwenden)
  • Copyimage (wenn Sie die LR_COPYRETURNORG Flagge und der hImage Parameter ist ein gemeinsames Symbol)
  • CreateIconFromResource
  • CreateIconFromResourceEx (wenn Sie die LR_SHARED Flag verwenden)

Also, wie dies in Ihren Code beziehen? Nun, wenn Sie schreiben

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

Sie Zuweisen der Handle Eigenschaft eines TIcon Objekt. Wenn das Objekt TIcon bereits ein Symbol enthält, wird dieses Symbol zerstört, bevor es durch das neue Symbol ersetzt wird. Das liegt daran, dass TIcon Eigentümer seiner Symbolhandles ist. All dies bedeutet, dass die obige Codezeile zu einem Aufruf von DestroyIcon für ein gemeinsames Symbol führt. Dies ist, was MSDN Ihnen sagt, nicht zu tun, aber in der Tat erweist es sich als gutartig. Es ist nichts worüber man sich sorgen muss.

Jetzt, auch wenn Sie eine Funktion verwenden, die nicht freigegebene Symbole, z. CreateIconIndirect dann würde Ihr Code Icon-Handles nicht verlieren. Das liegt daran, dass die Klasse TIcon den Besitz des Symbols übernimmt.

Aber da Sie geteilte Symbole verwenden, ist es nicht einmal möglich, diese Griffe zu verlieren.Objekte, die nicht zerstört werden können, können nicht durchleuchtet werden!

Einige weitere Punkte:

  1. Ich würde so persönlich nicht nennen LoadIcon über und über. Ich würde es beim Programmstart zweimal aufrufen und sich an die geteilten Icon-Handles erinnern. Dann würde ich diese Griffe verwenden, um TrayIcon.Icon.Handle zuzuweisen. Wenn Sie LoadIcon anrufen, haben Sie nicht viel Kontrolle über die Größe des zurückgegebenen Symbols. Ich denke, dass es möglich ist, dass Sie ein großes Symbol anstelle eines kleinen Symbols erhalten. Und das muss vor der Anzeige auf die kleine Symbolgröße skaliert werden. Beim Erstellen von Infobereich-Symbolen sollten Sie sicherstellen, dass sie SM_CXSMICON by SM_CYSMICON sind.