Autor |
Beitrag |
catweasel
      
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Do 06.11.03 15:03
Hi,
ich versuche gerade in OOP einzutauchen und es bewahrheitet sich mal wieder: Springe nie in unbekannte Gewässer
Ich versuche folgendes: Ich möchte eine Klasse erstellen die ein Panel mit Label ist. Dazu erzeuge ich meine Klasse. (Der Name Superchart ist erstmal nebensache, das soll mal ein eigener Charttyp werden, aber jetzt soll das erstmal prinzipiell funktionieren.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| unit Superchart;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TSuperchart = class(twincontrol) private anzeige : TPanel; sublabel : TLabel; protected public procedure setfarbe(farbe :TColor); published end;
implementation
procedure TSuperchart.setfarbe(farbe: TColor); begin anzeige.Color := farbe; end;
end. |
wie man sehen kann enthält die Klasse als Nachfahre von TObject lediglich ein Panel und ein Label, sowie die public Prozedur setfarbe. "Von aussen" kommt man ja nicht an die color eigenschaft des panels ran, da es ja als privat deklariert wurde. Nun habe ich eine Form, in der ich meine Klasse verwende.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, superchart;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var balken : TSuperchart; begin balken := TSuperchart.Create(self); balken.Parent := self; balken.setfarbe(clred); end;
procedure TForm1.FormCreate(Sender: TObject); begin
end;
end. |
Ich erzeuge also die instanz "balken" vom Typ TSuperchart. Aber der Aufruf von setfarbe(clred); führt zu einer ACCESS VIOLATION ..
Warum? Was hab ich falsch deklariert oder nicht bedacht ?
Der Code lässt sich immerhin ohne Probleme compilieren, also ist die Sytax ok. setfarbe ist doch public bei mir. warum trotzdem Access violation?
Moderiert von Tino: Code- durch Delphi-Tags ersetzt.
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
catweasel 
      
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Do 06.11.03 15:05
Titel: Kleiner Fehler....
Hi,
hab gerade gemerkt...
Ich leite Superchart nicht von TObject ab. (Das hatte ich zuerst vor, sondern von TWincontrol)...
Catweasel
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
barfuesser
      
Beiträge: 324
|
Verfasst: Do 06.11.03 16:27
Du mußt anzeige und sublevel auch irgendwann erzeugen. Ich nehme an, es soll automatisch mit Deinem SuperChart erzeugt werden. Also mußt Du einen Constructor und einen Destructor für Deine SuperChart erzeugen. Und darein schreibst Du:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| constructor Create(Owner: TComponent); override; destructor Destroy; override;
constructor TSuperchart.Create(Owner: TComponent); begin inherited; anzeige := TPanel.Create(Self); sublabel := TLabel.Create(Self); anzeige.Parent := Parent; sublabel.Parent := Parent; end;
destructor TSuperchart.Destroy; begin anzeige.Free; sublabel.Free; inherited; end; |
Außerdem mußt Du noch sicherstellen, daß, wenn Du den Parent Deines Controls setzt, auch der Parent den Elementen anzeige und sublabel zugeordnet wird.
barfuesser
|
|
catweasel 
      
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Do 06.11.03 21:33
Titel: Nochmal nachgefragt...
Hi,
Danke erstmal für die erklärung..
Habe jetzt brav den constructor und destructor implementiert. Nun bekomme ich zwar keine AccessViolation mehr... aber zu sehen ist trotzdem nix
Zitat: | Außerdem mußt Du noch sicherstellen, daß, wenn Du den Parent Deines Controls setzt, auch der Parent den Elementen anzeige und sublabel zugeordnet wird. |
Wie meinstest du das? Ich hatte ein bis zwei Beiträge vorher schonmal ne Frage zu Owner/Parent gestellt und blicke leider immer noch nicht so ganz durch.
So ein bischen kann ich es erahnen, aber könnte mir mal jemand an genau diesem Beispiel weiterhelfen...
Hmm, du schreibst:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| destructor TSuperchart.Destroy; begin anzeige.Free; sublabel.Free; inherited; end; |
Wenn ich das was ich im Thread meiner anderen Frage (zu Owner/Parent) mitbekommen habe im Hinterkopf behalte, müsste der Destructor entfallen, wenn Anzeige und Sublabel die Instanz "balken" vom Typ Superchart als Owner hätte, oder?
Ich dachte nämlich immer:
"Owner.free" freet auch immer alle geownten Objekte, ?
Wenn ich die Instanz von TSuperchart freigebe, werden dann anzeige und label nicht automatisch mit freigegeben?
Wie gesagt ein Tipp bei diesem Beispiel würde mir echt im Bezug auf das Verständniss des OOP Mechanismus weiterhelfen ...
Catweasel
Moderiert von Tino: Code- durch Delphi-Tags erstezt.
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
Tino
      

Beiträge: 9839
Erhaltene Danke: 45
Windows 8.1
Delphi XE4
|
Verfasst: Fr 07.11.03 09:30
Titel: Re: Nochmal nachgefragt...
Hallo!
catweasel hat folgendes geschrieben: | "Owner.free" freet auch immer alle geownten Objekte, ? |
Das ist richtig. Jedenfalls wenn der Owner von TComponent abgeleitet wurde. Das ist bei deiner Komponente auch der Fall. Allerdings sollte man jede Komponente die man selbst erzeugt auch selbst wieder freigeben. Wenn man sich daran hält vergisst man das auch nie bei Objekten die nicht "automatisch" freigegeben werden.
catweasel hat folgendes geschrieben: | Wenn ich die Instanz von TSuperchart freigebe, werden dann anzeige und label nicht automatisch mit freigegeben? |
Doch das werden sie. Allerdings würde ich diese trotzdem selbst freigeben.
catweasel hat folgendes geschrieben: | Wie gesagt ein Tipp bei diesem Beispiel würde mir echt im Bezug auf das Verständniss des OOP Mechanismus weiterhelfen ... |
Du solltest den Komponenten (anzeige und sublabel) als Parent das tSuperchart Objekt übergeben:
Delphi-Quelltext 1: 2: 3: 4:
| anzeige := TPanel.Create(Self); sublabel := TLabel.Create(Self); anzeige.Parent := Self; sublabel.Parent := Self; |
Wahrscheinlich müsste bei sublabel.Parent das Panel angegeben werden, oder?
Gruß
Tino
|
|
catweasel 
      
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Fr 07.11.03 19:20
Titel: Es will nichtz funzen....
Hi,
Nochmal danke für eure Tipps....
aaaaaaber es funktioniert nich  Ich kann mahcen was ich will, ich bekomme nix zu sehen....
Zitat: | Zitat: | Du solltest den Komponenten (anzeige und sublabel) als Parent das tSuperchart Objekt übergeben: |
Quelltext 1: 2: 3: 4: 5:
| Sourcecode: anzeige := TPanel.Create(Self); sublabel := TLabel.Create(Self); anzeige.Parent := Self; sublabel.Parent := Self; |
Zitat: | Wahrscheinlich müsste bei sublabel.Parent das Panel angegeben werden, oder? |
|
Ds versuche ich ja die ganze Zeit, aber woher soll meine Klasse TSuperchart wissen wie die Insanz dazu heisst... Die wird ja in Unit 1 erst gebildet.....
Nö, das Sublabel soll NICHT AUF dem Panel dargestellt werden, sondern ausserhalb davon.....
Das soll sowas wie das "LabeledEdit" aus der Zusätzlich-Sparte....
Aber das Problem ist ja schon das Panel.. Ich seh es nicht
da wird bei mir nix rot angemalt....
Mal ne Bitte :
Könnte jemand meinen Quelltext nicht mal in ein leeres Project pasten und mal guggen warum nix zu sehen ist.....
Bitte, bitte, bitte.....
Hier noch mal die beiden Units (aktuelle Version):
Hier die TSuperchart Unit:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:
| unit Superchart;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TSuperchart = class(twincontrol) private anzeige : TPanel; sublabel : TLabel; protected public constructor Create(Owner: TComponent); override; destructor Destroy; override; procedure setfarbe(farbe :TColor); published end;
implementation
constructor TSuperchart.Create(Owner: TComponent); begin inherited; anzeige := TPanel.Create(Self); sublabel := TLabel.Create(Self); anzeige.Parent := Parent; sublabel.Parent := Parent; end;
destructor TSuperchart.Destroy; begin anzeige.Free; sublabel.Free; inherited; end;
procedure TSuperchart.setfarbe(farbe: TColor); begin anzeige.Color := farbe; end;
end. |
... und hier die aufrufende Unit..:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, superchart;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var balken : TSuperchart; begin balken := TSuperchart.Create(self); balken.Parent := self; balken.setfarbe(clred); end;
end. |
Wäre echt Super  (Sorry wenn ich mit dieser "Kleinigkeit" so rumnerve, aber ich will das raffen
Catweasel
Moderiert von Tino: Code- durch Delphi-Tags ersetzt.
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
obbschtkuche
Gast
Erhaltene Danke: 1
|
Verfasst: Fr 07.11.03 19:26
haben das Panel und das Label vielleicht die Größe 0x0?
|
|
catweasel 
      
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Fr 07.11.03 20:19
Hi,
Zitat: | haben das Panel und das Label vielleicht die Größe 0x0? |
Nein, eigentlich nicht. In der Regel werden Panels mit ner Standartgrösse > 0 geboren.
Aber auch wenn ich mit
Quelltext 1: 2:
| balken.height := 100; balken.width := 100; |
oder,
Quelltext 1: 2:
| anzeige.height := 100; anzeige.width := 100; |
das ganze difinitv grösser als Null mache ist nix zu sehen....
Catweasel.[/code]
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
Keldorn
      
Beiträge: 2266
Erhaltene Danke: 4
Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
|
Verfasst: Sa 08.11.03 23:11
Zitat: |
anzeige := TPanel.Create(Self);
anzeige.Parent := Parent;
...
balken := TSuperchart.Create(self);
balken.Parent := self;
|
haltepunkt in Constructor: guggn was parent enthält: nämlich NIL.
den Parent deines Superchartsobjektes weißt du erst später zu.
Delphi-Quelltext 1:
| anzeige.Parent := self; |
passiert immer noch nix, nochmal haltepunkt rein und guggn was self macht (rechte maustaste -> Fehlersuche -> untersuchen und mal werte anschauen, die interessieren könnten, aha width und height deines erzeugten Tsuperchrtobjektes sind ja noch 0. egal welche größe dein Panel und so hat, es wird nix angezeigt, weil dein eigentliches Superchart die größe 0 hat. ein panel hat deswegen schon eine voreingestellte Größe, weil diese Größe im Constructor des Panels eingestellt wird.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| constructor TSuperchart.Create(Owner: TComponent); begin inherited Create(owner); width := 200; height :=200; anzeige := TPanel.Create(Self); anzeige.Parent := self; anzeige.Caption := 'paneltest'; end; |
der hinweis mit der Größe war schon richtig. und das mit dem ...Parent:=self, hat dir Tino schon gesagt
Zitat: |
procedure setfarbe(farbe :TColor);
|
sowas macht man mit properties
gugg dir auch mal im Source/Samples ordner die Source-Beispiele zum Spinedit etc. an. diese sind auch in nicht Professional versionen mit dabei. Dort werden auch komponentent mit darin enthaltenen Komponenten erstellt.
Mfg Frank
_________________ Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
|
|
catweasel 
      
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: So 09.11.03 13:49
Hi,
Danke für den Tipp
Auch Danke für die Skizzierung der Vorgehensweise
..Jepp. Ich gebe zu ich habe mich mit Haltepunkten, Tracern (eigentlich dem ganzen Debugger) noch nicht so richtig auseinandergesetzt..
Das mit den properties...
Ist das nur ein schöner Stlye, oder gibt es (abgesehen davon das man nun nicht mehr die Methoden selbst aufruft) noch einen sinnträchtigeren Grund?
Catweasel.
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
Keldorn
      
Beiträge: 2266
Erhaltene Danke: 4
Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
|
Verfasst: So 09.11.03 15:24
in deinem Fall setzt du mit der Farbe nur den eigenschaftswert einer andern Komponente. oft ist es aber so, daß du die Farbe auch auslesen willst. Das wäre bei dir gar nicht möglich. Anzeige ist bei dir private, du kannst von außen gar nicht auf diese Elemente zugreifen. (anm: das mit der Zugriffkontolle geht nur, wenn sich die Tsuperchart deklaration in einer extra unit drin ist). mit den properties kannst für das lese und schreibzugriffe eigene Proceduren angeben oder auch Eigenschaften deiner Klasse nur als Lese-eigenschaften zur Verfügung stellen.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| type private FFarbe: TColor; procedure SetFarbe(const Value: TColor); public property Farbe:TColor read FFarbe write SetFarbe; end; ... procedure TForm1.SetFarbe(const Value: TColor); begin FFarbe := Value; Anzeige.color:=FFarbe; end; |
Wenn du über eine Delphi-Version >= Professional verfügst, brauchst du bloß im Public Teil property Farbe:TColor; schreiben und rechte Maustaste und "Klasse vervollständigen", dann übernimmt Delphi für dich den größtennTeil der schreibarbeit, das private FFarb schreibt Delphi für dich und die write methode auch.
Mfg Frank
_________________ Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
|
|
|