| 
| Autor | Beitrag |  
| FriFra 
          Beiträge: 557
 
 Win XP Prof, Win XP Home,Win Server 2003,Win 98SE,Win 2000,Win NT4,Win 3.11,Suse Linux 7.3 Prof,Suse Linux 8.0 Prof
 D2k5 Prof, D7 Prof, D5 Standard, D3 Prof, K3 Prof
 
 | 
Verfasst: So 25.01.04 15:00 
 
Ich weiss, dass ich irgendwo etwas falsch mache, zumindest fängt bei wiederholter Ausführung der folgenden Funktion der Rechner irgendwann komplett an zu spinnen... obwohl eigentlich alles jeweils korrekt freigegeben wird (werden sollte).
 												| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 18:
 19:
 20:
 21:
 22:
 23:
 24:
 25:
 26:
 27:
 28:
 29:
 30:
 31:
 32:
 33:
 34:
 35:
 36:
 37:
 38:
 39:
 40:
 41:
 42:
 43:
 44:
 45:
 46:
 47:
 48:
 49:
 50:
 51:
 52:
 53:
 54:
 55:
 56:
 57:
 58:
 59:
 60:
 61:
 62:
 63:
 64:
 65:
 66:
 67:
 68:
 69:
 70:
 71:
 72:
 73:
 74:
 75:
 76:
 77:
 78:
 79:
 80:
 81:
 82:
 83:
 84:
 85:
 86:
 87:
 88:
 89:
 90:
 91:
 92:
 93:
 94:
 95:
 96:
 97:
 98:
 99:
 100:
 101:
 102:
 103:
 104:
 105:
 106:
 107:
 108:
 109:
 110:
 111:
 112:
 113:
 114:
 115:
 116:
 117:
 118:
 119:
 120:
 121:
 122:
 123:
 124:
 125:
 126:
 127:
 128:
 129:
 130:
 131:
 132:
 133:
 134:
 135:
 136:
 137:
 138:
 139:
 140:
 141:
 142:
 143:
 144:
 145:
 146:
 147:
 148:
 149:
 150:
 151:
 152:
 153:
 154:
 155:
 156:
 
 | procedure TForm1.SetIcon(Loading, Ignoring, Stopped, Plugin:boolean);
 function CombineIcons(FrontIcon, BackIcon: HIcon): HIcon;
 var
 WinDC: HDC;
 FrontInfo: TIconInfo;
 FrontDC: HDC;
 FrontSv: HBITMAP;
 BackInfo: TIconInfo;
 BackDC: HDC;
 BackSv: HBITMAP;
 BmpObj: tagBitmap;
 begin
 WinDC := GetDC(0);
 
 GetIconInfo(FrontIcon, FrontInfo);
 FrontDC := CreateCompatibleDC(WinDC);
 FrontSv := SelectObject(FrontDC, FrontInfo.hbmMask);
 
 GetIconInfo(BackIcon, BackInfo);
 BackDC := CreateCompatibleDC(WinDC);
 BackSv := SelectObject(BackDC, BackInfo.hbmMask);
 
 GetObject(FrontInfo.hbmMask, SizeOf(BmpObj), @BmpObj);
 BitBlt(BackDC, 0, 0, BmpObj.bmWidth, BmpObj.bmHeight, FrontDC, 0, 0,
 SRCAND);
 
 SelectObject(BackDC, BackInfo.hbmColor);
 DrawIconEx(BackDC, 0, 0, FrontIcon, 0, 0, 0, 0, DI_NORMAL);
 
 Result := CreateIconIndirect(BackInfo);
 
 SelectObject(FrontDC, FrontSv);
 DeleteDC(FrontDC);
 SelectObject(BackDC, BackSv);
 DeleteDC(BackDC);
 ReleaseDC(0, WinDC);
 DeleteObject(FrontInfo.hbmColor);
 DeleteObject(FrontInfo.hbmMask);
 DeleteObject(BackInfo.hbmColor);
 DeleteObject(BackInfo.hbmMask);
 DeleteObject(FrontSv);
 DeleteObject(BackSv);
 end;
 var
 RS: TResourceStream;
 sI: string;
 Ico: array[0..8] of TIcon;
 n: integer;
 begin
 for n := 0 to High(Ico) do
 Ico[n] := TIcon.Create;
 
 try
 StrPLCopy(IconData.szTip, '[' + Label2.Caption + ']'#13 + 'WAN-IP: ' +
 Edit3.Text + #13 + 'LAN-IP: ' + Edit4.Text, 63);
 
 if G_IP = '0.0.0.0'#0 then
 sI := 'I_Inactive'
 else if G_IP = '0.0.0.0' then
 sI := 'I_Offline'
 else
 sI := 'I_Online';
 try
 RS := TResourceStream.Create(0, sI + GetIconSufix, RT_RCDATA);
 RS.Position := 0;
 Ico[0].LoadFromStream(RS);
 finally
 RS.Free;
 end;
 
 
 if Loading then
 sI := 'I_Loading'
 else
 sI := 'I_Blank';
 try
 RS := TResourceStream.Create(0, sI + GetIconSufix, RT_RCDATA);
 RS.Position := 0;
 Ico[1].LoadFromStream(RS);
 finally
 RS.Free;
 end;
 Ico[2].Handle := CombineIcons(Ico[1].Handle, Ico[0].Handle);
 
 if Ignoring then
 sI := 'I_Ignoring'
 else
 sI := 'I_Blank';
 try
 RS := TResourceStream.Create(0, sI + GetIconSufix, RT_RCDATA);
 RS.Position := 0;
 Ico[3].LoadFromStream(RS);
 finally
 RS.Free;
 end;
 Ico[4].Handle := CombineIcons(Ico[3].Handle, Ico[2].Handle);
 
 if Stopped then
 sI := 'I_Stop'
 else
 sI := 'I_Blank';
 try
 RS := TResourceStream.Create(0, sI + GetIconSufix, RT_RCDATA);
 RS.Position := 0;
 Ico[5].LoadFromStream(RS);
 finally
 RS.Free;
 end;
 Ico[6].Handle := CombineIcons(Ico[5].Handle, Ico[4].Handle);
 
 if Plugin then
 sI := 'I_Plugin'
 else
 sI := 'I_Blank';
 try
 RS := TResourceStream.Create(0, sI + GetIconSufix, RT_RCDATA);
 RS.Position := 0;
 Ico[7].LoadFromStream(RS);
 finally
 RS.Free;
 end;
 Ico[8].Handle := CombineIcons(Ico[7].Handle, Ico[6].Handle);
 
 DestroyIcon(TNA_Icon.Handle);
 TNA_Icon.Assign(Ico[8]);
 DestroyIcon(IconData.hIcon);
 IconData.hIcon := TNA_Icon.Handle;
 
 
 DestroyIcon(Image1.Picture.Icon.Handle);
 Image1.Picture.Icon.Handle := IconData.hIcon;
 Image1.Repaint;
 Edit3.Text := G_IP;
 Label7.Caption := G_IT;
 
 if G_IP = '0.0.0.0'#0 then
 Label2.Caption := 'undefined'
 else if G_IP = '0.0.0.0' then
 Label2.Caption := 'Offline'
 else
 Label2.Caption := 'Online';
 
 if IsMinimized = True then
 Shell_NotifyIcon(NIM_MODIFY, @IconData);
 
 finally
 for n := 0 to High(Ico) do
 begin
 Ico[n].ReleaseHandle;
 DestroyIcon(Ico[n].Handle);
 FreeAndNil(Ico[n]);
 end;
 IconReady := True;
 end;
 end;
 |    Update: Ich habe auf einen Array of Icon umgestellt  _________________ Michael
 (principal certified lotus professional - developer)
 
 Zuletzt bearbeitet von FriFra am So 25.01.04 18:11, insgesamt 1-mal bearbeitet
 |  |  |  
| MaxiTB 
          Beiträge: 679
 
 Win2000, WinXp, Workbench ;-)
 D7 Ent, VS2003 Arch.
 
 | 
