![]() |
Re: Nochmal: Ermiteln ob Objekt freigegeben wurde
Zitat:
Ich hab mir dazu mal einen "Objectbroker" gebastelt, der die ganze arbeit übernimmt. Dort meldet sich ein Object an oder ab. alle Zeiger auf objekte werden da verwaltet. Ein anderes Object fragt jetzt nicht mit assigned(Referenz) die Gültigkeit ab, sondern fragt den Objectbroker, ob objekt noch gültig ist. Zusätzlich kann man dem Objektbroker noch sagen, von welchem Objekt man die Abmeldenachricht in einem Event bekommen will ( um die eigene Referenz auf nil zu setzen). (Observer) Der Objektbroker löscht sich auch gegenseitig korrekt die Referenzen, da ein Objekt ja aus der Benachrichtigungsliste entfernt werden muss, wenn es gelöscht wird. |
Re: Nochmal: Ermiteln ob Objekt freigegeben wurde
Hi Mabuse,
es geht dir sicherlich um den Zeiger des Formulars, richtig? Legst du dir zusätzlich eine Zeiger-Variable an? Oder wird das Formular automatisch durch die Projektdatei erzeugt und besitzt "keine" Variable auf die du direkt zurückgreifen kannst? Hast du die Zeiger-Variable auch global definiert? |
Re: Nochmal: Ermiteln ob Objekt freigegeben wurde
Zitat:
|
Re: Nochmal: Ermiteln ob Objekt freigegeben wurde
Zitat:
Das Programm ist nicht von mir. Es ist relativ komplex. Es werden mehrere 100 Forms verwendet, die von TBasisForm (Forms) oder TBasisClientForm (Frames) abgeleitet sind, in TBasisForm und TBasisClientForm ist ein eigenes "Festerverwaltungssystem" implementiert. Dort wird noch einiges gemacht. Ich muß da erst mal durchsteigen. Mir ist nur aufgefallen, das teilweise GPF auftreten, da obiges Problem besteht. Das Problem muß ich nun zuerst lösen. (Anforderung der Anwender) Danke für Eure Anregungen, ich werde nun mal einen Weile debuggen und dann berichten wie ich es gelöst habe. mfg MaBuSE |
Re: Nochmal: Ermiteln ob Objekt freigegeben wurde
Du darfst die Variable Form2 nicht verwenden!!!
Empfehlung: globale Variable Form2 löschen.
Delphi-Quellcode:
function FindOrCreateForm(FormClass: TFormClass; var Reference):Boolean;
var i : Integer; begin for i := Screen.CustomFormCount-1 downto 0 do begin if Screen.CustomForms[i].ClassType = FormClass then begin TCustomForm(Reference) := Screen.CustomForms[i]; Result := True; // gefunden Exit; end; end; Application.CreateForm(FormClass, Reference); Result := False; // neu erzeugt end; procedure TForm1.Button1Click(Sender: TObject); var frm : TForm2; begin if FindOrCreateForm(TForm2, frm) then begin Memo1.Lines.Add(DateTimeToStr(now)+' Create'); end else begin Memo1.Lines.Add(DateTimeToStr(now)+' schon da'); end; Frm.Caption := 'Test'; Frm.Show; Frm.WindowState := wsNormal; // falls minimiert -> sichtbar machen end; |
Re: Nochmal: Ermiteln ob Objekt freigegeben wurde
Zitat:
Aber keine Angst, sie wird im Projekt nicht verwendet. Ich habe aber ein anderes Problem entdeckt. Einige Forms werden mehrfach (in versch. Variablen) erzeugt. Bsp:
Delphi-Quellcode:
In dem Form2 habe ich keinen Zugriff auf privateForm1Var.
...
// in unit1.pas procedure TForm1.methode; begin if not assigned(privateForm1Var) then begin privateForm1Var := TForm2.Create(self); end; privateForm1Var.show end; // in unit3.pas procedure TForm3.andereMethode; begin if not assigned(privateForm3Var) then begin privateForm3Var := TForm2.Create(self); end; privateForm3Var.show end; ... 1. ist die Unit1 und Unit3 nicht in der uses des Form1 und 2. ist die Variable privat (lokal) Außerdem weis ich ja gar nicht in welcher Variable das TForm2 enthalten ist. Damit es nicht langweilig wird, sind manchmal auch mehrere Instanzen gleichzeitig aktiv. (also privateForm1Var <> privateForm3Var und beide <> nil) Ich kann also folgenden SourceCode nicht ausführen:
Delphi-Quellcode:
Folgendes funktioniert auch nicht, da dann zwar self auf nil gesetzt wird, aber privateForm1Var immer noch auf den "alten" Speicherbereich zeigt.
...
// Vorschlag von [user]tomsel[/user] procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin // hier werden noch viele weitere Dinge freigegeben Action := caFree; privateForm1Var := nil; end; ...
Delphi-Quellcode:
Der Lösungsansatz von shmia gefällt mir prinzipiell gut, aber es kann nur ein Form pro Typ erzeugt werden. Das Form muss aber auch mehrmals "sichtbar" sein.
...
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin // hier werden noch viele weitere Dinge freigegeben Action := caFree; self := nil; end; ... Die Idee von Bernhard Geyer das ![]() Der Lösungsansatz von dataspider scheint wohl der Beste zu sein. Das Problem dort ist allerdings, dass die lokale Variable im Form definiert sein muss und das bei jedem Objekt das eine Instanz erzeugt die Notification abgeleitet werden muss. Ich werde mit wohl eine FormFactory bauen müssen, die mir die Forms erzeugt und intern in einer Liste abspeichert. Diese FormFactory muß dann auch das Notification implementieren und dann die entsprechenden Speicherbereiche auf Nil setzen. Mal schauen ob das funktioniert. Danke an alle für die Anregungen |
Lösung: Nochmal: Ermiteln ob Objekt freigegeben wurde
Hallo,
ich habe eine einfache Lösung für mein Problem gefunden. Man muß dem Objekt nur bekannt machen welche Variable es referenziert. Diese kann man dann in onClose auf nil setzen. Man muß nur darauf achten, das man sich keine Kopie der Instanzvariablen, sondern die Adresse selber merkt. (Pointer auf Form2 vom Typ ^TForm2) Diesem Pointer weist man dann die Adresse zu := @Form2. Das war's. Relativ einfach, oder? ps: Vielen Dank an NicoDE, es war eigentlich seine Idee :thumb: Unit1 mit dem MainForm:
Delphi-Quellcode:
Und hier ist die Unit2 mit dem SubForm:
...
procedure TForm1.Button1Click(Sender: TObject); begin if not assigned(Form2) then begin Form2 := TForm2.Create(self); Form2.MyInstance := @Form2; end; form2.show; end; ...
Delphi-Quellcode:
...
unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm2 = class(TForm) procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private-Deklarationen } public { Public-Deklarationen } MyInstance: ^TForm2; end; var Form2: TForm2; implementation {$R *.dfm} procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; MyInstance^ := nil; end; end. ... |
Re: Lösung: Nochmal: Ermiteln ob Objekt freigegeben wurde
Zitat:
Für die konkrete Problemstellung war es die schnellste (und 'dreckigste' ;)) Lösung mit möglichst wenig Änderungen am bestehenden Projekt. Kommt bei neuen Projekten bitte nicht auf die Idee diesen Lösungsweg als Vorlage zu verwenden. |
Re: Nochmal: Ermiteln ob Objekt freigegeben wurde
Begründung?????
|
Re: Nochmal: Ermiteln ob Objekt freigegeben wurde
Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:17 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 by Thomas Breitkreuz