Delphi-PRAXiS
Seite 3 von 4     123 4      

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 Abgel. graf. Komponente aktualisiert nicht (https://www.delphipraxis.net/51571-abgel-graf-komponente-aktualisiert-nicht.html)

Robert_G 19. Aug 2005 12:42

Re: Abgel. graf. Komponente aktualisiert nicht
 
Zitat:

Zitat von Robert Marquardt
Ohne override wird die Ableitungsverbindung zu TGraphicControl unterbrochen.

Ich hoffte darauf, dass er selbst drauf kommt. Vor allem nachdem es auch jHeins erwähnt hatte. ;)

leddl 19. Aug 2005 12:42

Re: Abgel. graf. Komponente aktualisiert nicht
 
OK, beim Versuch, meinen vorherigen Code anzupassen, ist mir gerade eine Idee gekommen, woran es liegen könnte. Bisher lade ich das anzuzeigende Bild noch in Paint. Das wollte ich dann noch ändern, wenn der Rest funktioniert. In diesem Fall wird dann aber eben dadurch, daß das angezeigt Bild sich erst in Paint verändert natürlich auch keine Notwendigkeit erkannt, die Komponente neu zu zeichnen. Daran wirds wohl liegen. Ich teste das heute abend nochmal aus und melde mich morgen dazu nochmal.

Die Anpassungen, die du gerade noch angesprochen hast, wurden ja schon längst durch die vorherigen Posts geklärt. Das is also drin. Wird daher wohl wirklich das sein, was ich gerade geschrieben habe.

jfheins 19. Aug 2005 17:00

Re: Abgel. graf. Komponente aktualisiert nicht
 
Zitat:

Zitat von Robert Marquardt
Ohne override wird die Ableitungsverbindung zu TGraphicControl unterbrochen.

Ist das schlimm ?

TGraphicCotrol.Paint sieht etwa so aus:
Delphi-Quellcode:
procedure TGraphicCotrol.Paint;
begin
end;
Dürfte also nicht allzu viel ausmachen :mrgreen:

Robert Marquardt 19. Aug 2005 17:17

Re: Abgel. graf. Komponente aktualisiert nicht
 
Eben deshalb wird nichts angezeigt. Wenn man Invalidate aufruft, so ist das natuerlich das Invalidate von TGraphicControl.
Da Paint nicht ueberschrieben ist, wird natuerlich das Paint von TGraphicControl und nicht das neu deklarierte Paint aufgerufen.
Eine virtuelle Methode wird als Zeiger in der VMT (Virtual Method Table) abgelegt. Dort steht fuer diese Komponente erst mal das Paint von TGraphicControl.
Aufrufe von Paint gehen per Index in die VMT des Objekts.
Ueberschreibt man Paint in der abgeleiteten Konponente (override), so wird der Eintrag in der VMT durch das neue Paint ersetzt.
Damit ist eigentlich die ganze Vererbung erklaert.
dynamic macht keinen Eintrag in die VMT, stattdessen wird eine Suche nach dem Namen eingesetzt. Das Ergebnis ist das gleiche. Man tauscht nur Suchzeit gegen Speicherplatzersparnis.

Robert_G 19. Aug 2005 17:17

Re: Abgel. graf. Komponente aktualisiert nicht
 
Zitat:

Zitat von jfheins
Zitat:

Zitat von Robert Marquardt
Ohne override wird die Ableitungsverbindung zu TGraphicControl unterbrochen.

Ist das schlimm ?
...
Dürfte also nicht allzu viel ausmachen :mrgreen:

:wall:
Natürlich ist es das. Rate mal warum es das gibt? Genau, damit man generisch ein Neuzeichnen des GraphicControl-Nachfolgers auslösen kann, dieser es aber selbst implementieren kann.
Versteckt man Paint, bleibt es leer und nix passiert wenn man Paint auf die Instanz nach einem Cast auf GraphicControl ausführt.
Delphi-Quellcode:
TGraphicControl(x).Paint();
...ist dann plötzlich etwas anderes als...
Delphi-Quellcode:
X.Paint();

leddl 20. Aug 2005 16:20