Verfasst: So 25.01.04 17:13 
 
Ähm - Frage so nebenbei - warum verwendest den kein Array für die Icons ! Da blickt ja keiner mehr durch und die Fehleranfälligkeit steigt ins astronomische ... nein, fast intergalaktische Sphären die sich überdimensional auszudehen scheinen im Raumzeitkontinuum !   _________________Euer Mäxchen Wer früher stirbt, ist länger tot.
 |  |  |  
| FriFra  
          Beiträge: 557
 
 Win XP Prof, Win XP Home,Win Server 2003,Win 98SE,Win 2000,Win NT4,Win 3.11,Suse Linux 7.3 Prof,Suse Linux 8.0 Prof
 D2k5 Prof, D7 Prof, D5 Standard, D3 Prof, K3 Prof
 
 | 
Verfasst: So 25.01.04 17:17 
 
Ähm... sooo viele Icons sind es nun auch wieder nicht, und da jedes der temporären Icons nur einmal belegt wird, sollte es noch überschaubar sein... Array oder nicht Array, da ist hier nicht die Frage, gesucht wird der Fehler bei der Ressourcenfreigabe   _________________ Michael
 (principal certified lotus professional - developer)
 |  |  |  
| MaxiTB 
          Beiträge: 679
 
 Win2000, WinXp, Workbench ;-)
 D7 Ent, VS2003 Arch.
 
 | 
