![]() |
Pobleme mit FREE (bzw. Destroy)
Liste der Anhänge anzeigen (Anzahl: 1)
Hi. Habe ein kleines Tool in dem ich ein Panel dynamisch erzeuge. In diesem Panel erzeuge ich ein Image.
Zur Laufzeit hole ich mir mit "self.GetFormImage" dann das aktuelle Bild der Form. Funktion: Ich will, wenn ich ein Fenster aufmache den Hintergrund verschleiern. Das Funktioniert soweit ganz gut, aber nach dem ca. 47 maligen aufrufen des Fensters kommt die Fehlermeldung: Exception-Klasse EOutOfResources mit Meldung 'Für diesen Befehl ist nicht genügend Speicher verfügbar. Ich hab keine Ahnung wie ich den Fehler lokalisieren soll, bzw. ich weiß garnicht warum hier ein Fehler auftritt.
Delphi-Quellcode:
procedure TFrmMain.Button1Click(Sender: TObject);
var ModalesFenster: TForm2; begin Verschleiern(TRUE); ModalesFenster := TForm2.Create(Self); ModalesFenster.ShowModal; Verschleiern(FALSE); end; procedure TFrmMain.Verschleiern(Status: Boolean); begin if Status = TRUE then begin PanelVerschleiern := TPanel.Create(nil); PanelVerschleiern.Parent := FrmMain; PanelVerschleiern.Align := alclient; PanelVerschleiern.Visible := FALSE; PanelVerschleiern.BevelOuter := bvNone; ImageVerschleiern := TImage.Create(PanelVerschleiern); ImageVerschleiern.Parent := PanelVerschleiern; ImageVerschleiern.Align := alclient; ImageVerschleiern.Picture.Bitmap := self.GetFormImage; AlphaBlendRect(ImageVerschleiern.Canvas,PanelVerschleiern.ClientRect,clblack,80); PanelVerschleiern.Show; end else begin PanelVerschleiern.Hide; ImageVerschleiern.Free; PanelVerschleiern.Free; end; end; procedure TFrmMain.AlphaBlendRect (const aCanvas: TCanvas; const aRect: TRect; const aColor: TColor; const aIntensity: Byte); var w, h : Integer; Bitmap : TBitmap; BlendParams : TBlendFunction; begin w := Succ(aRect.Right - aRect.Left); h := Succ(aRect.Bottom - aRect.Top); Bitmap := TBitmap.Create; try Bitmap.Width := w; Bitmap.Height := h; Bitmap.Canvas.Brush.Color := ColorToRGB(aColor); Bitmap.Canvas.FillRect (Rect(0, 0, w, h)); BlendParams.BlendOp := AC_SRC_OVER; BlendParams.BlendFlags := 0; BlendParams.SourceConstantAlpha := aIntensity; BlendParams.AlphaFormat := 0; Windows.AlphaBlend(aCanvas.Handle, aRect.Left, aRect.Top, w, h, Bitmap.Canvas.Handle, 0, 0, w, h, BlendParams); finally Bitmap.Free; end; end; Im Anhang ist das Projekt |
Re: Pobleme mit FREE (bzw. Destroy)
Versuch mal
Delphi-Quellcode:
satt de, .Free
FreeAndNil( ImageVerschleiern);
Auerdem erzeugst du ja in denem Button immer ein neues Fenster, welches du nicht mehr freigibst. |
Re: Pobleme mit FREE (bzw. Destroy)
Hab ich auch schon probiert. Das geht auch nicht. Ich bin jetzt soweit, dass ich meine, dass es nicht an den dynamisch erzeugten Objekten liegt (Panel, Image), sondern irgendwie an "self.GetFormImage"
Aber wo belegt das denn speicher? Oder wie könnte ich den freigeben? |
Re: Pobleme mit FREE (bzw. Destroy)
Ich denke dass es, wie mkinzler schon geschrieben hat, daran liegt, dass du das "ModaleFenster" wahrscheinlich nicht wieder freigibst...
|
Re: Pobleme mit FREE (bzw. Destroy)
Binde doch mal FastMM ein und schau was der über deinen Code so zu berichten hat.
|
Re: Pobleme mit FREE (bzw. Destroy)
Danke für den Tipp.
Aber was ist denn FastMM? Wo bekomme ich das her und wie binde ich das ein? |
Re: Pobleme mit FREE (bzw. Destroy)
![]() Das überwacht dein Delphiprogramm und sagt dir ob irgendwo Speicherlecks auftreten, weil du z.b. ein dyn. erzeutes Formular nicht wieder freigibst und dieses somit immer noch Arbeitspeicher belegt. |
Re: Pobleme mit FREE (bzw. Destroy)
Wie genau wird das denn eingebunden oder gestartet? Hab jetzt die deutsche Unit FastMM4 und FastMM4Messages dem Projekt hinzugefügt.
Aber irgedwas muss ich doch noch machen, oder? |
Re: Pobleme mit FREE (bzw. Destroy)
Am besten noch kontrollieren, dass FastMM4 als aller erste Unit in der DPR in der Uses Liste steht. Dann Programm aufrufen, arbeiten und beenden. Dann erhälst du eine entsprechende Liste.
|
Re: Pobleme mit FREE (bzw. Destroy)
Liste der Anhänge anzeigen (Anzahl: 1)
So, habs nun hinbekommen. Nur verstehe ich die Meldung nicht. Was bedeutet das denn?
Bild ist im Anhang |
Re: Pobleme mit FREE (bzw. Destroy)
Wie sieht den TForm2 aus?
|
Re: Pobleme mit FREE (bzw. Destroy)
Hallo,
in FastMM4Options.Inc die in der MessageBox gezeigten Compiler-Schalter enabled ($define ..} und noch mal: Warum wir TForm2 erzeugt, aber nicht freigegeben ? Das ist dein 1. mem leak . Merke die Form-Variable global unbd guib sie wieder frei, wenn du das nächste Fenster erzeugst. Heiko |
Re: Pobleme mit FREE (bzw. Destroy)
Und GetFormImage erzeugt AFAIK auch bei jedem Aufruf eine neue Bitmap, die man wieder freigeben muss.
|
Re: Pobleme mit FREE (bzw. Destroy)
Huch, gleich so viele antworten.
Zitat:
Delphi-Quellcode:
unit UntModalesFenster;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm2 = class(TForm) Label1: TLabel; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} procedure TForm2.Button1Click(Sender: TObject); begin Close; end; end. Zitat:
|
Re: Pobleme mit FREE (bzw. Destroy)
Zitat:
Delphi-Quellcode:
var bm: TBitmap;
begin bm := GetFormImage; try //irgendwas mit dem Bitmap machen ... finally bm.Free; end; end; |
Re: Pobleme mit FREE (bzw. Destroy)
Zitat:
|
Re: Pobleme mit FREE (bzw. Destroy)
Tatsächlich. Jetzt klappts. Super. Ich weiß aber immer noch nicht warum?
Hier erstmal der neue Code
Delphi-Quellcode:
Was ist denn nun der unterschied? Ob ich das Bitmap gleich zuordne, ...
procedure TFrmMain.Verschleiern(Status: Boolean);
var bm : TBitmap; begin if Status = TRUE then begin PanelVerschleiern := TPanel.Create(nil); PanelVerschleiern.Parent := FrmMain; PanelVerschleiern.Align := alclient; PanelVerschleiern.Visible := FALSE; PanelVerschleiern.BevelOuter := bvNone; ImageVerschleiern := TImage.Create(PanelVerschleiern); ImageVerschleiern.Parent := PanelVerschleiern; ImageVerschleiern.Align := alclient; bm := self.GetFormImage; try ImageVerschleiern.Picture.Bitmap := bm; finally bm.Free; end; AlphaBlendRect(ImageVerschleiern.Canvas,PanelVerschleiern.ClientRect,clblack,80); PanelVerschleiern.Show; end else begin PanelVerschleiern.Hide; FreeAndNil( ImageVerschleiern); FreeAndNil( PanelVerschleiern); end; end;
Delphi-Quellcode:
ImageVerschleiern.Picture.Bitmap := self.GetFormImage;
...oder erst über eine neue Variable?
Delphi-Quellcode:
bm := self.GetFormImage;
try ImageVerschleiern.Picture.Bitmap := bm; finally bm.Free; end; |
Re: Pobleme mit FREE (bzw. Destroy)
Das sollte nur ein Beispiel sein. Eigentlich müsste es auch so gehen (ungetestet):
Delphi-Quellcode:
Das natürlich, bevor Du das Image selbst freigibst.
FreeAndNil(ImageVerschleiern.Picture.Bitmap);
|
Re: Pobleme mit FREE (bzw. Destroy)
Das hatte ich so gemacht. Und da ging es nicht. Komisch
Trotzdem vielen Dank an alle!!! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:59 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz