![]() |
Klassentyp zur Laufzeit ändern
Hallo zusammen,
ich habe eine MainForm vom Typ TForm, deren Klasse ich gerne in Abhängigkeit vom OS beim Programmstart ändern möchte. Bsp.:
Delphi-Quellcode:
Geht das überhaupt?
type
TMainForm = class(TForm) (...) end; var MainForm: TMainForm; (...) if (IsVista) then <Pseudocode> MainForm:= TVistaForm; </Pseudocode> Gruß, Carsten |
Re: Klassentyp zur Laufzeit ändern
So geht das nicht. Du könntest aber abhängig von OS die Instanz entsprechend erstellen:
Delphi-Quellcode:
Sinnvoller ist aber m.E. das der Implementierungscode einer Klasse alle Windows-OS-Versionen handeln kann.
if IsVista then
Application.CreateForm(TVistaForm, frmMain) else Application.CreateForm(TMainForm, frmMain); |
Re: Klassentyp zur Laufzeit ändern
Zitat:
Ich werde das da oben mal testen, Danke dafür. Gruß, Carsten |
Re: Klassentyp zur Laufzeit ändern
Hier ein Hack, mit dem das doch geht:
Delphi-Quellcode:
Bei Dir funktioniert das nur, wenn TVistaForm von TMainForm abgeleitet ist.
type
PClass = ^TClass; begin PClass(MyObjectOfTypeXXX)^ := TDerivedClassFromXXX; end; Viel sauberer wäre folgende Lösung;
Delphi-Quellcode:
Such mal unter dem Stichwort: 'Class Factory'.
Type
TFormClass = Class Of TMyMainForm; TVistaForm = Class (TMyMainForm)... TWindows7Form = Class (TMyMainForm)... TWINNTForm = Class (TMyMainForm)... Var FormClass : TFormClass; Begin // Das hier ist eine Class-Factory (nun ja, wenn sie einmal groß ist) Case OSType Of Vista : FormClass := TVistaForm; Windows7 : FormClass := TWindows7Form; ... End; // Application.CreateForm (FormClass, MyFormInstance); ... |
Re: Klassentyp zur Laufzeit ändern
Hhhmm, irgendwie bin ich heute morgen noch nicht so ganz wach. :angel2:
Also, bisher leitet sich meine TMainForm wie folgt ab:
Delphi-Quellcode:
Unter Vista habe ich leider die genannten Darstellungsproblemchen, so dass ich (erstmal) speziell für Vista meine TMainForm nicht ableiten möchte von TAdvToolbarForm, sondern schlicht von TForm.
TMainForm = class(TAdvToolBarForm)
(...) end; Und hier kann ich noch nicht die Transferleistung erbringen zu Deinem Code. :wall: Gruß, Carsten |
Re: Klassentyp zur Laufzeit ändern
Moin,
Somit hat Bernhadt aber schon recht. Die Klasse eines instanziierten Objektes kann man nicht ändern. Der entscheidende Punkt ist, dass das Objekt mir der passenden Klasse instanziiert wird. Ich finde alzaimar's Ansatz mir der Metaklasse aber sehr elegant. Dies vorallem, dass nur an einer Stelle die Entscheidung über die richtige Klassenauswahl getroffen werden muss und danach "normal" gecoded werden kann. Umständliche cases auf den BS-Typ an jeder weiteren Stelle im Code kann verzichtet werden was die Fehlerquote rapide senken sollte. Ich persönlich halte das für eine sehr elegante Lösung und würde diese verwenden. Die Instanz der Form muss aber auf jeden Fall mit der passenden Klasse gebildet werden. Ein nachträgliches Ändern halte ich für nicht akzeptabel oder ehen unmöglich (habe das mit der Zeigerthematik auf die Klasse in alzaimar's Beispiel aber auch noch nicht komplett durchschaut). Gruß oki |
Re: Klassentyp zur Laufzeit ändern
Hi Carsten,
es ist so gemeint, dass du zwei Fensterklassen erstellt. Einmal das von dir beschriebene und dann eins für Vista (sozusagen zwei Formulare). Beide Fensterklassen "sammelst" du unter einer Metaklasse. Beim Start des Programms wertest du das Betrieblssystem aus und weist deiner Metaklasse die passende Fenserklasse zu. Bei Vista dann den Klassennamen deines Form für Vista. Jetzt kannst du dein MainForm ganz normal mit dem Klassentyp deiner Metaklasse instanziieren, weil du vorher dieser ja den passenden Klassentyp zugewiesen hast. Im gesamten Code arbeitest du dann immer mit dem Metaklassenbezeichner hinter dem sich der richtige Klassentyp verbirgt. Ein aufwendiges Abfragen an jeder Stelle des Codes welches OS läuft entfällt dann. Gruß oki |
Re: Klassentyp zur Laufzeit ändern
Hallo Oki,
Zitat:
Einmal für die von mir beschriebene Version und einmal für die Vista-Form. Gruß, Carsten |
Re: Klassentyp zur Laufzeit ändern
nun ja, zumindest für den Teil, der bei Vista anders ist.
Entweder du hast je eine Klasse für jedes OS, dann macht das mit der Klassenänderung auch Sinn. Ob du dabei die Klassen untereinander vererbst oder jede speziell erstellst bleibt dir überlassen. Deine Frage war ja, ob du die Klasse ändern kannst. Also mußt du auch eine andere Klasse haben. Was soll sonst deine "Vista-Klasse" sein als anderer implementierter Code. Wenn du nur spezielle wenige Dinge im Code deines Forms anders machen mußt kann du durchaus auch mit einer Klasse arbeiten und in den entsprechenden Abschnitten das OS abfragen und den passenden Code ausführen. Ganz nach belieben. Gruß oki |
Re: Klassentyp zur Laufzeit ändern
Zitat:
Es ist auch möglich, dass der Trick nach dem Wechsel des Compiler nicht mehr funktioniert. Die neue Klasse muss vor der bisherigen Klasse abgeleitet sein und ausserdem darf die abgeleitete Klasse keine zusätzlichen Felder haben.
Delphi-Quellcode:
procedure ChangeClass(obj : TObject; NewClass:TClass);
type PClass = ^TClass; begin if Assigned(obj) and (obj.ClassType <> NewClass) then begin if obj.ClassType <> NewClass.ClassParent then raise Exception.CreateFmt('can''t change Object of class %s to class %s', [obj.ClassName, NewClass.ClassName]); if obj.InstanceSize <> NewClass.InstanceSize then raise Exception.CreateFmt('Class %s - invalid instance size', [NewClass.ClassName]); PClass(obj)^ := NewClass; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:51 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