Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Record oder Class???


Tweafis - Mo 02.06.03 09:13
Titel: Record oder Class???
Ich möchte eine neue Class (oder Record) erstellen, und zwar TZeiger, welche ungefähr so aussieht:

Delphi-Quelltext
1:
2:
3:
4:
TZeiger=class/record
  Length: real;
  Pen: TPen;
end;

Ich müsste aber noch wissen wie ich das initialisiere, in Create der Uhr:

Delphi-Quelltext
1:
2:
3:
TZeiger := TZeiger.Create // afaik nur bei class
TZeiger.Length := 0.7 // Müsste gehen
TZeiger.Pen := TPen.Create // ??? gib afair fehler bei record


ErnestoChe - Mo 02.06.03 10:12

Hallo,

erstelle doch eine Klasse und kreatiere TPen im Konstruktor von TZeiger:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
TZeiger = class(TObject)
public
  Length: real; 
  Pen: TPen;
  constructor Create; 
  destructor Destroy; 
end

// ..............

constructor TZeiger.Create;
begin
  inherited Create;
  
  Pen :=TPen.Create;
end;

destructor TZeiger.Destroy;
begin
  Pen.Free;
  inherited Destroy;
end;


MFG

- Ernesto -


Tweafis - Mo 02.06.03 10:13

nagut, aber ich müsste noch wissen, von was ich die classe ableiten soll.
Hab grade sowas von Persistent abgeleitet gesehen (auch Zeiger).


ErnestoChe - Mo 02.06.03 10:24

Hi,

kommt darauf an was deine Klasse alles haben soll und wofür sie gedacht. Für eine Real-Zahl und TPen denk ich mal, dass TObject genügt.

MFG

- Ernesto -


Tweafis - Mo 02.06.03 11:10

Hmm ich hab es jetzt so gemacht:

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:
type
  TZeiger = class
  public
    Length: real;
    Pen: TPen;
    constructor Create;
    destructor Destroy;
  end;

...

constructor TZeiger.Create; 
begin
  inherited Create;

  Pen :=TPen.Create;
end;

destructor TZeiger.Destroy;
begin
  Pen.Free;
  inherited Destroy;
end;


und im Published Abschnitt meiner Komponente



Delphi-Quelltext
1:
2:
3:
    property StdZeiger: TZeiger read fStdZeiger write fStdZeiger;
    property MinZeiger: TZeiger read fMinZeiger write fMinZeiger;
    property SekZeiger: TZeiger read fSekZeiger write fSekZeiger;


sowie folgendes im protected abschnitt

Delphi-Quelltext
1:
2:
3:
    fStdZeiger: TZeiger;
    fMinZeiger: TZeiger;
    fSekZeiger: TZeiger;


Aber wenn ich z.B. StdZeiger im Objectinspektor verändern will, dann kommt wenn ich [+] klicke "Keine Expandierung möglich"

