Autor Beitrag
catweasel
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: 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 :wink:

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.
ausblenden volle Höhe Delphi-Quelltext
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;
    { Private declarations }
  protected
    { Protected declarations }
  public
  procedure setfarbe(farbe :TColor);
    { Public declarations }
  published
    { Published declarations }
  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.
ausblenden volle Höhe Delphi-Quelltext
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
    { Private declarations }
  public
    { Public declarations }
  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? :autsch:

Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt.

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 324



BeitragVerfasst: 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:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Do 06.11.03 21:33 
Titel: Nochmal nachgefragt...
Hi,

Danke erstmal für die erklärung.. :D
Habe jetzt brav den constructor und destructor implementiert. Nun bekomme ich zwar keine AccessViolation mehr... aber zu sehen ist trotzdem nix :cry:

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... :roll:

Hmm, du schreibst:
ausblenden 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 ... :autsch:

Catweasel

Moderiert von user profile iconTino: Code- durch Delphi-Tags erstezt.

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
Tino
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: 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 ... :autsch:

Du solltest den Komponenten (anzeige und sublabel) als Parent das tSuperchart Objekt übergeben:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Fr 07.11.03 19:20 
Titel: Es will nichtz funzen....
Hi,

Nochmal danke für eure Tipps....

aaaaaaber es funktioniert nich :cry: :bawling: 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:

ausblenden 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 : :oops:

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:

ausblenden volle Höhe Delphi-Quelltext
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;
    { Private declarations }
  protected
    { Protected declarations }
  public
  constructor Create(Owner: TComponent); override;
  destructor Destroy; override;
  procedure setfarbe(farbe :TColor);
    { Public declarations }
  published
    { Published declarations }
  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..:
ausblenden volle Höhe Delphi-Quelltext
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
    { Private declarations }
  public
    { Public declarations }
  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 :autsch:

Catweasel

Moderiert von user profile iconTino: 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



BeitragVerfasst: Fr 07.11.03 19:26 
haben das Panel und das Label vielleicht die Größe 0x0?
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: 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

ausblenden Quelltext
1:
2:
balken.height := 100;
balken.width := 100;


oder,

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: 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.
ausblenden 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.
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: So 09.11.03 13:49 
Hi,

Danke für den Tipp :lol:

Auch Danke für die Skizzierung der Vorgehensweise :D

..Jepp. Ich gebe zu ich habe mich mit Haltepunkten, Tracern (eigentlich dem ganzen Debugger) noch nicht so richtig auseinandergesetzt.. :oops:

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: 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.
ausblenden 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)