*altenThreadausgrab*
Das gleiche Thema mit dem Freigeben dynamisch erzeugter Forms hatte ich jetzt auch in meinem aktuellen Projekt.
Zitat von
sirius:
Den kleinen Nachteil könnte man jetzt auch noch umgehe,n indem man von der ComponentList eine eigene Liste ableitet, die nach außen hin mit TForm arbeitet. Aber da dürfte der Aufwand höher sein. Ich mach das nur ganz selten und meist, wenn ich sowieso die Listenklasse umschreiben muss.
Genau das hab ich dafür mal gemacht. In den Anhang hab ich die
Unit gepackt, Verbesserungsvorschläge seh ich gerne, so oft hab ich noch keine neuen Klassen von anderen abgeleitet.
Ich hab die Klasse
TDynamicFormManager von
TObjectList abgeleitet und die Funktionen implementiert die ich brauchte:
- der DynamicFormManager wird im OnCreate der Anwendung erzeugt und im OnClose wieder freigegeben
- Forms werden normal erzeugt und mit AddForm() dem FormManager hinzugefügt, Beispiel:
Delphi-Quellcode:
procedure TMainForm.BBlubbClick(Sender: TObject);
var
AnyForm: TAnyForm;
begin
AnyForm := TAnyForm.Create(nil);
<machwasmitAnyform>;
DynFormManager.AddForm(AnyForm);
end;
AddForm setzt die Tag-Eigenschaft des Fensters auf einen einmaligen Wert (interner Zähler, wird bei jedem Aufruf der Funktion erhöht)
- die Forms werden mit DeleteFormByInternalIndex() freigegeben. Dazu wird der Funktion einfach der Tag des Fensters übergeben.
- in meinem Projekt hab ich zwei Arten von dynamischen Forms: welche die nur einmal aufgerufen werden sollen, und welche die mehrmals (mit unterschiedlichen Inhalten) aufgerufen werden können.
Ob die Form bereits existiert kann im ersten Fall durch GetFormByClassName() und im zweiten Fall durch GetFormByName() geprüft werden. Komplett sieht das bei mir so aus:
Delphi-Quellcode:
procedure TMainForm.BBlubbClick(Sender: TObject);
var
AnyForm: TAnyForm;
begin
AnyForm := TAnyForm(DynFormManager.GetFormByClassName('TAnyForm')); // oder z. B. AnyForm := TAnyForm(DynFormManager.GetFormByName('AnyForm1')); wenn mehrere Forms der Klasse TAnyForm möglich sein sollen
if Assigned(AnyForm) then
begin
AnyForm.Show;
AnyForm.BringToFront;
end
else
begin
AnyForm:= TAnyForm.Create(nil);
<machwasmitAnyForm>
DynFormManager.AddForm(AnyForm);
AnyForm.Show;
end;
end;
Den Tag der Form als Eigenschaft zur eindeutigen Identifikation der Form zu verwenden hat den Vorteil das man mit TForm arbeiten kann und nicht noch ne Klasse von TForm ableiten muss. Wenn man natürlich den Tag anderweitig verwendet, funktioniert das nicht mehr.