Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Probleme mit TForm bzw. TFormClass innerhalb von Komponenten (https://www.delphipraxis.net/44939-probleme-mit-tform-bzw-tformclass-innerhalb-von-komponenten.html)

hhluemmel 27. Apr 2005 09:49


Probleme mit TForm bzw. TFormClass innerhalb von Komponenten
 
Hallo ich habe in einer Komponente (TCollection) Informationen über Formulare (TForm) gespeichert, hinterlegt sind die FormClass (TFormClass) sowie das Form (TForm) selbst.

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 möchte gern - innerhalb der Komponente - alle Forms die speichert sind mit RegisterClass registrieren, damit ich damit weiterarbeiten kann. Nur ich bekomme immer eine Fehlermeldung.
Auch wenn ich die Komponente innerhalb einer Anwendung benutze und von dort auf die FormClass
zugreife um diese zu registrieren bekomme ich auch eine Fehlermeldung. Ich dann die Formulare anzeigen, wenn diese automatisch geladen wurden. Ich möchte die Formulare gern dynamisch innerhalb der Komponente erzeugen.

Ich möchte auch vermeiden, auf jedem Formulare RegisterClass aufzurufen, das wäre doch unsinng, da alle Informaionen in der Komponente hinterlegt sind.

Darf man das TFormObjekt grundsätzlich nicht in Komponenten verwenden oder was mache ich falsch??? :wall:

Für Informaitonen, Hilfe und vielleicht ein Beispiel wäre ich sehr dankbar!

:witch:

MaBuSE 28. Apr 2005 07:31

Re: Probleme mit TForm bzw. TFormClass innerhalb von Kompone
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

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:

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:

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
Delphi-Quellcode:
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.

hhluemmel 4. Mai 2005 12:21

Re: Probleme mit TForm bzw. TFormClass innerhalb von Kompone
 
Ich Danke alle die sich an der Diskussion beteiligt haben, das Problem ist gelöst!

MaBuSE 4. Mai 2005 12:53

Re: Probleme mit TForm bzw. TFormClass innerhalb von Kompone
 
Zitat:

Zitat von hhluemmel
Ich Danke alle die sich an der Diskussion beteiligt haben, das Problem ist gelöst!

Gern geschehen ;)

Ach ja, hab ich ganz vergessen:

Herzlich willkommen in der DP :dp:


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:41 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