Verfasst: So 25.01.04 17:46 
 
Schön - Frage: Wo gibst du FrontSv frei ? Und wo BackSv ?
 Und ich bleibe dabei, du sagst selber du hast den Überblick verloren, also ist ein Array angesagt. Bei alles was mehr als 2 ist, ist ein Array nämlich angesagt. Da schrumpfen in deinem Fall 9 Zeilen auf zwei - und das in 3 Fällen ... wirst ja nicht nach Codezeilen bezahlt, oder ?   Edit Moment - SelectObject ... in dem Fall braucht man das RegionObject nnicht freizugeben. *puh* Ich blick da gerade nicht durch. Vielleicht tut sich ein anderer leichter bei deinem Code !_________________Euer Mäxchen Wer früher stirbt, ist länger tot.
 |  |  |  
| FriFra  
          Beiträge: 557
 
 Win XP Prof, Win XP Home,Win Server 2003,Win 98SE,Win 2000,Win NT4,Win 3.11,Suse Linux 7.3 Prof,Suse Linux 8.0 Prof
 D2k5 Prof, D7 Prof, D5 Standard, D3 Prof, K3 Prof
 
 | 
Verfasst: So 25.01.04 18:02 
 
Ich habe nirgends gesagt, dass ich den Überblick verloren habe...
 Danke für den Tip    . Die Funktion CombineIcons  habe ich vom SwissDelphicenter und wende sie auch schon längere Zeit ohne Probleme an, deshalb habe ich dort keinen Fehler vermutet. Aber Du hast recht, ich habe am Ende der Funktion noch folgendes eingebaut: 		                       Delphi-Quelltext 
 									| 1:2:
 
 |     DeleteObject(FrontSv);DeleteObject(BackSv);
 |  Allerdingt kommt immernoch nach wenigen Minuten (einige hundert Updates) ein EOutOfResources     Ich habe die Funktion CombineIcons  auch noch nie so häufig genutzt, aber da der Tip schon länger veröffentlicht ist und offenbar noch keiner solche Probleme hatte denke ich nicht, das es an dieser Funktion liegt. Der Fehler müsste eigentlich wo anders liegen..._________________ Michael
 (principal certified lotus professional - developer)
 |  |  |  
| FriFra  
          Beiträge: 557
 
 Win XP Prof, Win XP Home,Win Server 2003,Win 98SE,Win 2000,Win NT4,Win 3.11,Suse Linux 7.3 Prof,Suse Linux 8.0 Prof
 D2k5 Prof, D7 Prof, D5 Standard, D3 Prof, K3 Prof
 
 | 
Verfasst: So 25.01.04 18:14 
 
@MaxiTB: Ich habe Deinem Wunsch entsprochen und auf Array umgestellt  _________________ Michael
 (principal certified lotus professional - developer)
 |  |  |  