Re: Abgel. graf. Komponente aktualisiert nicht
 
So, nix is. Selbst nachdem ich jetzt auch schon in der Setter-Methode das Bild gesetzt habe, wird durch Invalidate nichts nue gezeichnet. Paint funktioniert aber weiterhin wunderbar. :gruebel:
Hier mal der bisherige Code:
Delphi-Quellcode:
unit UCard;

interface

uses
  SysUtils, Classes, Controls, Graphics, Dialogs;

type
  TCardType = (CTcard, CTjoker, CTnext_player);
  TCardValue = (CVblue_01, CVblue_02, CVblue_03, CVblue_04, CVblue_05, CVblue_06,
                CVblue_07, CVblue_08, CVblue_09, CVblue_10, CVblue_11, CVblue_12,
                CVyellow_01, CVyellow_02, CVyellow_03, CVyellow_04, CVyellow_05, CVyellow_06,
                CVyellow_07, CVyellow_08, CVyellow_09, CVyellow_10, CVyellow_11, CVyellow_12,
                CVgreen_01, CVgreen_02, CVgreen_03, CVgreen_04, CVgreen_05, CVgreen_06,
                CVgreen_07, CVgreen_08, CVgreen_09, CVgreen_10, CVgreen_11, CVgreen_12,
                CVred_01, CVred_02, CVred_03, CVred_04, CVred_05, CVred_06,
                CVred_07, CVred_08, CVred_09, CVred_10, CVred_11, CVred_12);
  TJokerValue = (JVblue_01, JVblue_02, JVblue_03, JVblue_04, JVblue_05, JVblue_06,
                JVblue_07, JVblue_08, JVblue_09, JVblue_10, JVblue_11, JVblue_12,
                JVyellow_01, JVyellow_02, JVyellow_03, JVyellow_04, JVyellow_05, JVyellow_06,
                JVyellow_07, JVyellow_08, JVyellow_09, JVyellow_10, JVyellow_11, JVyellow_12,
                JVgreen_01, JVgreen_02, JVgreen_03, JVgreen_04, JVgreen_05, JVgreen_06,
                JVgreen_07, JVgreen_08, JVgreen_09, JVgreen_10, JVgreen_11, JVgreen_12,
                JVred_01, JVred_02, JVred_03, JVred_04, JVred_05, JVred_06,
                JVred_07, JVred_08, JVred_09, JVred_10, JVred_11, JVred_12,
                JVall);

type
  TCustomCard = class(TGraphicControl)
  private
    { Private declarations }
    fCardOpen : Boolean;
    fImageDirectory, fCardImagePath : String;
    fCardImage : TBitmap;

    const CardFileNames : Array[0..50] of String = ('blue_01.bmp','blue_02.bmp','blue_03.bmp','blue_04.bmp','blue_05.bmp','blue_06.bmp',
            'blue_07.bmp','blue_08.bmp','blue_09.bmp','blue_10.bmp','blue_11.bmp','blue_12.bmp',
            'yellow_01.bmp','yellow_02.bmp','yellow_03.bmp','yellow_04.bmp','yellow_05.bmp','yellow_06.bmp',
            'yellow_07.bmp','yellow_08.bmp','yellow_09.bmp','yellow_10.bmp','yellow_11.bmp','yellow_12.bmp',
            'green_01.bmp','green_02.bmp','green_03.bmp','green_04.bmp','green_05.bmp','green_06.bmp',
            'green_07.bmp','green_08.bmp','green_09.bmp','green_10.bmp','green_11.bmp','green_12.bmp',
            'red_01.bmp','red_02.bmp','red_03.bmp','red_04.bmp','red_05.bmp','red_06.bmp',
            'red_07.bmp','red_08.bmp','red_09.bmp','red_10.bmp','red_11.bmp.bmp','red_12.bmp',
            'joker.bmp','next_player.bmp','backside.bmp');

    procedure setCardOpen(aCardOpen : Boolean);

  protected
    { Protected declarations }
    procedure Paint; virtual; abstract;
    procedure SetCardImage; virtual; abstract;

  public
    { Public declarations }
    property CardOpen : Boolean read fCardOpen write setCardOpen;
    property ImageDirectory : String read fImageDirectory;

    constructor Create(aOwner : TComponent); override;
    destructor Destroy; override;

  published
    { Published declarations }
