Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Komponenten Erstellung (https://www.delphipraxis.net/173173-komponenten-erstellung.html)

Kellerassel 11. Feb 2013 10:21

Komponenten Erstellung
 
Hallo,
ich komme gerade nicht weiter.
Ich schreibe eine Komponente. Die Komponente soll Prozesswerte als Kurve darstellen.


folgender Code wird zwar vom compiler akzeptiert, ich kann aber im Projekt nicht auf VisuKurve1.Kurve[xy] zugreifen.
wo ist mein Denkfehler?




wäre schön wenn mir jemand einen Tip geben kann



Delphi-Quellcode:

Type TKurve =record
  aktiv      :Boolean;
  Farbe:     TColor;
  Brush:     TBrush;
  Pen:       TPen;
  Zoom:      Integer;
  Text:      String;
  Text_Pos:  Integer;
  Werte:     Array [0..1000]of Integer;
  X:         TAxis;
  Y:         TAxis;
end;


type
  TVisuKurve = class(TCustomControl)
  private
    FCanvas                  :TCanvas;
    FBGColor                 :Tcolor;
    FKurven                  :Array [1..10] of TKurve;
    FZoom                    :Real;
    FRun                     :Boolean;
    Ftimer                   :TTimer;
    function GetKurve(Index: Integer): TKurve;
    procedure PutKurve(Index: Integer; Value:TKurve);

  protected
    procedure Paint; override;
    property Canvas: TCanvas read FCanvas;
    procedure TickEvent(Sender: TObject);
    procedure SaveKurveToFile(Filename:String);

  public
    property   Kurve[Index:integer]     :TKurve                        read GetKurve                write PutKurve;

.....


function TVisuKurve.GetKurve(Index: Integer): TKurve;
begin
Result:=FKurven[index];
end;


procedure TVisuKurve.PutKurve(Index: Integer; value: TKurve);
begin
 FKurven[index]:=value;
end;

Codehunter 11. Feb 2013 10:26

AW: Komponenten Erstellung
 
Versuch mal, TKurve nicht als Record sondern als TPersistent-Ableger zu deklarieren. Dann solltest du die ganzen Objektinstanzen per TList verwalten (OwnsObjects nimmt dir Arbeit beim Freigeben ab).

Die Prozedur PutKurve solltest du in WriteKurve umbenennen, das hat sich stilmäßig so bewährt. Technisch ist das aber irrelevant.

EDIT: Um noch zu ergänzen, warum das bei Dir nicht funktioniert: Du kannst auf Records als Objekteigenschaften nicht auf diese Weise zugreifen. In deinem Fall müßtest du das so machen:
Delphi-Quellcode:
procedure TVisuKurve.PutKurve(Index: Integer; value: TKurve);
begin
  with FKurven[index] do begin
    Aktiv:= Value.Aktiv;
    Farbe:= Value.Farbe;
    {....}
  end;
end;
Diese Zuweisungsprozedur entspricht im Wesentlichen auch einer Assign-Prozedur bei den TPersistent-Objekten.

Popov 11. Feb 2013 10:32

AW: Komponenten Erstellung
 
Hallo Kellerassel, da du hier schon seit 10 Jahren registriert bis, kennst du sicherlich die BBCodes, wie z. B.
Code:
[DELPHI][/DELPHI]
Den Code dazwischen packen und schon kann man alles leichter lesen. Man kann es auch nachträglich machen. Einfach Editieren.

Kellerassel 11. Feb 2013 11:15

AW: Komponenten Erstellung
 
Hallo Codehunter,

danke für die schnelle Antwort.
So geht es.




@ Popov ja sorry haste wohl recht, war einige Zeit nicht mehr hier :pale:


habs berichtigt



nochmal danke

Kellerassel 28. Feb 2013 10:50

AW: Komponenten Erstellung
 
So ich bin ein Stück weiter, aber jetzt hängt es an einer ähnlichen Stelle

ich bekomme von aussen (nachdem die komponente installiert ist und ich von einer form unit auf Visukurve zugreife keinen Zugriff auf die Attribute des records XAchse

Delphi-Quellcode:
unit Kurve;

interface

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

Type
TOrientierung = (Aleft,Aright,Acenter,Atop,Abottom);

Type TAxis=record
  Aktiv:boolean;
  Color:Tcolor;
  Position:TOrientierung;
  Text:String;
  Textpos:TPoint;
  Font:TFont;
end;

Type TKurve = class(TPersistent)
private
  Faktiv:     Boolean;
  FFarbe:     TColor;
  FZoom:      Integer;
  FText:      String;
  FText_Pos:  TPoint;
  FWerte:     Array of Integer;
  FSize:      Integer;
  FX:         TAxis;
  FY:         TAxis;
  function GetWert(Index:integer):Integer;
  procedure WriteWert(Index,Value:integer);
  function GetSize:Integer;
  procedure WriteSize(value:Integer);
  function GetXAchse:TAxis;
  procedure WriteXAchse(value:TAxis);
  function GetYAchse:TAxis;
  procedure WriteYAchse(value:TAxis);
public
  procedure   Assign(Source: TPersistent); override;
  property    Wert[Index:integer]   :Integer                       read GetWert               write WriteWert;
  property    XAchse                :TAxis                         read GetXAchse              write WriteXAchse;
  property    YAchse                :TAxis                         read GetXAchse              write WriteXAchse;
  constructor Create(Text:String;size:Integer);
  destructor  Destroy; override;
published
  property    Aktiv                   :Boolean                       read FAktiv                   write FAktiv;
  property    Zoom                   :Integer                       read FZoom                   write FZoom;
  property    Text                   :String                        read FText                   write FText;
  property    Size                  :Integer                       read GetSize               write WriteSize;
  property    Farbe                   :TColor                        read FFarbe                   write FFarbe;
end;
implementation


procedure TKurve.Assign(Source: TPersistent);
var
  I: Integer;
begin
  if Source is TKurve then
  begin
  self.Faktiv :=TKurve(Source).Faktiv;
  self.FFarbe :=TKurve(Source).FFarbe;
  self.FZoom :=TKurve(Source).FZoom;
  self.FText :=TKurve(Source).FText;
  self.FSize :=TKurve(Source).FSize;

  for I := 0 to TKurve(Source).FSize -1 do
  self.Wert[i]:=TKurve(Source).Wert[i];
  end
  else
  inherited; // Klasse nicht bekannt, also inherited aufrufen;

end;

constructor TKurve.Create(Text:String;size:Integer);
var i:integer;
mypoint:tpoint;
begin
  inherited Create;
  SetLength(FWerte,size);
  mypoint.X:=0;mypoint.Y:=0;
  Faktiv:=true;
  FFarbe:=clyellow;
  FZoom:=0;
  FText:=Text;
  FText_Pos:=mypoint;
  for I := 0 to high(FWerte) do FWerte[i]:=i;//Random(100);

  // Axen init
  FX.Font:=TFont.Create;
  FX.Color:=clwhite;
  FX.Aktiv:=true;
  FX.Position:=Acenter;
  FX.Textpos.X:=0;
  FX.Textpos.Y:=0;
  FX.Text:='X-Achse';


end;

destructor TKurve.Destroy;
begin
  inherited Destroy;
end;


{ TKurve }

function TKurve.GetXAchse:TAxis;
begin
  with TAxis (fx) do begin
   result.Aktiv:=fx.Aktiv;
   result.Color:=fx.Color;
   result.Position:=fx.Position;
   result.Text:=fx.Text;
   result.Textpos:=fx.Textpos;
   //result.Font.Assign(fx.Font);
  end;
end;



function TKurve.GetYAchse: TAxis;
begin
   result.Aktiv:=FY.Aktiv;
   result.Color:=fy.Color;
   result.Position:=fy.Position;
   result.Text:=fy.Text;
   result.Textpos:=fy.Textpos;
   //result.Font.Assign(fy.Font);
end;

function TKurve.GetSize: Integer;
begin
result:=high(FWerte);
end;

procedure TKurve.WriteXAchse(value: TAxis);
begin
  with TAxis(FX) do begin
    Aktiv:=Value.Aktiv;
    Color:=Value.Color;
    Position:=Value.Position;
    Text:=Value.Text;
    Textpos:=Value.Textpos;
    Font.Assign(Value.Font);
  end;
end;

procedure TKurve.WriteYAchse(value: TAxis);
begin
    FY.Aktiv:=Value.Aktiv;
    FY.Color:=Value.Color;
    FY.Position:=Value.Position;
    FY.Text:=Value.Text;
    FY.Textpos:=Value.Textpos;
    FY.Font.Assign(Value.Font);
end;

procedure TKurve.WriteSize(value: Integer);
begin
SetLength(FWerte,value+1);
end;

function TKurve.GetWert(Index: integer): Integer;
begin
result:=FWerte[index];
end;

procedure TKurve.WriteWert(Index, Value: integer);
begin
FWerte[Index]:=Value;
end;


end.

innerhalb der folgenden Komponenten Unit geht's noch


Delphi-Quellcode:
unit Visu_Kurvenunit1;


interface

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

type
  TVisuKurve = class(TCustomControl)
  private
    FCanvas                  :TCanvas;
    FKurven                  :Array [1..10] of TKurve;
    FZoom                    :Real;
    FRun                     :Boolean;
    FTimer                   :TTimer;
    FTime                    :Integer;
    FKurvenCount             :Integer ;
    function GetKurve  (Index: Integer): TKurve;
    procedure WriteKurve (Index: Integer; Value:TKurve);
    function GetKurvenCount:Integer;
  protected
    procedure Paint; override;
    procedure TickEvent(Sender: TObject);
    procedure SaveKurveToFile(Filename:String);
  public
    property   Kurve[Index:integer]     :TKurve                        read GetKurve                write WriteKurve;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property VisuRUN                      :Boolean                       read FRUN                       write FRUN;
    property RefreshIntervall             :Integer                       read FTime                     write FTime;
    property KurvenCount                  :Integer                       read GetKurvenCount;
  end;

procedure Register;

implementation


procedure Register;
begin
  RegisterComponents('MiningComponents', [TVisuKurve]);
end;

constructor TVisuKurve.Create(AOwner: TComponent);
var
  i: Integer;
begin
  inherited Create(AOwner);
  FCanvas := TControlCanvas.Create;
  TControlCanvas(FCanvas).Control := Self;

  // Setting default Values
  FCanvas.Brush.Color        :=clblack;
  Width                      :=220;
  Height                     :=100;

  // Create the Timer for painting
  FTimer := TTimer.Create(nil);
  FTimer.Interval := 100;        // Konstant
  FTimer.OnTimer := TickEvent;

  FKurven[1]:=TKurve.Create('Kurve 1',width);
  for i := 2 to 10 do
  begin
   FKurven[i]:=TKurve.Create('Kurve ' + inttostr(i),0);
   FKurven[i].Aktiv:=false;
  end;
end;


destructor TVisuKurve.Destroy;
begin
  Ftimer.Free;
  FCanvas.Free;
  inherited Destroy;
end;


procedure TVisuKurve.Paint;
var Render:TBitmap;
  i,count:Integer;

begin
  Render:=Tbitmap.Create;
  Render.Width:=Width;Render.Height:=Height;
  Render.Canvas.Brush.Color:=FCanvas.Brush.Color;
  Render.Canvas.Rectangle(0,0,width,height);

  // Über alle instanzierten Objekte
  for Count:=1 to 10 do
  begin
          if FKurven[count].aktiv then
            begin

              if FKurven[count].XAchse.Aktiv then
              begin
                    render.Canvas.Pen.Color:=FKurven[count].XAchse.Color;
                    case FKurven[count].XAchse.Position of
                    Atop  : begin
                              Render.Canvas.MoveTo(5,5);
                              render.Canvas.LineTo(width-5,5);
                             end;
                    Acenter: begin
                              Render.Canvas.MoveTo(5,height div 2);
                              render.Canvas.LineTo(width-5,height div 2);
                             end;
                    ABottom: begin
                              Render.Canvas.MoveTo(5,height -5);
                              render.Canvas.LineTo(width-5,height -5);
                             end;
                    end;
              end;

            // Werte auslesen, und als Kurve darstellen
             render.Canvas.Pen.Color:=FKurven[count].Farbe;

             if FKurven[count].XAchse.Position = Acenter then
              begin
                Render.Canvas.MoveTo(5,height div 2);
                  for i:= 0 to FKurven[count].Size -1 do
                    begin
                      Render.Canvas.LineTo(6+i,height div 2 - FKurven[count].Wert[i] );
                    end;
              end;

            if FKurven[count].XAchse.Position = ABottom then
              begin
                Render.Canvas.MoveTo(5,height -5);
                  for i:= 0 to FKurven[count].Size -1 do
                    begin
                      Render.Canvas.LineTo(6+i,height-5 - FKurven[count].Wert[i] );
                    end;
              end;

            if FKurven[count].XAchse.Position = ATop then
              begin
                Render.Canvas.MoveTo(5,5);
                  for i:= 0 to FKurven[count].Size -1 do
                    begin
                      Render.Canvas.LineTo(6+i,5 + FKurven[count].Wert[i] );
                    end;
              end;

            end;
  end;

  Canvas.Draw(0,0,Render);
  Render.Free;
end;



function TVisuKurve.GetKurve(Index: Integer): TKurve;
begin
Result:=(FKurven[index]);
//with TAxis (FX) do begin
//   result.XAchse.Aktiv:=FKurven[index].XAchse.Aktiv; Fehler linker Seite dar nichts zugewiesen werden.
//end;
end;

function TVisuKurve.GetKurvenCount: Integer;
var
  I,j: Integer;
begin
j:=0;
for I := 1 to 10 do
begin
     if FKurven[i].Aktiv then inc(j);
end;
result:=j;
end;

procedure TVisuKurve.WriteKurve(Index: Integer; Value: TKurve);
begin
FKurven[index].Assign(Value);
end;

procedure TVisuKurve.SaveKurveToFile(Filename: String);
begin
//
end;

procedure TVisuKurve.TickEvent(Sender: TObject);
begin
Paint;
end;

end.

was überseh ich ?

Ich weiß es ist etwas viel Quelltext, aber ich wollte nix vergessen :roll:


Thx

Codehunter 28. Feb 2013 11:06

AW: Komponenten Erstellung
 
Gleiches Problem - gleiche Antwort: TAxis ist als Record implementiert und bei einen Record-Property kann man nicht schreibend auf die einzelnen Elemente im Record zugreifen. Implementiere TAxis so:
Delphi-Quellcode:
Type TAxis=class(TObject)
private  
   FAktiv:boolean;
   FColor:Tcolor;
   FPosition:TOrientierung;
   FText:String;
   FTextpos:TPoint;
   FFont:TFont;
public
   property Aktiv: Boolean read FAktiv write FAktiv;
   property Color: TColor read FColor write FColor;
   property Position: TOrientierung read FOrientierung write FOrientierung;
   property Text: String read FText write FText;
   property TextPos: TPoint read FTextPoint write FTextPoint;
   property Font: TFont read FFont write FFont;
end;
Beim Instantiieren und Freigeben von TKurve auch jede Instanz von TAxis mit zu behandeln. Vorsicht beim TFont, das ist an sich schon eine Klasse und hat womöglich einen eigenen Eigentümer. Doppeltes Freigeben belohnt die Runtime mit heißen Ohren.

Wenn du die Elemente von TAxis im Objektinspektor bearbeiten willst, musst du TAxis von TPersistent ableiten und nicht TObjekt - das geht aus deinem Post nicht hervor.

Kellerassel 28. Feb 2013 12:43

AW: Komponenten Erstellung
 
Hi, danke erstmal.

So ich habe das übernommen, und habe damit 3units
Kurve,axis,und die komponentenunit Visukurve.

innerhalb der Unit visukurve kann ich auf ein objekt vom typ Kurve, welches ein objekt vom Typ axis enthält zugriff aud die attribute von axis bekommen.
Also solltre doch das lesen/schreiben korrekt funktionieren.

Wenn ich aber nun versuche von einer Form-unit zugriff zu bekommen ist bei

Kurve.axis schluss. die attribute der axis sind nicht sichtbar.

verstehe ich nicht.:?:


kann mir jemand helfen ?

Codehunter 28. Feb 2013 15:41

AW: Komponenten Erstellung
 
Sind sie wirklich nicht sichtbar oder zeigts die Eingabehilfe bloß nicht an? Was sagt der Compiler dazu?

Ansonsten müsstest du schauen ob bei TAxis irgendwas als protected statt public deklariert ist. Wenn du vom Objektinspektor redest, dann müsste der Abschnitt "published" statt "public" heißen.

DeddyH 28. Feb 2013 15:49

AW: Komponenten Erstellung
 
Ist die Unit, die die Attribute der Axis beschreibt, denn auch in der Formularunit eingebunden?

sx2008 28. Feb 2013 15:51

AW: Komponenten Erstellung
 
Zitat:

Zitat von Codehunter (Beitrag 1205378)
Wenn du die Elemente von TAxis im Objektinspektor bearbeiten willst, musst du TAxis von TPersistent ableiten und nicht TObjekt

+ die Methode
Delphi-Quellcode:
Assign
richtig überschreiben
+ in der
Delphi-Quellcode:
procedure Register
zusätzlich noch
Delphi-Quellcode:
RegisterClass(TAxis);
aufrufen


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:05 Uhr.
Seite 1 von 2  1 2      

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