:( Fis


Tino - Mo 02.06.03 11:14

Tweafis hat folgendes geschrieben:
Aber wenn ich z.B. StdZeiger im Objectinspektor verändern will, dann kommt wenn ich [+] klicke "Keine Expandierung möglich"

Deine leite die Klasse mal von Persistent ab.

Gruß
Tino


ErnestoChe - Mo 02.06.03 11:19

Hi,

dann leite deine TZeiger von TPersistent ab und mache folgendes:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
type 
  TZeiger = class(TPersistent) 
  public 
    Length: real; 
    Pen: TPen; 
    constructor Create; 
    destructor Destroy; 
    procedure Assign(Source : TPersistent); override;
  end

//...................

procedure TZeiger.Assign(Source: TPersistent);
begin
  Length := TZeiger(Source).Length;
  Pen := TZeiger(Source).Pen;
end;


MFG

- Ernesto -


Tweafis - Mo 02.06.03 11:24

Jetzt kommt zwar keine Fehlermeldung mehr, aber aus dem + wird nur ein - und es klappt nicht auf, bzw werden keine optionen zum verändern angezeigt


Tweafis - Mo 02.06.03 11:30

Und wenn ich in Create Assign(Self) aufrufe bringt das auch nix, nur dass die Teile von Anfang an "aufgeklappt" sind (- statt +). (vielleicht war das auch nur weil ich es davor aufgeklappt habe...)


ErnestoChe - Mo 02.06.03 11:32

Hi,

dann mach noch folgendes, erstelle ein Objekt von der Klasse von der deine Komponente abgeleitet ist, und ändere den Konstruktor folgendermaßen um:


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:
type  
  TZeiger = class(TPersistent)  
  private
    FOwner: TCustomControl;     // <-------- zum Beispiel
  public  
    Length: real;  
    Pen: TPen;  
    constructor Create(AOwner: TComponent); 
    destructor Destroy;  
    procedure Assign(Source : TPersistent); override
  end;  

//.........................

constructor TZeiger.Create(AOwner: TComponent);
begin 
  inherited Create;

  if AOwner is TCustomControl then
    FOwner := TCustomControl(AOwner)
  else
    FOwner:=nil

  Pen :=TPen.Create; 
end;


MFG

- Ernesto -


Tweafis - Mo 02.06.03 11:37


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
type
  TZeiger = class(TPersistent)
  private
    FOwner: TCustomControl;
  public
    Length: real;
    Pen: TPen;
    constructor Create(AOwner: TComponent);
    destructor Destroy;
    procedure Assign(Source : TPersistent); override;
  end;


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:
//TZeiger Start

constructor TZeiger.Create;
begin
  inherited Create;

  if AOwner is TCustomControl then 
    FOwner := TCustomControl(AOwner)
  else
    FOwner:=nil;  

  Pen :=TPen.Create;
end;

destructor TZeiger.Destroy;
begin
  Pen.Free;
  inherited Destroy;
end;
               
procedure TZeiger.Assign(Source: TPersistent);
begin
  Length := TZeiger(Source).Length;
  Pen := TZeiger(Source).Pen;
end;

// TZeiger Ende


Delphi-Quelltext
1:
2:
3:
4:
  //in Create func  der Kompo
StdZeiger := TZeiger.Create(Self);
  MinZeiger := TZeiger.Create(Self);
  SekZeiger := TZeiger.Create(Self);



Delphi-Quelltext
1:
2:
3:
4:
//in Destroy func der Kompo
  StdZeiger.Free;
  MinZeiger.Free;
  SekZeiger.Free;


Bringt nix, ich kann die Eigenschaften von z.B. StdZeiger nicht über den Objektinspektor verändern[/delphi]


ErnestoChe - Mo 02.06.03 11:43

Hallo,

werden die Eigenschaften expandiert wenn du "+" drückst? Werden nur die Änderungen zur Entwurfszeit nicht angezeigt?


Tweafis - Mo 02.06.03 11:48

[+]StdZeiger

so sieht es aus... dann *click* ->

[-]StdZeiger

aber keine Ausklappung


ErnestoChe - Mo 02.06.03 11:52

Hallo,


Delphi-Quelltext
1:
2:
3:
property StdZeiger: TZeiger read fStdZeiger write fStdZeiger; 
    property MinZeiger: TZeiger read fMinZeiger write fMinZeiger; 
    property SekZeiger: TZeiger read fSekZeiger write fSekZeiger;


Das soltest Du umändern und per Write in Methoden schreiben. So etwa:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
type deineKompo = class(TCustomControl)
   //.......
protected
  procedure SetStdZeiger(newValue:  TZeiger);
published 
  property StdZeiger: TZeiger read fStdZeiger write SetStdZeiger; 
  property MinZeiger: TZeiger read fMinZeiger write SetMinZeiger; 
  property SekZeiger: TZeiger read fSekZeiger write SetSekZeiger;
end;


//....

procedure deineKompo.SetStdZeiger(newValue:  TZeiger);
begin
  fStdZeiger := newValue;
  RePaint;
end;


MFG

- Ernesto -


ErnestoChe - Mo 02.06.03 11:57

Hallo nochmal,

du musst sie veröffentlichen, genauso wie bei der Komponente selber:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
type 
  TZeiger = class(TPersistent) 
  private 
    FOwner: TCustomControl; 
  public 
    Length: real; 
    Pen: TPen; 
    constructor Create(AOwner: TComponent); 
    destructor Destroy; 
    procedure Assign(Source : TPersistent); override
  published
    property Length;
    property Pen;
  end;


MFG

- Ernesto -


Tweafis - Mo 02.06.03 11:57

hab genau das gemacht


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TwUhr.SetStdZeiger(newValue:  TZeiger);
begin
  fStdZeiger := newValue;
  RePaint;
end;

procedure TwUhr.SetMinZeiger(newValue:  TZeiger);
begin
  fMinZeiger := newValue;
  RePaint;
end;

procedure TwUhr.SetSekZeiger(newValue:  TZeiger);
begin
  fSekZeiger := newValue;
  RePaint;
end;
und halt protected und property

aber das bringt nix.

Ich glaube das liegt an

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
type
  TZeiger = class(TPersistent)
  private
    FOwner: TCustomControl;
  public
    Length: real;
    Pen: TPen;
    constructor Create(AOwner: TComponent);
    destructor Destroy;
    procedure Assign(Source : TPersistent); override;
  end;


dem und


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:
constructor TZeiger.Create;
begin
  inherited Create;

  if AOwner is TCustomControl then 
    FOwner := TCustomControl(AOwner)
  else
    FOwner:=nil;  

  Pen :=TPen.Create;
end;

destructor TZeiger.Destroy;
begin
  Pen.Free;
  inherited Destroy;
end;

procedure TZeiger.Assign(Source: TPersistent);
begin
  Length := TZeiger(Source).Length;
  Pen := TZeiger(Source).Pen;
end;


dem Teil


ErnestoChe - Mo 02.06.03 12:06

Hi,

lies dieses und das vorhergehende Postin durch. Und natürlich noch den private-bereich ändern.


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:
type  
  TZeiger = class(TPersistent)  
  private  
    FLength: Real;
    FPen: TPen;
    FOwner: TCustomControl;  
    procedure SetLength(newValue: Real);
    procedure SetPen(newValue: Tpen);
  public 
    constructor Create(AOwner: TComponent);  
    destructor Destroy;  
    procedure Assign(Source : TPersistent); override;  
  published 
    property Length: Real read FLength write SetLength;
    property Pen: TPen read FPen write SetPen;
  end;

// ......


procedure TZeiger.SetLength(newValue: Real);
begin
  FLength := newValue;
  FOwner.Repaint;
end;

procedure TZeiger.Setpen(newValue: TPen);
begin
  FPen := newValue;
  FOwner.Repaint;
end;

MFG

- Ernesto -


Tweafis - Mo 02.06.03 12:22

Das Gibt so Fehler wie Stack-Überlauf und das Programm startet nimma


Tweafis - Mo 02.06.03 12:24

ES GEHT!!!!!

Ich hab nur ausversehen in SetPen Pen stat FPen geändert -> muss ja stack überlaufgeben (ruft sich immer wieder selber auf))

