AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi 'TMyForm' nach TMyForm casten ? ("lebendig" werden lassen?)
Thema durchsuchen
Ansicht
Themen-Optionen

'TMyForm' nach TMyForm casten ? ("lebendig" werden lassen?)

Ein Thema von st2000 · begonnen am 30. Sep 2003 · letzter Beitrag vom 2. Okt 2003
Antwort Antwort
st2000

Registriert seit: 23. Apr 2003
Ort: Hamburg
52 Beiträge
 
Delphi 5 Enterprise
 
#1

'TMyForm' nach TMyForm casten ? ("lebendig" werden

  Alt 30. Sep 2003, 16:50
Hallo,

hier mal eine gaaanz verwegene Frage : (ist vermutlich Unsinn, aber wer weiss...)

Ich würde gern eine Function schreiben, welche den NAMEN eines Formulartyps TMyForm1, TMyForm2, usw.
als String übergeben bekommt, und die dann aus dem tatsächlich als Klasse definierten TMyForm1 eine Instanz created (die von mir gesuchte Funktion nenne ich mal StrToClass):

Delphi-Quellcode:
Function FormAufruf (Formtyp: String): TForm;
Begin

Result:=StrToClass(FormTyp).Create(Application);

end;
In der aufrufenden Procedure könnte ich das dann weiternutzen :

Delphi-Quellcode:
Procedure Formbenutzen;
var
BenutzForm: TForm;
BenutzFormName: String;

Begin
BenutzFormName:='TMyForm1';

Benutzform:=FormAufruf(BenutzFormName);

BenutzForm.Showmodal;

BenutzForm.Free;

End;
Wäre ja quasi ein Pinocchio-Effekt : Aus einem 'hölzernen' String wird ein 'lebendiges' Formular.
Nicht anvisiert ist hier eine CASE-Struktur, die alle vorhandenen TMyForm? abfragt, und in der auch alle vorhandenen Typen vorher eingetragen werden sollen...

Hat jemand sowas schon mal gemacht ? Gibts da eine Funktion ? Ist das etwa was triviales, was ich nur einfach nicht kenne ?
Oder ist es schlicht unmöglich ?

In der OH oder in DP habe ich mit den dollsten Suchbegriffen nix gefunden....

Bin für jeden Tip dankbar, da ich sonst einen MeGa-Case schreiben darf.....

Viele Grüsse,
ST2000
Stefan
Keine Softwarepatente ! Die Polen = wahre Freiheitskämpfer !!! Gerade noch rechtzeitig Mitglied geworden, um die Notbremse zu ziehen. Year !!!
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.611 Beiträge
 
#2

Re: 'TMyForm' nach TMyForm casten ? ("lebendig" we

  Alt 30. Sep 2003, 17:14
Trivial ist die Lösung nicht, aber interessant.

Du schreibst eine Klasse, die Dir Formulare zurückgibt. Da sie die Dinger produziert nennen wir sie einfach mal FormFactory. Was die genau macht kommt am Ende. Im Initialization Teil der Unit-Deklaration erzeugst Du eine globale(!) Variable mit der Factory und erzeugst eine Instanz. Im Finalization Teil zerstörst Du sie wieder. Wir programmieren schliesslich ordentlich

Diese Unit (wo die FormFactory drin ist) bindest Du bei allen Formularen ein, die Du zur Laufzeit herzaubern willst.

Im Initialization Teil der Units mit den Formularen trägst Du das Formular dann in der Factory ein. Du machst das Formular also sozusagen bei der Factory bekannt.

Die Factory selber macht folgendes:

Sie hält einen Container von Formularnamen und einen von Forms vor. Ein Formular wird dann z.B. mit:
Delphi-Quellcode:
Initialization
   FormFactory.RegisterForm('Normales Fenster', TForm);
registriert.

Die Factory nimmt also einen String und ein Objekt vom Typ TForm auf. Da jedes Deiner Formulare von TForm abgeleitet ist ist das kein Problem. Diese Registrierung packt deine Factory dann ins 'Lager'.

Wenn Du nun ein Formular haben willst, machst Du folgendes:
Delphi-Quellcode:
var Formular: TForm
begin
   Formular := FormFactory.GetForm('Normales Fenster');
Die Factory sucht nun nach dem String, pickt sich die übergebene Klasse heraus (in dem Fall ein TForm) und erzeugt das ganze Ding. z.B. in einem result := m_FormArray[m_NameArray.IndexOf('Normales Fenster')].Create(self);

Anstelle dem fixen String halt eine Variable.

Da in dem Formarray ja ein Pointer auf die beim Registrieren angegebene Klasse vorliegt und eben kein reguläres TForm kannst Du hierüber alle registrierten Formulare zur Laufzeit anfordern.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
st2000

Registriert seit: 23. Apr 2003
Ort: Hamburg
52 Beiträge
 
Delphi 5 Enterprise
 
#3

Re: 'TMyForm' nach TMyForm casten ? ("lebendig" we

  Alt 30. Sep 2003, 17:53
Hallo Phoenix,

Vielen Dank für das schnelle Feedback.

Verstehe ich es denn richtig :

Delphi-Quellcode:
Initialization
   FormFactory.RegisterForm('Normales Fenster', TForm);
hätte dann die Deklaration RegisterForm(FormName: String, FormTyp: TForm); und ich lege in der FormFactory-Klasse dann das besagte Array m_FormArray[] an, welches ich als array m_FormArray[] of TForm deklariere.

Ist dann zwar auch eine Art Index von MyForm-Typen, die ich aber dann zumindest per Anmeldung bequem eintragen lassen kann.... Klingt gut. Jedenfalls eleganter als ein Endlos-Case.

Ist doch richtig : Wenn ich bei 'Normales Fenster' -> TMyForm4711 mit

result := m_FormArray[m_NameArray.IndexOf('Normales Fenster')].Create(self); eine Instanz Result -> MyForm4711 erzeuge und diese als TForm an eine die FormFactory aufrufende Procedure übergebe, kann ich doch in der weiteren Verwendung der Instanz mit TMyForm4711 bzw. den darauf zeigenden Pointer stets zurückcasten ?
Also :
TMyForm4711(ErzeugteForm=TForm).MethodeAusTMyForm4711 führt dann eine Methode aus, die es NUR in TMyForm4711 und nicht in TForm gibt ???

Im Grunde würde es dann ja reichen, nur den richtigen Pointer für 'Normales Fenster' zu ermitteln, der seinerzeit beim RegisterForm erstellt wurde, und diesen dann in der die FormFactory aufrufenden Procedure zu benutzen, um erst dort das MyForm4711 zu instanzieren. Dann hätte man ausserhalb der FormFactory beides noch verfügbar : Das Form und den Pointer auf TMyForm4711.

Aber geht das mit dem Casten so ? TMyForm4711 instanzieren -> als TForm übergeben an aufrufende Procedure -> dort mit TMyForm4711(TForm) casten -> alle individuellen Methoden und Attribute der TMyForm4711 - Klasse weiterbenutzen ?

Gruß,
ST2000
Stefan
Keine Softwarepatente ! Die Polen = wahre Freiheitskämpfer !!! Gerade noch rechtzeitig Mitglied geworden, um die Notbremse zu ziehen. Year !!!
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.611 Beiträge
 
#4

Re: 'TMyForm' nach TMyForm casten ? ("lebendig" we

  Alt 1. Okt 2003, 07:50
Ja, prinzipiell geht das schon.

Ich würde aber nie 'hart' casten (also TMyForm4711(Form).blafasel ) sondern immer nur 'weich' : (Form as TMyForm4711).blafasel

Das hat den Vorteil, daß Dir der Compiler Fehlermeldungen gibt, wenn Du etwas hast, das sich nicht als TMyForm4711 casten lässt.

Was den Pointer angeht: Du kannst ja neben FormFactory.GetForm (das direkt instanziert) noch ein FormFactory.GetClass implementieren, das Dir den Pointer direkt durchreicht.
So bist Du imho ein wenig flexibler. Allerdings hab ich bisher für sowas noch keine Anwendung gefunden.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
st2000

Registriert seit: 23. Apr 2003
Ort: Hamburg
52 Beiträge
 
Delphi 5 Enterprise
 
#5

BTW... woher nehme ich .RegisterForm(...,TForm) ???

  Alt 1. Okt 2003, 12:33
Hallo Phoenix,

da fällt mir nun aber noch ein: Um die FormFactory.RegisterForm - Methode auszuführen, also eine Formularklasse anzumelden, brauche ich doch zunächst den Formular-Typen als Übergabeparameter.

Irgendwo muss ich ja dann eine Routine schreiben, die z.B. bei Programmstart die ganzen Formklassen per .RegisterForm (String,TForm) registriert.

Kann ich denn irgendwo auslesen, welche "Type TMyForm? = class(Tform)" - Deklarationen vorhanden sind ?

Müsste ja im Grunde gehen, denn soweit ich eine Unit mit so einer Klassendeklaration mit uses einbinde, steht der Typ ja für einen create zur Verfügung.
Demnach müßte Delphi ja bei Programmstart (oder nur bei Compilestart?) irgendwo einen Index der ganzen gefundenen Type-Statements in den diversen Units erstellen.
Wenn ich Create(TMyForm1) anweise, ist TMyForm1 doch strenggenommen nur ein bereits angelegter Zeiger auf eben diesen Typ, richtig ?

Weisst Du, wie man das anzapfen kann ? Um die Typen(-Zeiger) durchzuiterieren und in mein FormFactory-Typen-Inventar zu registrieren ?

Sonst muss ja doch wieder irgendeine statische Auflistung aller Klassen her. Und es können 70-100 werden...

Gruss,
ST2000
Stefan
Keine Softwarepatente ! Die Polen = wahre Freiheitskämpfer !!! Gerade noch rechtzeitig Mitglied geworden, um die Notbremse zu ziehen. Year !!!
  Mit Zitat antworten Zitat
Benutzerbild von maximov
maximov

Registriert seit: 2. Okt 2003
Ort: Hamburg
548 Beiträge
 
Delphi 2005 Professional
 
#6

Re: 'TMyForm' nach TMyForm casten ? ("lebendig" we

  Alt 2. Okt 2003, 13:54
Hallo jungs...hallo PD!

Was haltet ihr von dieser lösung?

Delphi-Quellcode:
implementation

{$R *.dfm}


var f:TForm;

procedure TForm1.Button1Click(Sender: TObject);
begin
  f := StrToForm('TForm1');
  if f<>nil then f.Show;
end;

function StrToForm(className:string):TForm;
var c:TClass;
begin
  c:=FindClass(className);
  if (c<>nil) and c.InheritsFrom(TForm) then result := TFormClass(c).Create(nil);
end;

initialization

  registerclass(TForm1);


end.
..warum nicht bereits vorhandene möglichkeiten nutzen?

mfg
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:59 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz