AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Klassentyp zur Laufzeit ändern

Ein Thema von Carsten1234 · begonnen am 25. Mär 2009 · letzter Beitrag vom 26. Mär 2009
Antwort Antwort
Seite 1 von 2  1 2      
Carsten1234

Registriert seit: 9. Apr 2008
Ort: Vechelde
178 Beiträge
 
Delphi 8 Professional
 
#1

Klassentyp zur Laufzeit ändern

  Alt 25. Mär 2009, 06:16
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:
type
  TMainForm = class(TForm)
(...)
  end;

var
  MainForm: TMainForm;

(...)
  if (IsVista) then
<Pseudocode>
    MainForm:= TVistaForm;
</Pseudocode>
Geht das überhaupt?

Gruß, Carsten
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Klassentyp zur Laufzeit ändern

  Alt 25. Mär 2009, 06:20
So geht das nicht. Du könntest aber abhängig von OS die Instanz entsprechend erstellen:

Delphi-Quellcode:
if IsVista then
  Application.CreateForm(TVistaForm, frmMain)
else
  Application.CreateForm(TMainForm, frmMain);
Sinnvoller ist aber m.E. das der Implementierungscode einer Klasse alle Windows-OS-Versionen handeln kann.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Carsten1234

Registriert seit: 9. Apr 2008
Ort: Vechelde
178 Beiträge
 
Delphi 8 Professional
 
#3

Re: Klassentyp zur Laufzeit ändern

  Alt 25. Mär 2009, 06:27
Zitat von Bernhard Geyer:

Delphi-Quellcode:
if IsVista then
  Application.CreateForm(TVistaForm, frmMain)
else
  Application.CreateForm(TMainForm, frmMain);
Sinnvoller ist aber m.E. das der Implementierungscode einer Klasse alle Windows-OS-Versionen handeln kann.
Bisher habe ich lediglich unter Vista ein paar kl. Darstellungsprobleme von/bei zugekauften GUI-Komponenten. Während unter W2K und XP alles top aussieht, habe ich unter Vista die eben genannten Probleme (mal sehen, wie es unter Windows 7 aussieht). Derzeit behelfe ich mir diesbzgl. mit einer kl. Krücke, aber das ist auch noch nicht sooooo der Hit.

Ich werde das da oben mal testen, Danke dafür.

Gruß, Carsten
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: Klassentyp zur Laufzeit ändern

  Alt 25. Mär 2009, 06:46
Hier ein Hack, mit dem das doch geht:
Delphi-Quellcode:
type
  PClass = ^TClass;

begin
  PClass(MyObjectOfTypeXXX)^ := TDerivedClassFromXXX;
end;
Bei Dir funktioniert das nur, wenn TVistaForm von TMainForm abgeleitet ist.

Viel sauberer wäre folgende Lösung;
Delphi-Quellcode:
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);
...
Such mal unter dem Stichwort: 'Class Factory'.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Carsten1234

Registriert seit: 9. Apr 2008
Ort: Vechelde
178 Beiträge
 
Delphi 8 Professional
 
#5

Re: Klassentyp zur Laufzeit ändern

  Alt 25. Mär 2009, 07:00
Hhhmm, irgendwie bin ich heute morgen noch nicht so ganz wach.

Also, bisher leitet sich meine TMainForm wie folgt ab:
Delphi-Quellcode:
  TMainForm = class(TAdvToolBarForm)
  (...)
  end;
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.
Und hier kann ich noch nicht die Transferleistung erbringen zu Deinem Code.

Gruß, Carsten
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#6

Re: Klassentyp zur Laufzeit ändern

  Alt 25. Mär 2009, 07:08
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
42
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#7

Re: Klassentyp zur Laufzeit ändern

  Alt 25. Mär 2009, 07:15
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
42
  Mit Zitat antworten Zitat
Carsten1234

Registriert seit: 9. Apr 2008
Ort: Vechelde
178 Beiträge
 
Delphi 8 Professional
 
#8

Re: Klassentyp zur Laufzeit ändern

  Alt 25. Mär 2009, 07:21
Hallo Oki,

Zitat von oki:
es ist so gemeint, dass du zwei Fensterklassen erstellt. Einmal das von dir beschriebene und dann eins für Vista (sozusagen zwei Formulare).
Das bedeutet doch aber im Umkehrschluss, dass ich sämtliche Routinen (z.B. OnClick für einen Button usw.) doppel schreiben muss!?!?!
Einmal für die von mir beschriebene Version und einmal für die Vista-Form.

Gruß, Carsten
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#9

Re: Klassentyp zur Laufzeit ändern

  Alt 25. Mär 2009, 07:33
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
42
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#10

Re: Klassentyp zur Laufzeit ändern

  Alt 25. Mär 2009, 11:06
Zitat von oki:
Die Klasse eines instanziierten Objektes kann man nicht ändern.
Man kann schon , aber man kann sich damit auch gewaltig in den Fuß schiesen.
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;
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 22:58 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