Aber jetzt geht es!!!

Thx ErnestoChe, thxthxthx :D :D :D


ErnestoChe - Mo 02.06.03 12:27

Hi,

nimm mal für FLength Integer statt Real und teile mal neben bei mit von welcher Klasse du deine Komponente ableitest.

// Nachtrag: gerngeschehen, freut mich, dass es jetzt klappt :wink:

MFG

- Ernesto -


Tweafis - Mo 02.06.03 12:28

Die Klasse ist von TGraphicControl abgeleitet, aber jetzt geht es ja!

Length muss real sein, da es ein Anteil an der MaxLänge ist


Tweafis - Mo 02.06.03 13:17

Kann ich für das ganze TZeiger eigentlich ne eigene Unit anlegen?


ErnestoChe - Mo 02.06.03 13:40

Hi,

kannst du machen. Must du halt die unit noch in die uses einbinden. Und wenn du deine Komponente weiter gibst musst du halt beide units mitgeben. Wäre sinnvoll, wenn du TZeiger noch bei anderen Komponenten verwendest. Wenn nicht, würde ich es in der Unit deiner Komponente lassen.

MFG

- Ernesto -


Tweafis - Mo 02.06.03 13:41

Ich überlege nur, da ich den Code so übersicthlich wie möglich gestallten will. Gibt es sowas wie Includes??

