AGB  ·  Datenschutz  ·  Impressum  







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

Abgel. graf. Komponente aktualisiert nicht

Ein Thema von leddl · begonnen am 15. Aug 2005 · letzter Beitrag vom 21. Aug 2005
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    
Benutzerbild von leddl
leddl

Registriert seit: 13. Okt 2003
Ort: Künzelsau
1.613 Beiträge
 
Delphi 2006 Professional
 
#1

Abgel. graf. Komponente aktualisiert nicht

  Alt 15. Aug 2005, 11:09
Servus Leute,

nach längerer Zeit habe ich mich dann nun auch endlich mal wieder ans Programmieren rangewagt und stehe sofort vor einem - eher kleinen, aber dennoch nervigen - Problem.
Ich versuche gerade, ein Kartenspiel zu programmieren und habe mir für diesen Zweck eine Klasse TCustomCard von TGraphicControl abgeleitet, von der ich wiederrum die 3 verschiedenen Kartentypen (Karten mit Zahlen von 1-12 in 4 Farben, Joker, Aussetzen) ableite. Die Basisklasse besitzt so gut wie keine Eigenschaften und Funktionen, insofern hätte ich das ganze auch anders lösen können. Ich empfand es aber als gute Möglichkeit, mal den Umgang mit Vererbung etwas näher kennen zu lernen.
Die Basisklasse besitzt die Eigenschaft CardOpen : Boolean, die besagt, ob die Karte offen oder verdeckt liegt.
Meine zugehörige setter-Methode sieht aus wie folgt:
Delphi-Quellcode:
procedure TCustomCard.setCardOpen(aCardOpen : Boolean);
Begin
  if aCardOpen <> fCardOpen Then
  Begin
    fCardOpen := aCardOpen;
    Paint;
  End;
End;
Die Paint-Methode habe ich erst in den abgeleiteten Klassen implementiert, weil erst dort Daten vorhanden sind, über die ich die Oberfläche bestimme. Dennoch sollte doch - meinem Verständnis der Vererbung nach - bei einem Ändern der Eigenschaft in einer abgeleiteten Klasse auch die entsprechende Paint-Methode der abgeleiteten Klasse aufgerufen werden, und nicht die der Basisklasse, oder? Das scheint nämlich hier nicht der Fall zu sein. Die Oberfläche wird nämlich nicht neu gezeichnet. Erst durch eine Extra-Funktion in der abgeleiteten Klasse aktualisiert sich die Ansicht.

Und ne kleine zweite Frage hätte ich auch noch kurz. Ich weiß, "neue Frage, neuer Thread", aber die Frage is eigentlich so klein, daß sich ein Thread nicht lohnt.
Kann ich - der Einfachheit halber - diese abgeleiteten Klassen später dennoch als TCustomCard deklarieren, und dann per Typenüberprüfung darauf zugreifen? Das könnte mir später eventuell etwas Arbeit ersparen.
Axel Sefranek
A programmer started to cuss, cause getting to sleep was a fuss.
As he lay there in bed, looping round in his head
was: while(!asleep()) ++sheep;
  Mit Zitat antworten Zitat
Phistev
(Gast)

n/a Beiträge
 
#2

Re: Abgel. graf. Komponente aktualisiert nicht

  Alt 15. Aug 2005, 12:46
zu 2.: Ja, kannst du, das nennt sich Polymorphie

zu 1.: Wie ist TCustomCard.Paint deklariert? Empfehlenswert wäre procedure Paint; virtual; abstract;
  Mit Zitat antworten Zitat
Benutzerbild von leddl
leddl

Registriert seit: 13. Okt 2003
Ort: Künzelsau
1.613 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Abgel. graf. Komponente aktualisiert nicht

  Alt 15. Aug 2005, 13:00
Zitat von Phistev:
zu 2.: Ja, kannst du, das nennt sich Polymorphie
OK, dann muß ich da aber auch nichts ändern, das geht einfach so?
Zitat von Phistev:
zu 1.: Wie ist TCustomCard.Paint deklariert? Empfehlenswert wäre procedure Paint; virtual; abstract;
Bisher habe ich es nur mit override deklariert und nur die übergeordnete Paint-Methode aufgerufen. Aber das könnte ich eigentlich auch wieder entfernen, da Paint wie gesagt erst in den abgeleiteten Klassen eine Bedeutung bekommt. Aber das mit virtual und abstract werde ich mal austesten. Kann dazu dann leider erst morgen was sagen, da ich hier auf der Arbeit kein Delphi und daheim keinen Internetanschluß habe
Axel Sefranek
A programmer started to cuss, cause getting to sleep was a fuss.
As he lay there in bed, looping round in his head
was: while(!asleep()) ++sheep;
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#4

