2013-03-21 13 views
5

Sto usando questo codice per animare un'icona nella barra in un thread (icon1 icon2 e sono in un file res):È possibile una perdita di memoria con LoadIcon()?

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

ho il timore che possa creare una perdita di memoria se lo faccio in un ciclo perché icon1/2 vengono caricati di nuovo.

Il codice crea una perdita di memoria o è sicuro da utilizzare in un ciclo?

+0

Non so, ma so come dirlo. Eseguilo per 10 minuti con Process Explorer (www.sysinternals.com) in esecuzione, e ti mostrerà se hai una perdita o meno. –

+1

Non ho capito il motivo per usare un ** thread ** per animare un TrayIcon. Conosco le TrayIcons animate con una proprietà ImageList e Animate impostata su True –

+0

Esempio di TrayIcon da Emba http://docwiki.embarcadero.com/CodeExamples/XE3/en/TTrayIcon_(Delphi) –

risposta

8

Stai chiamando LoadIcon. Ciò restituisce quelle che sono conosciute come icone condivise. Questo è spiegato nella documentazione per DestroyIcon. Una delle conseguenze dell'essere un'icona condivisa è che non è necessario chiamare DestroyIcon.

E 'necessario solo per chiamare DestroyIcon per le icone e cursori creati con le seguenti funzioni: CreateIconFromResourceEx (se chiamato senza il flag LR_SHARED), CreateIconIndirect, e CopyIcon. Non utilizzare per distruggere un'icona condivisa. Un'icona condivisa è valida come finché il modulo dal quale è stato caricato rimane in memoria. Le seguenti funzioni ottengono un'icona condivisa.

  • LoadIcon
  • LoadImage (se si utilizza il flag LR_SHARED)
  • CopyImage (se si utilizza il LR_COPYRETURNORG bandiera e il parametro hElaborazione è l'icona di un comune)
  • CreateIconFromResource
  • CreateIconFromResourceEx (se si utilizza il flag LR_SHARED)

Quindi, come si rapporta questo con il tuo codice? Beh, quando si scrive

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

si sta assegnando alla Handle proprietà di un oggetto TIcon. Se l'oggetto TIcon contiene già un'icona, quell'icona verrà distrutta prima di essere sostituita dalla nuova icona. Questo perché TIcon ha la proprietà delle relative icone. Tutto ciò significa che la riga di codice sopra comporta una chiamata a DestroyIcon per un'icona condivisa. Questo è ciò che MSDN ti dice di non fare, ma in realtà risulta essere benigno. Non è nulla di cui preoccuparsi.

Ora, anche se si stesse utilizzando una funzione che restituisce icone non condivise, ad es. CreateIconIndirect quindi il tuo codice non perderebbe le maniglie dell'icona. Questo perché la classe TIcon assume la proprietà dell'icona di gestione.

Ma dal momento che si utilizzano icone condivise, non è nemmeno possibile perdere quei punti di manipolazione.Oggetti che non possono essere distrutti, non possono essere trapelati!

Alcuni punti di più:

  1. io personalmente non chiamerei LoadIcon più e più volte in quel modo. Lo chiamerei due volte all'avvio del programma e ricorderò le maniglie delle icone condivise. Quindi userei quelle maniglie per assegnarle a TrayIcon.Icon.Handle.
  2. Quando si chiama LoadIcon non si ha un grande controllo sulla dimensione dell'icona restituita. Penso che sia possibile ottenere un'icona grande piuttosto che una piccola icona. E questo dovrà essere ridimensionato alla piccola dimensione dell'icona prima della visualizzazione. Quando crei le icone dell'area di notifica, assicurati che siano SM_CXSMICON di dimensioni SM_CYSMICON.