{I TZeiger.inc}

oder so?

Später kann ich ja alles zusammenpfropfen <-- ^^

Edit 100 Post :party: (naja ist nicht so viel, aber nach so kurzer Zeit :mrgreen:)


ErnestoChe - Mo 02.06.03 13:53

Hi,

meinst include aus c/c++. Wie schon erwähnt die Uses-Klausel:


Delphi-Quelltext
1:
2:
uses
  dieTZeigerUnit;


Auserdem schadet es nicht der Übersichtlichkeit, wenn du es in der selben Unit lässt, dank Code-Explorer.

Desweiteren kannst du mit Kommentaren Quellcode übersichtlich gestalten. Z.B. so:


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:
// ********** Deklaration der Klasse TZeiger ******************
type   
  TZeiger = class(TPersistent)   
  private   
    FLength: Real; 
    FPen: TPen; 
    FOwner: TCustomControl;   
    procedure SetLength(newValue: Real); 
    procedure SetPen(newValue: Tpen); 
  public  
    constructor Create(AOwner: TComponent);   
    destructor Destroy;   
    procedure Assign(Source : TPersistent); override;   
  published  
    property Length: Real read FLength write SetLength; 
    property Pen: TPen read FPen write SetPen; 
  end
// *******************************************************

// ************** Definitionen der Klassenmethoden ************
procedure TZeiger.SetLength(newValue: Real); 
begin 
  FLength := newValue; 
  FOwner.Repaint; 
end

procedure TZeiger.Setpen(newValue: TPen); 
begin 
  FPen := newValue; 
  FOwner.Repaint; 
end;
// *******************************************************


MFG

- Ernesto -


Tweafis - Mo 02.06.03 14:00

Ich meine das Include aus TurboPascal Zeiten, welches es hier anscheinend auch gibt :D

Delphi Hilfe hat folgendes geschrieben:
Typ Parameter
Syntax {$I Dateiname}
{$INCLUDE Dateiname}
Gültigkeitsbereich Lokal
Anmerkungen

Die Parameter-Direktive $I weist den Compiler an, die angegebene Datei in die Compilierung aufzunehmen. Diese Datei wird direkt nach der Direktive {$I Dateiname} in den Text eingefügt. Die vorgegebene Namenserweiterung für die Datei ist PAS. Wenn die Datei ohne Verzeichnispfad angegeben wird, sucht Delphi die Datei in dem Verzeichnis, in dem auch das Modul liegt. Außerdem werden alle Verzeichnisse durchsucht, die im Eingabefeld Suchpfad der Registerkarte Verzeichnisse|Bedingungen im Dialogfeld Projektoptionen (oder mit der Option /I in der DCC32-Kommandozeile) festgelegt wurden.

Wenn der Dateiname ein Leerzeichen enthält, schließen Sie ihn in halbe Anführungszeichen ein: {$I 'Meine Datei'}.
Für die Verwendung von Include-Dateien gilt die Einschränkung, daß sie nicht im Inneren eines Anweisungsbereichs eingebunden werden können. Alle Anweisungen zwischen den Schlüsselwörtern begin und end eines Anweisungsbereichs müssen nämlich aus derselben Quelldatei stammen.