Re: Abgel. graf. Komponente aktualisiert nicht

  Alt 15. Aug 2005, 15:33
Delphi-Quellcode:
type TBase = class
  protected
    procedure Paint; virtual; abstract;
  public
    procedure DoSomething;
  end;
Delphi-Quellcode:
type
  Descendant1 = class(Base)
  protected
    procedure Paint; override;
  end;

  Descendant2 = class(Base)
  protected
    procedure Paint; override;
  end;
Wenn du in einer Mehtode in Base nun Paint aufrufst wird die Implementierung der Ableitung benutzt.

Zur Frage nach der Polymorphy:
Delphi-Quellcode:
var
  Instance1, Instance2 :Base;
begin
  Instance1 := Descendant1.Create();
  Instance2 := Descendant2.Create();
Instance1 & Instance2 lassen sich somit auf die Methoden von Base zusammenfassen und gleich behandeln, sie zeichnen sich aber unterschiedlich.
  Mit Zitat antworten Zitat
Benutzerbild von leddl
leddl

Registriert seit: 13. Okt 2003
Ort: Künzelsau
1.613 Beiträge
 
Delphi 2006 Professional
 
#5

Re: Abgel. graf. Komponente aktualisiert nicht

  Alt 15. Aug 2005, 15:42
OK, danke für die erklärende Zusammenfassung. Werd ich mir zu Gemüte führen und später dann mal testen. Und dann mal schaun, wie weit ich komme, wenn ich damit dann die einzelnen Karten fertig hab. Jetzt fängts nämlich erst so richtig an
Axel Sefranek
A programmer started to cuss, cause getting to sleep was a fuss.
As he lay there in bed, looping round in his head
was: while(!asleep()) ++sheep;
  Mit Zitat antworten Zitat
Benutzerbild von leddl
leddl

Registriert seit: 13. Okt 2003
Ort: Künzelsau
1.613 Beiträge
 
Delphi 2006 Professional
 
#6

Re: Abgel. graf. Komponente aktualisiert nicht

  Alt 16. Aug 2005, 08:51
Mist, jetzt sehe ich gerade, daß Robert noch override hinter die Paint-Methoden der abgeleiteten Klassen gepackt hat.
Ich meine aber, daß das bei mir nicht ging. Am Anfang müsste es nämlich so gewesen sein, weil ich vergessen hatte, es rauszunehmen, als ich virtual und abstract hinzugefügt hatte.
Das ging aber, soweit ich mich erinnere nicht, weil die Paint-Methode in der Basisklasse nicht implementiert war. Habe ich sie dann implementiert, krieg ich einen Abstract Error. Klar, kann ja nich ne abstrakte Methode doch noch implementieren.
So, dann hab ich das override und die Implementierung in der Basisklasse rausgenommen. Dann wurde auch brav compiliert. Beim Setzen von CardOpen (ihr erinnert euch, die setter-Methode aus meinem ersten Beitrag ) bekomme ich allerdings wieder einen Abstract Error. Warum?

OK, davon jetzt mal abgesehen. Seit dem Ändern habe ich noch ein ganz anderes Problem bekommen: Die Paint-Methoden der abgeleiteten Klassen funktioniert nicht mehr richtig, seit ich das "inherited Paint" entfernt habe, daß mir ja nur Fehler gebracht hat, seit ich Paint als abstract deklariert hatte. Jetzt wird nämlich nicht neugezeichnet, wenn ich Paint aufrufe, es sei denn, ich rufe in der Paint-Methode zB als erstes ein ShowMessage auf. Kann mir das mal jemand erklären?

//Edit:
Ich pack jetzt einfach mal den relevanten Teil meines bisherigen Quellcodes rein, dann is es vielleicht einfacher, mir das näher zu bringen
Delphi-Quellcode:
unit UCard;

interface

uses
  SysUtils, Classes, Controls, Graphics;

type
  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);
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;

  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;

  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;
    Paint;
  End;
End;

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