| MaxiTB 
          Beiträge: 679
 
 Win2000, WinXp, Workbench ;-)
 D7 Ent, VS2003 Arch.
 
 | 
Verfasst: So 25.01.04 18:19 
 
Der Absatz kommt mir noch ein bisserl merkwürdig vor ... was pssiert hier genau ?
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 
 | DestroyIcon(TNA_Icon.Handle); TNA_Icon.Assign(Ico[8]);
 DestroyIcon(IconData.hIcon);
 IconData.hIcon := TNA_Icon.Handle;
 | _________________Euer Mäxchen Wer früher stirbt, ist länger tot.
 |  |  |  
| FriFra  
          Beiträge: 557
 
 Win XP Prof, Win XP Home,Win Server 2003,Win 98SE,Win 2000,Win NT4,Win 3.11,Suse Linux 7.3 Prof,Suse Linux 8.0 Prof
 D2k5 Prof, D7 Prof, D5 Standard, D3 Prof, K3 Prof
 
 | 
Verfasst: So 25.01.04 18:28 
 
	  | MaxiTB hat folgendes geschrieben: |  	  | Der Absatz kommt mir noch ein bisserl merkwürdig vor ... was pssiert hier genau ? 
 
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 
 | DestroyIcon(TNA_Icon.Handle); TNA_Icon.Assign(Ico[8]);
 DestroyIcon(IconData.hIcon);
 IconData.hIcon := TNA_Icon.Handle;
 |  | 
 1. Zeile: Ich habe in meinem Programm eine globale Icon Variable TNA_Icon , deren Icon wird hier freigegeben.
 2. Zeile: Meinem globalen Icon wird der Inhalt des gerade berechneten Icons (Ico[8]) zugewiesen
 3. Zeile: Das Icon der globalen Variable IconData  (Typ: TNotifyIconData) wird hier freigegeben.
 4. Zeile: Das TNA_Icon wird dem eigentlichen NotifyIcon zugewiesen (noch nicht in den TNA upgedatet)_________________ Michael
 (principal certified lotus professional - developer)
 |  |  |  
| MaxiTB 
          Beiträge: 679
 
 Win2000, WinXp, Workbench ;-)
 D7 Ent, VS2003 Arch.
 
 | 
Verfasst: So 25.01.04 18:32 
 
Jetzt fällt mir nix mehr auf ... ists sicher, daß es an dieser Stelle passiert ? Immerhin wird hier wesentlich mehr freigegeben als überhaupt reserviert wird ... _________________Euer Mäxchen Wer früher stirbt, ist länger tot.
 |  |  |  
| FriFra  
          Beiträge: 557
 
 Win XP Prof, Win XP Home,Win Server 2003,Win 98SE,Win 2000,Win NT4,Win 3.11,Suse Linux 7.3 Prof,Suse Linux 8.0 Prof
 D2k5 Prof, D7 Prof, D5 Standard, D3 Prof, K3 Prof
 
 | 
Verfasst: So 25.01.04 18:44 
 
	  | MaxiTB hat folgendes geschrieben: |  	  | Immerhin wird hier wesentlich mehr freigegeben als überhaupt reserviert wird ... | 
 Eben deshalb frage ich ja hier... Ich bin mir aber 100% sicher, dass es an dieser Procedure liegt. Denn wenn ich direkt am Procedure-beginn ein Exit platziere, läuft das Programm Fehlerfrei... nur eben sinnlos, weil das Icon nicht geändert wird   _________________ Michael
 (principal certified lotus professional - developer)
 |  |  |  
| MaxiTB 
          Beiträge: 679
 
 Win2000, WinXp, Workbench ;-)
 D7 Ent, VS2003 Arch.
 
 | 
Verfasst: So 25.01.04 20:38 
 
Oki - kann dir nur noch einen Tip geben ... klammert per Kommentare soviel Code in der Prozedure aus wie möglich und dann schrittweise weniger ... bis der Fehler wieder auftritt.     Mehr fällt mir nicht ein ... so kannst du vielleicht die Stelle besser eingrenzen ..._________________Euer Mäxchen Wer früher stirbt, ist länger tot.
 |  |  |  
