Einzelnen Beitrag anzeigen

Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.840 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

Re: Probleme mit TForm bzw. TFormClass innerhalb von Kompone

  Alt 28. Apr 2005, 08:31
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.
Angehängte Dateien
Dateityp: zip tcollection_beispiel_199.zip (3,5 KB, 9x aufgerufen)
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
  Mit Zitat antworten Zitat