end;

type
  TCard = class(TCustomCard)
  private
  { Private declarations }
    fCardValue : TCardValue;

  protected
    { Protected declarations }
    procedure Paint; override;
    procedure SetCardImage; override;

  public
    { Public declarations }
    property CardValue : TCardValue read fCardValue;

    procedure Initialize(aImageDirectory : String; aCardValue : TCardValue; aCardOpen : Boolean = false);

  published
    { Published declarations }
end;

implementation

{
********************************************************************************
***********************************CUSTOMCARD***********************************
********************************************************************************
}

procedure TCustomCard.setCardOpen(aCardOpen : Boolean);
Begin
  if aCardOpen <> fCardOpen Then
  Begin
    fCardOpen := aCardOpen;
    SetCardImage;
    Invalidate;
  End;
End;

constructor TCustomCard.Create(aOwner : TComponent);
Begin
  inherited Create(aOwner);
  Width := 57;
  Height := 86;
  fCardImage := TBitmap.Create;
End;

destructor TCustomCard.Destroy;
Begin
  inherited Destroy;
 
  FreeAndNil(fCardImage);
End;



{
********************************************************************************
**************************************CARD**************************************
********************************************************************************
}

procedure TCard.Paint;
Begin
  Canvas.Draw(0,0,fCardImage);
End;

procedure TCard.SetCardImage;
Begin
  If fCardOpen Then
    fCardImagePath := fImageDirectory + CardFileNames[Integer(fCardValue)]
  Else
    fCardImagePath := fImageDirectory + CardFileNames[50];
   
  fCardImage.LoadFromFile(fCardImagePath);
End;

procedure TCard.Initialize(aImageDirectory : String; aCardValue : TCardValue; aCardOpen : Boolean = false);
Begin
  If aImageDirectory <> fImageDirectory Then
    fImageDirectory := IncludeTrailingBackslash(aImageDIrectory);
  If aCardValue <> fCardValue Then
    fCardValue := aCardValue;
  If aCardOpen <> fCardOpen Then
    fCardOpen := aCardOpen;

  SetCardImage;
  Invalidate;
End;

end.

Robert Marquardt 20. Aug 2005 16:34

Re: Abgel. graf. Komponente aktualisiert nicht
 
Schmeiss "procedure Paint; virtual; abstract;" raus.

Flocke 20. Aug 2005 16:35

Re: Abgel. graf. Komponente aktualisiert nicht
 
Zitat:

Zitat von leddl
Delphi-Quellcode:
...
type
  TCustomCard = class(TGraphicControl)
  ...
  protected
    { Protected declarations }
    procedure Paint; virtual; abstract; //<-- das muss weg
    procedure SetCardImage; virtual; abstract;

  ...
end;

Das "Paint; virtual; abstract;" muss weg, damit überschreibst du ja die Definition von TGraphicControl!

//EDIT: wo war die rote Box?!?

leddl 20. Aug 2005 16:44

Re: Abgel. graf. Komponente aktualisiert nicht
 
:gruebel: Wie jetzt? Wovon wird denn hier die ganze Zeit in dem Thread geredet? Mir wurde hier doch erst gesagt, ich solle das reinsetzen, damit ich jeden Nachfahren individuell zeichnen kann?

Flocke 20. Aug 2005 16:47

Re: Abgel. graf. Komponente aktualisiert nicht
 
Auszug aus Controls.pas:
Delphi-Quellcode:
  TGraphicControl = class(TControl)
  private
    FCanvas: TCanvas;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  protected
    procedure Paint; virtual; //<-- HIER !!!
    property Canvas: TCanvas read FCanvas;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;
Oben ist die Definition von TGraphicControl, und die hat schon eine virtuelle Methode Paint. Die musst du mit override überschreiben, aber nicht mit abstract neu definieren.

Nachtrag: und das override natürlich nur in der Klasse wo du es überschreibst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:11 Uhr.
Seite 3 von 4     123 4      

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