| FriFra  
          Beiträge: 557
 
 Win XP Prof, Win XP Home,Win Server 2003,Win 98SE,Win 2000,Win NT4,Win 3.11,Suse Linux 7.3 Prof,Suse Linux 8.0 Prof
 D2k5 Prof, D7 Prof, D5 Standard, D3 Prof, K3 Prof
 
 | 
Verfasst: So 25.01.04 20:49 
 
Ich habe jetzt festgestellt, dass bei Auskommentierung aller Zuweisungen über CombineIcon kein Fehler mehr auftritt    ... Allerdings ist die Kombination der Icons elementar für mein Programm     Wenn ich das nicht gelöst bekomme, muss ich die Anzahl der Icons in der Resource vervierfachen, um alle Kombinationen abzudecken   _________________ Michael
 (principal certified lotus professional - developer)
 |  |  |  
| MaxiTB 
          Beiträge: 679
 
 Win2000, WinXp, Workbench ;-)
 D7 Ent, VS2003 Arch.
 
 | 
Verfasst: So 25.01.04 20:52 
 
Okay - jetzt wirds ernst - gucken wir mal, was das Ding wirklich macht und wo da der Saft verloren geht ... Moment ...
 Jetzt habe ich gerade X-Men 2: United hinter mir, jetzt bin ich wieder motiviert   _________________Euer Mäxchen Wer früher stirbt, ist länger tot.
 |  |  |  
| MaxiTB 
          Beiträge: 679
 
 Win2000, WinXp, Workbench ;-)
 D7 Ent, VS2003 Arch.
 
 | 
Verfasst: So 25.01.04 21:01 
 
Haha ... ist doch klar. *lol* Warum ists mir nicht gleich aufgefallen ...
 Mit CreateIconIndirect erstellst du eine neue Resource, welche du mit DestroyIcon ja wieder freigibst, oder ? ODER ? Ja was ist ? Wo wird die jetzt freigegeben ? *g*
 Das ist die Frage, nicht ?
 Schauen wir uns diese Zeile mal genau an:
 		                       Delphi-Quelltext 
 									| 1:
 | Ico[2].Handle := CombineIcons(Ico[1].Handle, Ico[0].Handle);					 |  Die Frage ist: Was macht sie ? Ändert sie nur eine Referenz, wird die alte Resource freigegeben - wird vielleicht intern wieder ein CreateIconIndirect gemacht um eine Kopie zu bekommen - da hilft nur ein Blick in die Source    Moment ..._________________Euer Mäxchen Wer früher stirbt, ist länger tot.
 |  |  |  
| toms 
          Beiträge: 1099
 Erhaltene Danke: 2
 
 
 
 
 | 
Verfasst: So 25.01.04 21:03 
 
	  | Zitat: |  	  | Remember: The icon created with the CombineIcons function must be destroyed with DestroyIcon() function when finished using it. | 
 |  |  |  
| FriFra  
          Beiträge: 557
 
 Win XP Prof, Win XP Home,Win Server 2003,Win 98SE,Win 2000,Win NT4,Win 3.11,Suse Linux 7.3 Prof,Suse Linux 8.0 Prof
 D2k5 Prof, D7 Prof, D5 Standard, D3 Prof, K3 Prof
 
 | 
Verfasst: So 25.01.04 21:09 
 
	  | MaxiTB hat folgendes geschrieben: |  	  | Haha ... ist doch klar. *lol* Warum ists mir nicht gleich aufgefallen ... 
 Mit CreateIconIndirect erstellst du eine neue Resource, welche du mit DestroyIcon ja wieder freigibst, oder ? ODER ? Ja was ist ? Wo wird die jetzt freigegeben ? *g*
 | 
 Schau mal in den finally  Abschnitt... da gebe ich alles frei. Zwischendurch ändere ich auch nichts mehr an den bettr. Icons._________________ Michael
 (principal certified lotus professional - developer)
 |  |  |  
