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 CustomControl Vererbung und Paint (https://www.delphipraxis.net/193834-customcontrol-vererbung-und-paint.html)

stOrM 13. Sep 2017 18:40

CustomControl Vererbung und Paint
 
Moin,
bräuchte mal kurz eine Erklärung wie man folgendes macht:

Ich erstelle eine neue Komponente TBlubb von TCustomControl, welche Paint überschreibt, soweit noch alles gut. Wenn ich jetzt eine weitere Komponente TBlubbA erstelle diesmal von TBlubb abgeleitet wie überschreibt man jetzt das Paint von TBlubb?

Sieht dann so aus zur Zeit:

Delphi-Quellcode:
  TBlubb = class(TCustomControl)
protected
   procedure Paint; override;
.....


   TBlubbA = class(TBlubb)
protected
   procedure Paint ?????
Mit einem nochmaligen override gehts jedenfalls nicht, da wird nur Paint von TBlubb ausgeführt.
Sinn dahinter ist, sehr viele Eigenschaften der Hauptkomponente können so bleiben, es kommen bei den anderen Komponenten Eigenschaften hinzu je nachdem welche Komponente benötige ich dann im Paint andere Sachen die ich zeichnen muss. Deshalb wollte ich es mir einfach machen und nicht jedes Mal wieder alles deklarieren, was in der Basis schon da ist.

stahli 13. Sep 2017 18:59

AW: CustomControl Vererbung und Paint
 
Du willst also die vorletzte Hierarchieebene aufrufen?

Ich habe dazu etwas gefunden:
http://www.delphipraxis.net/53075-ve...inherited.html
http://www.delphipraxis.net/14523-me...rspringen.html

Vielleicht hilft Dir das weiter. Ganz genau habe ich das jetzt nicht nachvollzogen.

Evtl. ist es sauberer, eine gemeinsame Basisklasse zu schaffen und/oder ein Flag UseOriginalPaintMethode.
Wenn das gesetzt ist (was man in Constructor machen kann wird inherited Paint aufgerufen und sonst MyNewPaint (welches selbst auch überschrieben werden kann).

DeddyH 13. Sep 2017 19:34

AW: CustomControl Vererbung und Paint
 
Wieso sollte ein nochmaliges Überschreiben nicht funkionieren? Das wäre ja gegen alles, was ich von OOP so kenne. Gegenbeispiel:
Delphi-Quellcode:
type
  TClassA = class
  protected
    procedure Blubb; virtual;
  end;

  TClassB = class(TClassA)
  protected
    procedure Blubb; override;
  end;

  TClassC = class(TClassB)
  protected
    procedure Blubb; override;
  end;

  TClassD = class(TClassC)
  public
    procedure Blubb; override;
  end;

{ TClassA }

procedure TClassA.Blubb;
begin
  ShowMessage('Bubb aus Class A');
end;

{ TClassB }

procedure TClassB.Blubb;
begin
  inherited;
  ShowMessage('Blubb aus Class B');
end;

{ TClassC }

procedure TClassC.Blubb;
begin
  inherited;
  ShowMessage('Blubb aus Class C');
end;

{ TClassD }

procedure TClassD.Blubb;
begin
  inherited;
  ShowMessage('Blubb aus Class D');
end;

procedure TForm5.FormCreate(Sender: TObject);
var
  Dingens: TClassD;
begin
  Dingens := TClassD.Create;
  try
    Dingens.Blubb;
  finally
    Dingens.Free;
  end;
end;
Da kommen alle Messages schön von "oben" nach "unten" durchgeblubbert, hab ich auch nicht anders erwartet.

stOrM 13. Sep 2017 20:07

AW: CustomControl Vererbung und Paint
 
Zitat:

Zitat von DeddyH (Beitrag 1381072)
Wieso sollte ein nochmaliges Überschreiben nicht funkionieren? Das wäre ja gegen alles, was ich von OOP so kenne. Gegenbeispiel:
Delphi-Quellcode:
type
  TClassA = class
  protected
    procedure Blubb; virtual;
  end;

  TClassB = class(TClassA)
  protected
    procedure Blubb; override;
  end;

  TClassC = class(TClassB)
  protected
    procedure Blubb; override;
  end;

  TClassD = class(TClassC)
  public
    procedure Blubb; override;
  end;

{ TClassA }

procedure TClassA.Blubb;
begin
  ShowMessage('Bubb aus Class A');
end;

{ TClassB }

procedure TClassB.Blubb;
begin
  inherited;
  ShowMessage('Blubb aus Class B');
end;

{ TClassC }

procedure TClassC.Blubb;
begin
  inherited;
  ShowMessage('Blubb aus Class C');
end;

{ TClassD }

procedure TClassD.Blubb;
begin
  inherited;
  ShowMessage('Blubb aus Class D');
end;

procedure TForm5.FormCreate(Sender: TObject);
var
  Dingens: TClassD;
begin
  Dingens := TClassD.Create;
  try
    Dingens.Blubb;
  finally
    Dingens.Free;
  end;
end;
Da kommen alle Messages schön von "oben" nach "unten" durchgeblubbert, hab ich auch nicht anders erwartet.

Probier das mal mit der Paint Procedure so wie ich und versuche die mal 2x zu überschreiben, genau das ist ja das Problem z.Z.

DeddyH 13. Sep 2017 20:39

AW: CustomControl Vererbung und Paint
 
Entweder eine Methode ist virtuell und kann somit überschrieben werden, oder sie ist es nicht. Ob die nun Paint heißt oder PinkelNichtInDieEcke, welche Rolle sollte das spielen? Zeig doch mal Deinen Code, irgendwo machst Du sicherlich etwas falsch.

stOrM 13. Sep 2017 20:43

AW: CustomControl Vererbung und Paint
 
Zitat:

Zitat von DeddyH (Beitrag 1381076)
Entweder eine Methode ist virtuell und kann somit überschrieben werden, oder sie ist es nicht. Ob die nun Paint heißt oder PinkelNichtInDieEcke, welche Rolle sollte das spielen? Zeig doch mal Deinen Code, irgendwo machst Du sicherlich etwas falsch.

Den hab ich doch oben schon gepostet :-D

Vielleicht erkläre ich das mal anders, die Hauptkomponente wird von TCustomControl abgeleitet, Paint wird mittels override überschrieben, in der Paint Procedure male ich ein bisschen rum.
Jetzt erstelle ich eine neue Komponente aber diesmal nicht von TCustomControl sondern von meiner ersten Komponente abgeleitet. Diese sollte wieder eine Paint Procedure besitzen, aber die muss natürlich die Paint Procedure meiner ersten Kompoente überschreiben und genau das geht eben nicht, da diese ja CustomControl Paint überschreibt. Das auf Virtual zu setzen geht nicht bzw. geht nicht ist nicht richtig kann man machen hat nur das Ergebnis das z.B. der Hintergrund der Hauptkomponente der vorher Rot war nun weiß gemalt wird das wohl dem Default von CustomControl entspricht.

Soweit ich weiß ist ja TCustomControl.Paint virtual kann ja auch einmalig überschrieben werden was ich ja mit Komponente1 auch mache nur Komponente2 kann Paint von Komponente1 nicht überschreiben. Ich hoffe es ist so deutlicher.

Mail ein Beispiel so wie ich denke das es sein

Delphi-Quellcode:
 TBlubb = class(TCustomControl)
 protected
   procedure Paint; virtual;

----


procedure TBlubb.Paint;
begin

   // bisschen rumpinseln...

inherited;
end;

// Komponente2

type
  TBlubb2 = class(TBlubb)
protected
   procedure Paint; override; // hier sollte TBlubb.Paint überschrieben werden und nicht TCustomControl.Paint....

...

procedure TBlubb2.Paint;
begin
  // den Bereich zeichen der nicht in TBlubb enthalten ist

inherited;
end;
Sagen wir mal bei TBlubb wird der Hintergrund der Kompoente mit Rot gefüllt. Wenn ich Jetzt die Ableitung in Komponente2 von TBlubb mache und dort den Hintergrund auf grün setze, bleibt dieser Rot.
Da anscheinend eben Paint aus TBlubb nicht durch Paint aus TBlubb2 überschrieben wird.

Das einzige was ich machen kann Paint in TBlubb nicht zu implementieren und nur in TBlubb2 zu implementieren, was nicht wirklich die Lösung ist, da ich beides benötige.

nahpets 13. Sep 2017 21:14

AW: CustomControl Vererbung und Paint
 
Soll denn in TBlubb2.Paint das Gleiche gemacht werdenn, wie in TBlubb.Paint?

Jedenfalls machst Du (ausgehend von Deinem Beispiel) zuerst etwas und dann lässt Du per inherited auch noch das machen, was im Paint des Vorgängers geschieht.

Wenn Du also im Paint von TBlubb2 etwas rot machst und dann das Paint von TBlubb aufrufst, ist es klar, dass die Farbe vom Paint des TBlubb übrig bleibt, also das Grünmachen nach Deinem Rotmachen erfolgt.

Wenn das Paint von TBlubb aufgerufen werden muss, dann zuerst das inherited aufrufen und dann die eigene Ergänzung machen. Soll aber das Paint vom Vorgänger nicht aufgerufen werden, dann das inherited weglassen.

stahli 13. Sep 2017 21:15

AW: CustomControl Vererbung und Paint
 
Du machst wohl nur einen Denkfehler.
Du kannst Paint in jedem Derivat überschreiben:

Delphi-Quellcode:
procedure TBlubb2.Paint;
begin
  // wenn Du hier etwas zeichnest, wird das durch inherited Paint (falls Du es aufrufst) wieder übermalt
  inherited; // Zeichnet das von TBlubb - aber Du kannst inherited auch weg lassen und alles neu zeichnen
  // hier weiteres hinzumalen
end;

stOrM 13. Sep 2017 21:26

AW: CustomControl Vererbung und Paint
 
Zitat:

Zitat von stahli (Beitrag 1381080)
Du machst wohl nur einen Denkfehler.
Du kannst Paint in jedem Derivat überschreiben:

Delphi-Quellcode:
procedure TBlubb2.Paint;
begin
  // wenn Du hier etwas zeichnest, wird das durch inherited Paint (falls Du es aufrufst) wieder übermalt
  inherited; // Zeichnet das von TBlubb - aber Du kannst inherited auch weg lassen und alles neu zeichnen
  // hier weiteres hinzumalen
end;

Ok fast, klappt es. Das Inherited war falsch :oops: Irgendeinen Fehler hab ich wohl noch, jetzt wird zwar der Hintergrund geändert durch das Paint in Komponente 2 nur mal ich da noch eine rote Linie oben auf das OffscreenBitmap das zeigt er mir jetzt dafür nicht mehr an :mrgreen: Mal gucken wo da jetzt der Fehler ist. Erledigt....

nahpets 13. Sep 2017 21:40

AW: CustomControl Vererbung und Paint
 
Wenn Du mal den ganzen Quelltext posten würdest, könnte man Dir sogar gezielt helfen und müsste nicht permanent raten, wo denn da jetzt ein Problem liegen könnte, dass es per Definition garnicht geben kann.

inherited wird dann aufgerufen, wenn die Methode des Vorgängers aufgerufen werden soll und zwar genau an der Stelle, an der die Methode des Vorgängers aufgerufen werden soll.

Möglich wäre also sowas:
Delphi-Quellcode:
procedure TBlubb2.Paint;
begin
  inherited; // Mache nur das, was auch der Vorgänger macht.
end;

procedure TBlubb2.Paint;
begin
  // Mache was eigenes ...
  inherited; // und dann das, was auch der Vorgänger macht.
end;

procedure TBlubb2.Paint;
begin
  inherited; // Mache das, was auch der Vorgänger macht.
  // und dann was eigenes ...
end;

procedure TBlubb2.Paint;
begin
  // Mache was eigenes,
  inherited; // dann das, was auch der Vorgänger macht ...
  // und dann noch was eigenes ...
end;
Bei inherited kommt es also durchaus darauf an, wo man es aufruft und nicht nur, dass man es aufruft oder es eben nicht aufruft.


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