Zitat von
hhluemmel:
Hallo ich habe in einer Komponente (TCollection) Informationen über Formulare (TForm) gespeichert, hinterlegt sind die FormClass (TFormClass) sowie das Form (TForm) selbst.
Ich habe zwar (bis vorhin) noch nicht bewust mit TCollections gearbeitet, aber das scheint ja noicht soo schweer zu sein
Ich habe ein kleines beispiel Programm geschrieben, dass ich später noch genauer erkläre.
Zitat von
hhluemmel:
Ich kann über den Objektinspektor auf die Eigenschaften zugreifen, sind auch alle da! nur ich kann weder das Formular erstellen, anzeigen, oder gar die Formclass registriesen!
Ich habe nur zur Laufzeit damit gearbeitet, also kein ObjektInspektor
Zitat von
hhluemmel:
Ich möchte auch vermeiden, auf jedem Formulare RegisterClass aufzurufen, das wäre doch unsinng, da alle Informaionen in der Komponente hinterlegt sind.
Wie so ist das unsinnig, die TCollections ist doch nur ein "Sammelbehälter" für viele TCollectionItems, die dann die Forms beinhalten. Die Klassen der Formularte sind ja trotzdem einzeln definiert. Also kannst du auch bei jeder Klassendefinition ein RegisterClass einbauen (z.B. im initialization Teil der
Unit, wobei Forms doch automatisch registriert sind, oder?)
In der Delphi 7 Onlinehilfe steht
Mit RegisterClass kann eine Klasse beim Streaming-System registriert werden. In einer Formulardeklaration enthaltene Formular- und Komponentenklassen (Instanzvariablen) werden automatisch registriert. Alle anderen in einer Anwendung verwendeten Klassen müssen mit RegisterClass explizit registriert werden, wenn Instanzen gespeichert werden sollen.
Abgesehen davon kannst Du ja prüfen ob eine Klasse registriert worden ist:
In der Delphi 7 Onlinehilfe steht
IdentToInt gibt nil (Delphi) bzw. NULL (C++) zurück, wenn die angegebene Klasse noch nicht registriert ist.
So nun zu meinem kleinen Beispiel:
Es gliedert sich in drei Units:
- u_frmMain - das Hauptformular mit 5 TButton und einer TListBox
- u_frmDialog - ein Beispiel Formular mit nur einem TLabel und einem TButton (mit Close
- u_TLinkedForm - Hier ist ein TLinkedForm definiert. Eine eigene TColletion habe ich nicht abgeleitet.
Delphi-Quellcode:
unit u_TLinkedForm;
interface
uses SysUtils, Forms, Classes;
type
TLinkedForm =
class(TCollectionItem)
private
FForm: TForm;
// hier wird das instanzierte Form gespeichert
FFormClass: TFormClass;
procedure SetFormClass(
const Value: TFormClass);
protected
function GetDisplayName:
string;
override;
public
constructor Create(ACollection: TCollection);
override;
destructor Destroy;
override;
procedure Show;
published
// Form ist readonly, wird durch zuweisen von FormClass instanziert
property Form: TForm
read FForm;
property FormClass: TFormClass
read FFormClass
write SetFormClass;
end;
implementation
{ TLinkedForm }
constructor TLinkedForm.Create(ACollection: TCollection);
begin
inherited;
SetFormClass(TForm);
// per Default wird eine "leere" TForm erzeugt
end;
destructor TLinkedForm.Destroy;
begin
FForm.Free;
FForm :=
nil;
inherited;
end;
function TLinkedForm.GetDisplayName:
string;
begin
Result := FForm.Caption;
// Der Name, der in der Liste angezeigt wird
end;
procedure TLinkedForm.SetFormClass(
const Value: TFormClass);
begin
// wird aufgerufen wenn FormClass gesetzt wird
if FFormClass <> Value
then
begin
FFormClass := Value;
if Assigned(FForm)
then
begin // Wenn Form instanziert, dann freigeben
FForm.Free;
FForm :=
nil;
end;
FForm := Value.Create(
nil);
// FormClass instanzieren
// und Caption setzen (testweise, um in der Liste etwas anzuzeigen :-)
FForm.Caption := '
Test ('+IntToStr(self.ID)+'
) - ['+TimeToStr(now)+'
]';
end;
end;
procedure TLinkedForm.Show;
begin
FForm.Show;
// Ist eigentlich unnötig, da mit LinkedForm.Form.Show erreichbar
end;
end.
Der Quellcode erklärt sich eigentlich selbst
Du kannst nun ein
mc : TCollection;
definieren und dann Forms reinschieben.
Delphi-Quellcode:
procedure TfrmMain.btnAddFormClick(Sender: TObject);
var
f: TLinkedForm;
begin
f := mc.Add as TLinkedForm;
// obwohl Form readonly ist, kann man trotzdem seine Eigenschaften setzen
f.Form.Position := poDefaultPosOnly; // Damit es nicht (0,0) erscheint
f.show;
FillListBox(Sender);
end;
Eine Liste der Forms bekommt man ganz leicht mit:
Delphi-Quellcode:
procedure TfrmMain.FillListBox(Sender: TObject);
var
i : Integer;
begin
// Zeigt die Liste der enthaltenen Forms in der Listbox an
ListBox1.Items.Clear;
for i := 0 to mc.Count - 1 do
begin
ListBox1.Items.Add( mc.Items[i].DisplayName + ': ' +
(mc.Items[i] as TLinkedForm).Form.ClassName )
end;
end;
Eine FormClass kann man auch ganz einfach zuweisen:
Delphi-Quellcode:
procedure TfrmMain.btnAddFrmDialogClick(Sender: TObject);
var
f: TLinkedForm;
begin
f := mc.Add as TLinkedForm;
f.FormClass := TfrmDialog;
f.show;
FillListBox(Sender);
end;
In demBeispiel wird ja die FForm direkt instanziert, somit kann das Form auch direkt mit Show; angezeigt werden.
Ich hoffe das Beispiel hilft Dir etwas weiter.