| MaxiTB 
          Beiträge: 679
 
 Win2000, WinXp, Workbench ;-)
 D7 Ent, VS2003 Arch.
 
 | 
Verfasst: So 25.01.04 21:12 
 
		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 
 | procedure TIcon.SetHandle(Value: HICON);begin
 NewImage(Value, nil);
 Changed(Self);
 end;
 |  Aha ... weiterstöbern ...
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 
 | procedure TIcon.NewImage(NewHandle: HICON; NewImage: TMemoryStream);var
 Image: TIconImage;
 begin
 Image := TIconImage.Create;
 try
 Image.FHandle := NewHandle;
 Image.FMemoryImage := NewImage;
 except
 Image.Free;
 raise;
 end;
 Image.Reference;
 FImage.Release;
 FImage := Image;
 end;
 |  		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 
 | procedure TIconImage.FreeHandle;begin
 if FHandle <> 0 then DestroyIcon(FHandle);
 FHandle := 0;
 end;
 |  Okay ... Mist ... schaut so aus, wie wenn das auch richtig täte ...
 Aber so wie es aussieht, ists vielleicht gar nicht soo gut, wenn du am Schluß auf diese Referenz ein DestroyIcon machst eben wegen den Code da oben ...
 Wenn mans nämlich genau betrachtet, wird zweimal ein DestroyIcon durchgeführt ... und ich weiß nicht, ob das nicht zu Nebeneffekten führen kann. Obwohl FHandle:=nil ... daher müßten die schon alle nil sein zu dem Zeitpunkt ..._________________Euer Mäxchen Wer früher stirbt, ist länger tot.
 |  |  |  
| MaxiTB 
          Beiträge: 679
 
 Win2000, WinXp, Workbench ;-)
 D7 Ent, VS2003 Arch.
 
 | 
Verfasst: So 25.01.04 21:25 
 
		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 
 | function TIcon.ReleaseHandle: HICON;begin
 with FImage do
 begin
 if FRefCount > 1 then NewImage(CopyIcon(FHandle), nil);
 Result := FHandle;
 FHandle := 0;
 end;
 Changed(Self);
 end;
 |  Schau mal, ob zufällig ReleaseHandle ein Icon zurückgibt; das solltest du nämlich freigeben. Man beachte das CopyIcon !_________________Euer Mäxchen Wer früher stirbt, ist länger tot.
 |  |  |  
| FriFra  
          Beiträge: 557
 
 Win XP Prof, Win XP Home,Win Server 2003,Win 98SE,Win 2000,Win NT4,Win 3.11,Suse Linux 7.3 Prof,Suse Linux 8.0 Prof
 D2k5 Prof, D7 Prof, D5 Standard, D3 Prof, K3 Prof
 
 | 
Verfasst: So 25.01.04 22:11 
 
Also, nach ReleaseHandle bleibt die Handlenummer immer erhalten, genau wie nach DestroyIcon...
 Ohne DestroyIcon schaufelt sich merklich der Arbeisspeicher zu. So wie es jetzt ist, bleibt der Speicherverbrauch relativ konstant, bis plötzlich die Ressourcen verbraucht sind.
 Ich habe übrigens etwas merkwürdiges im Debugger bemerkt:
 _________________ Michael
 (principal certified lotus professional - developer)
 |  |  |  
| MaxiTB 
          Beiträge: 679
 
 Win2000, WinXp, Workbench ;-)
 D7 Ent, VS2003 Arch.
 
 | 
Verfasst: So 25.01.04 22:20 
 
Dann hats aber was - weil da oben siehst du ja, das FHandle auf 0 gesetzt wird. Nach ReleaseHandle muß also Handle=nil sein.
 Nochmals der ...
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 
 | function TIcon.ReleaseHandle: HICON; begin
 with FImage do
 begin
 if FRefCount > 1 then NewImage(CopyIcon(FHandle), nil);
 Result := FHandle;
 FHandle := 0;
 end;
 Changed(Self);
 end;
 |  Irgendwie scheints da ordentlich den Speicher durcheinander zu wirbeln ..._________________Euer Mäxchen Wer früher stirbt, ist länger tot.
 |  |  |  |