Delphi-PRAXiS
Seite 1 von 2  1 2      

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 class(TPersistent) - Zugriff auf "höhere" Prozeduren (https://www.delphipraxis.net/51846-class-tpersistent-zugriff-auf-hoehere-prozeduren.html)

Merlin1988 20. Aug 2005 11:43


class(TPersistent) - Zugriff auf "höhere" Prozedur
 
Hi

Ich habe eine eigene Komponente, welche eine Hauptklasse beinhaltet (abgeleitet von TPaintbox)
und mehrere Unterklassen (abgeleitet von TPersistent), die zum Teil wiederum einige Unterklassen, abgeleitet von Tpersistent, beinhalten. Dies dient dazu im Objektinspektor eine Art "Treeview" darzustellen. [Vielleicht blöd ausgedrückt ^^], also wie "Font".
Jetzt möchte ich bei einer Änderung einer Property bzw. Subproperty eine Procedure / Function der Hauptklasse aufrufen. Das Problem ist nur das die Unterklasse, wo die Änderung geschieht, nichts von der Hauptklasse und deren Procedures weiss. (Es kann sein, dass die Änderung zum Beispiel in der 5. Unterklasse einer Hauptklasse geschieht.)

Wie kann ich also von einer Unterklasse die Procedures und Functions der Hauptklasse aufrufen (Beweggrund: die Hauptklasse kennt alle Variablen die in der Komponente/Hauptklasse vorkommen, was zum Zeichnen der Kopmonente wichtig ist) ???

Khabarakh 20. Aug 2005 11:49

Re: class(TPersistent) - Zugriff auf "höhere" Proz
 
Ich würde in den Unterklassen ein Event auslösen und dieses in der Hauptklasse dann verarbeiten. Das hat den Vorteil, dass die Unterklasse keine Informationen von der übergeordneten Klasse benötigt.

Merlin1988 20. Aug 2005 11:50

Re: class(TPersistent) - Zugriff auf "höhere" Proz
 
und wie würde das dann aussehen. Quelltext technisch :-D

SirThornberry 20. Aug 2005 11:52

Re: class(TPersistent) - Zugriff auf "höhere" Proz
 
wenn du beim Create der unterclassen (TComponent) den Owner angegeben hast könntest du dich anhand dessen nach oben durchhangeln.

Merlin1988 20. Aug 2005 12:20

Re: class(TPersistent) - Zugriff auf "höhere" Proz
 
funktioniert das auch wenn die Unterklassen von TPersistent abgeleitet sind ???

Merlin1988 20. Aug 2005 12:25

Re: class(TPersistent) - Zugriff auf "höhere" Proz
 
1. Wie würde der Constructor dann aussehen ??
2. Kann ich mich über "Owner" hochangeln ??

Khabarakh 20. Aug 2005 12:30

Re: class(TPersistent) - Zugriff auf "höhere" Proz
 
Für dieses Projekt habe ich beide Varianten benutzt:
Für das OffScreenBitmap und andere untergeordnete Klassen hat die Ereignis-Variante genügt, zur Vereinfachung habe ich noch eine gemeinsame Basisklasse geschrieben:
Delphi-Quellcode:
TNotifyingPersistent = class(TPersistent)
  private
    FOnChange: TNotifyEvent;
  protected
    procedure Change; virtual;
  public
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
  end;

[...]

{ TNotifyingPersistent }

procedure TNotifyingPersistent.Change;
begin
  if Assigned(FOnChange) then
    FOnChange(Self);
end;
Die Implementierung in die Basisklasse sah dann so aus:
Delphi-Quellcode:
TMathImage = class(TCustomControl)
  private
    [...]
    FBit: TMathBitmap;
    procedure SomeEventhandler(Sender: TObject);
  published
    [...]
    property MathBitmap: TMathBitmap read FBit write SetBit;
  end;

procedure TMathImage.SomeEventhandler(Sender: TObject);
begin
  Redraw;
end;

constructor TMathImage.Create;
begin
  inherited;
  [...]

  FBit := TMathBitmap.Create;
  FBit.OnChange := SomeEventhandler;
end;
Für die View-Property habe ich aber Zugriff auf das Image gebraucht, deshalb muss hier zusätzlich zum Ereignis der Owner angegeben werden:
Delphi-Quellcode:
  TMathImage = class; // Forward-Deklaration
  TMathFloatRectClass = class(TNotifyingPersistent)
  private
    FOwner: TMathImage;
    [...]
  public
    constructor Create(AOwner: TMathImage);
    procedure NormalizeRect;
  end;

{ TMathFloatRectClass }

constructor TMathFloatRectClass.Create;
begin
  inherited Create;
  FOwner := AOwner;
  TestRect;
end;

procedure TMathFloatRectClass.NormalizeRect;
var
  yRel, yCenter: MathFloat;
begin
  // xAbs / yAbs = xRel / yRel
  // yRel = yAbs / xAbs * xRel
  if Assigned(FOwner) and (FOwner.Height <> 0) and (FOwner.Width <> 0) then
    with FRect do
    begin
      yRel := FOwner.Height / FOwner.Width * (Right - Left);
      yCenter := (Top + Bottom) / 2;
      Top := yCenter + yRel / 2 * (Ord(Top > yCenter) * 2 - 1);
      Bottom := yCenter + yRel / 2 * (Ord(Bottom > yCenter) * 2 - 1);
      Change;
    end;
end;
Der Zugriff ist also problemlos über FOwner möglich (wobei hier ein FOwner: TCustomControl ohne Forward-Deklaration gereicht hätte).
Endergebnis:
http://img388.imageshack.us/img388/9939/oi2ce.png

Merlin1988 20. Aug 2005 16:08

Re: class(TPersistent) - Zugriff auf "höhere" Proz
 
ich hab das jetzt so versucht zu lösen, indem ich den Owner bei Create übergebe und in einer Variable speichere.
Jetzt weiss ich nur nicht von welchem Typ der Owner sein muss ??
Das Problem ist, wenn der Owner den Typ der Hauptklasse hat, muss diese vorher deklariert sein. Dann kann aber die Hauptklasse keine Variable vom Typ der Unterklasse haben, weil diese noch nicht bekannt ist.

Robert_G 20. Aug 2005 16:34

Re: class(TPersistent) - Zugriff auf "höhere" Proz
 
Zitat:

Zitat von Khabarakh
Ich würde in den Unterklassen ein Event auslösen und dieses in der Hauptklasse dann verarbeiten. Das hat den Vorteil, dass die Unterklasse keine Informationen von der übergeordneten Klasse benötigt.

Dafür würde ich auch meine Stimme abgeben. ;)
Auf die Art kann man die Klassen auch schön entkoppeln, da nicht zwangsläufig eine Dorfstraßen-Kommune entstehen muss, in der jede Klasse jede andere kennt. :)

Flocke 20. Aug 2005 16:38

Re: class(TPersistent) - Zugriff auf "höhere" Proz
 
Zitat:

Zitat von Merlin1988
Das Problem ist, wenn der Owner den Typ der Hauptklasse hat, muss diese vorher deklariert sein. Dann kann aber die Hauptklasse keine Variable vom Typ der Unterklasse haben, weil diese noch nicht bekannt ist.

Wenn du alles unter ein type schreibst, dann kannst du die Klasse "forward" deklarieren:
Delphi-Quellcode:
type
  TX = class; //<-- das ist die "forward" Deklaration

  TY = class(...)
  private
    FOwner: TX;
  public
    constructor Create(AOwner: TX);
    property Owner: TX read FOwner;
  end;

  TX = class(...)
  private
    FChild: TY;
  public
    property Child: TY read FChild;
  end;
//EDIT: bisschen nachgebessert...


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:30 Uhr.
Seite 1 von 2  1 2      

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