destructor TCustomCard.Destroy;
Begin
  FreeAndNil(fCardImage);

  inherited Destroy;
End;



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


procedure TCard.Paint;
Begin
  fCardImage.LoadFromFile(fCardImagePath);
  Canvas.Draw(0,0,fCardImage);
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;
    
  If fCardOpen Then
    fCardImagePath := fImageDirectory + CardFileNames[Integer(fCardValue)]
  Else
    fCardImagePath := fImageDirectory + CardFileNames[50];

  Paint;
End;
Axel Sefranek
A programmer started to cuss, cause getting to sleep was a fuss.
As he lay there in bed, looping round in his head
was: while(!asleep()) ++sheep;
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#7

Re: Abgel. graf. Komponente aktualisiert nicht

  Alt 16. Aug 2005, 09:11
Du hast jetzt 2-mal Paint. Einmal von der Basisklasse und einmal von der Ableitung.
Wenn du eine abstrakte Methode überschreibst darfst du natürlich NICHT inherited aufrufen.
Ist ja auch gar nix da, was im Vorgänger aufgerufen werden könnte -> *abstract error*.
Wie kamst du eigentlich auf die Idee mit dem inherited?
  Mit Zitat antworten Zitat
Benutzerbild von leddl
leddl

Registriert seit: 13. Okt 2003
Ort: Künzelsau
1.613 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Abgel. graf. Komponente aktualisiert nicht

  Alt 16. Aug 2005, 09:18
Weil ich vorher eben keine abstrakte Basismethode hatte Da war das inherited noch ein Überbleibsel. Allerdings hats ja - soweit ich mich erinnere - mit dem override auch nicht hingehauen, solange ich keine Paint-Methode in der Basisklasse implementiert hatte - da hat danna ber natürlich wieder das abstract zugehauen.
Problem is aber grade, daß ich eben hier kein Delphi habe, und daher nur aus dem Gedächtnis erzählen kann. Vielleicht lieg ich auch irgendwo mal falsch.

Könntest du mir gerade an meinem Code mal zeigen, wie ich das zum Laufen bekomme?
Axel Sefranek
A programmer started to cuss, cause getting to sleep was a fuss.
As he lay there in bed, looping round in his head
was: while(!asleep()) ++sheep;
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#9

Re: Abgel. graf. Komponente aktualisiert nicht

  Alt 16. Aug 2005, 10:35
Also, so funktioniert es:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
   end;

   TKlasse = class(TGraphicControl)
   public
      procedure DoSomething;
   end;

   TErbe1 = class(TKlasse)
   protected
      procedure Paint; override;
   end;

   TErbe2 = class(TKlasse)
   protected
      procedure Paint; override;
   end;


var
   Form1: TForm1;
   Klasse: TKlasse;

implementation

{$R *.dfm}

{ TKlasse }

procedure TKlasse.DoSomething;
begin
   Paint;
end;

{ TErbe1 }

procedure TErbe1.Paint;
begin
  inherited;

   with Canvas do
   begin
      Brush.Color := clRed;
      Rectangle(10, 10, 80, 80);
   end;

end;

{ TErbe2 }

procedure TErbe2.Paint;
begin
  inherited;

   with Canvas do
   begin
      Brush.Color := clGreen;
      Ellipse(10, 10, 80, 80);
   end;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Klasse := TErbe1.Create(Self);

   with Klasse do
   begin
      Parent := Self;
      Top := 50;
      Left := 50;
      Height := 100;
      Width := 100;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Klasse.DoSomething;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
   Klasse.Free;
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von leddl
leddl

Registriert seit: 13. Okt 2003
Ort: Künzelsau
1.613 Beiträge
 
Delphi 2006 Professional
 
#10

Re: Abgel. graf. Komponente aktualisiert nicht

  Alt 16. Aug 2005, 11:01
Also wenn das so funktioniert, dann möchte ich mal gerne wissen, was dann an meiner Setter-Methode so anders ist, daß es bei mir nicht funktioniert.
Naja, nichtsdestotrotz bin ich jetzt heiß darauf zu erfahren, wie ich es denn jetzt mit der abstrakten Methode zum Laufen bekomme. Sagt mal was...
Axel Sefranek
A programmer started to cuss, cause getting to sleep was a fuss.
As he lay there in bed, looping round in his head
was: while(!asleep()) ++sheep;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    


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:59 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