Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Noch mal zu neuen Komponenten - Neue Events - Methoden (https://www.delphipraxis.net/193689-noch-mal-zu-neuen-komponenten-neue-events-methoden.html)

josef-b 29. Aug 2017 15:00

Noch mal zu neuen Komponenten - Neue Events - Methoden
 
Ich kämpfe mich weiter voran..

Ich möchte in meiner neuen Komponente eine procedure "Starten einfügen" dazu sollen einige
bool-Variablen übernommen werden.

Ich habe es mir mal so gedacht (bzw. abgeschrieben ;-)),

Delphi-Quellcode:
unit Elevator;

interface

uses
  System.SysUtils, System.Classes, Vcl.Controls;


type
  TElevatorStart = procedure (var starten,motorschutz,stern_ein,
          dreieck_ein,motor_ein,schief_oben,schief_unten,drehzahl: boolean) of object;

  TElevator = class(TGraphicControl)
  private
    { Private-Deklarationen }

    //Eingänge nur lesen

    FAdr_Motorschutz: Integer;
.......
.......
 
   
    //Ausgänge lesen und schreiben
    FStart:Boolean;
........
........
    FDoStart :TElevatorStart;

  protected
    { Protected-Deklarationen }

    procedure Paint; override;


  public
    { Public-Deklarationen }

    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;


  published
    { Published-Deklarationen }
    //hiermit wird das im Obkektinspektor angezeigt

 
    property Meldung_Motorschutz: boolean read FMeldung_Motorschutz write FMeldung_Motorschutz;
    property Meldung_Motor_Ein : boolean read FMeldung_Motor_Ein write FMeldung_Motor_Ein;
    property Meldung_Stern_Ein : boolean read FMeldung_Stern_Ein write FMeldung_Stern_Ein;
    property Meldung_Dreieck_Ein : boolean read FMeldung_Dreieck_Ein write FMeldung_Dreieck_Ein;
    property Meldung_Schief_o : boolean read FMeldung_Schief_o write FMeldung_Schief_o;
    property Meldung_Schief_u : boolean read FMeldung_Schief_u write FMeldung_Schief_u;
    property Meldung_Drehzahl : boolean read FMeldung_Drehzahl write FMeldung_Drehzahl;

    //Methoden
    property dostart : TElevatorStart read FDOStart write FDOStart;

  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('SPS', [TElevator]);
end;

constructor TElevator.Create(AOwner: TComponent);
begin
  inherited;
  FStart := true;

end;

destructor TElevator.Destroy;
begin
  // Hier deine Freigaben
  inherited;
end;

procedure TElevator.Paint;
begin
  inherited;
end;

procedure TElevator.dostart(var starten,motorschutz,stern_ein,
          dreieck_ein,motor_ein,schief_oben,schief_unten,drehzahl: boolean);
begin
  FStart := starten;
  FMeldung_Motorschutz := motorschutz;
  FMeldung_Motor_Ein := motor_ein;
  FMeldung_Stern_Ein := stern_ein;
  FMeldung_Dreieck_Ein := dreieck_ein;
  FMeldung_Schief_o:= schief_oben;
  FMeldung_Schief_u:= schief_unten;
  FMeldung_Drehzahl:= drehzahl;
end;
ganz unten bei Starten kommt : "Starten unterscheidet sich von vorheriger Deklaration" und
er meldet meine ganzen Variablen F.... als undeklariert

SebastianZ 29. Aug 2017 15:17

AW: Noch mal zu neuen Komponenten - Neue Events - Methoden
 
Zitat:

Zitat von josef-b (Beitrag 1379855)
Ich kämpfe mich weiter voran..

Ich möchte in meiner neuen Komponente eine procedure "Starten einfügen" dazu sollen einige
bool-Variablen übernommen werden.

Ich habe es mir mal so gedacht (bzw. abgeschrieben ;-)),

Delphi-Quellcode:
unit Elevator;

interface

uses
  System.SysUtils, System.Classes, Vcl.Controls;


type
  TElevatorStart = procedure (var starten,motorschutz,stern_ein,
          dreieck_ein,motor_ein,schief_oben,schief_unten,drehzahl: boolean) of object;

  TElevator = class(TGraphicControl)
  private
    { Private-Deklarationen }

    //Eingänge nur lesen

    FAdr_Motorschutz: Integer;
.......
.......
 
   
    //Ausgänge lesen und schreiben
    FStart:Boolean;
........
........
    FDoStart :TElevatorStart;

  protected
    { Protected-Deklarationen }

    procedure Paint; override;


  public
    { Public-Deklarationen }

    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;


  published
    { Published-Deklarationen }
    //hiermit wird das im Obkektinspektor angezeigt

 
    property Meldung_Motorschutz: boolean read FMeldung_Motorschutz write FMeldung_Motorschutz;
    property Meldung_Motor_Ein : boolean read FMeldung_Motor_Ein write FMeldung_Motor_Ein;
    property Meldung_Stern_Ein : boolean read FMeldung_Stern_Ein write FMeldung_Stern_Ein;
    property Meldung_Dreieck_Ein : boolean read FMeldung_Dreieck_Ein write FMeldung_Dreieck_Ein;
    property Meldung_Schief_o : boolean read FMeldung_Schief_o write FMeldung_Schief_o;
    property Meldung_Schief_u : boolean read FMeldung_Schief_u write FMeldung_Schief_u;
    property Meldung_Drehzahl : boolean read FMeldung_Drehzahl write FMeldung_Drehzahl;

    //Methoden
    property dostart : TElevatorStart read FDOStart write FDOStart;

  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('SPS', [TElevator]);
end;

constructor TElevator.Create(AOwner: TComponent);
begin
  inherited;
  FStart := true;

end;

destructor TElevator.Destroy;
begin
  // Hier deine Freigaben
  inherited;
end;

procedure TElevator.Paint;
begin
  inherited;
end;

procedure TElevator.dostart(var starten,motorschutz,stern_ein,
          dreieck_ein,motor_ein,schief_oben,schief_unten,drehzahl: boolean);
begin
  FStart := starten;
  FMeldung_Motorschutz := motorschutz;
  FMeldung_Motor_Ein := motor_ein;
  FMeldung_Stern_Ein := stern_ein;
  FMeldung_Dreieck_Ein := dreieck_ein;
  FMeldung_Schief_o:= schief_oben;
  FMeldung_Schief_u:= schief_unten;
  FMeldung_Drehzahl:= drehzahl;
end;
ganz unten bei Starten kommt : "Starten unterscheidet sich von vorheriger Deklaration" und
er meldet meine ganzen Variablen F.... als undeklariert


Ok, hier ist ein bisschen was durcheinander gekommen mit der Deklaration :wink: . Wenn es nicht notwendig ist, das die "dostart"-procedure von außen überschrieben wird, ist es nicht nötig hier mit procedure of object und property zu arbeiten.

Zu beginn reicht sicher diese Variante:

Delphi-Quellcode:
unit Elevator;

interface

uses
  System.SysUtils, System.Classes, Vcl.Controls;


type
  TElevator = class(TGraphicControl)
  private
    { Private-Deklarationen }

    //Eingänge nur lesen

    FAdr_Motorschutz: Integer;
.......
.......
 
   
    //Ausgänge lesen und schreiben
    FStart:Boolean;
........
........
    FDoStart :TElevatorStart;

  protected
    { Protected-Deklarationen }

    procedure Paint; override;


  public
    { Public-Deklarationen }

    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
   
    procedure DoStart(var starten, motorschutz, stern_ein, dreieck_ein, motor_ein, schief_oben, schief_unten, drehzahl: Boolean);

  published
    { Published-Deklarationen }
    //hiermit wird das im Obkektinspektor angezeigt

 
    property Meldung_Motorschutz: boolean read FMeldung_Motorschutz write FMeldung_Motorschutz;
    property Meldung_Motor_Ein : boolean read FMeldung_Motor_Ein write FMeldung_Motor_Ein;
    property Meldung_Stern_Ein : boolean read FMeldung_Stern_Ein write FMeldung_Stern_Ein;
    property Meldung_Dreieck_Ein : boolean read FMeldung_Dreieck_Ein write FMeldung_Dreieck_Ein;
    property Meldung_Schief_o : boolean read FMeldung_Schief_o write FMeldung_Schief_o;
    property Meldung_Schief_u : boolean read FMeldung_Schief_u write FMeldung_Schief_u;
    property Meldung_Drehzahl : boolean read FMeldung_Drehzahl write FMeldung_Drehzahl;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('SPS', [TElevator]);
end;

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

  FStart := true;

end;

destructor TElevator.Destroy;
begin
  // Hier deine Freigaben
  inherited;
end;

procedure TElevator.Paint;
begin
  inherited;
end;

procedure TElevator.DoStart(var starten,motorschutz,stern_ein,
          dreieck_ein,motor_ein,schief_oben,schief_unten,drehzahl: boolean);
begin
  FStart := starten;
  FMeldung_Motorschutz := motorschutz;
  FMeldung_Motor_Ein := motor_ein;
  FMeldung_Stern_Ein := stern_ein;
  FMeldung_Dreieck_Ein := dreieck_ein;
  FMeldung_Schief_o:= schief_oben;
  FMeldung_Schief_u:= schief_unten;
  FMeldung_Drehzahl:= drehzahl;
end;

//änderungen sind ungetestet
Weiters solltest du sicher stellen, dass deine Member-Variablen initialisiert werden. Aktuell ist nicht gesichert was nach dem Create zB in "FMeldung_Motor_Ein" steht.

DeddyH 29. Aug 2017 15:37

AW: Noch mal zu neuen Komponenten - Neue Events - Methoden
 
Zitat:

Zitat von SebastianZ (Beitrag 1379861)
Weiters solltest du sicher stellen, dass deine Member-Variablen initialisiert werden. Aktuell ist nicht gesichert was nach dem Create zB in "FMeldung_Motor_Ein" steht.

Doch, ist es. Private Felder und globale Variablen werden mit ihrer 0-Entsprechung (0, nil, Leerstring, false) initialisiert. Was mich mehr verwundert: wieso sind das denn Var-Parameter, es wird ja nichts zurückgeschrieben? Abgesehen davon gilt eine derartige Methode (speziell mit so vielen Argumenten) allgemein als unelegant.

josef-b 29. Aug 2017 21:17

AW: Noch mal zu neuen Komponenten - Neue Events - Methoden
 
Danke, Sebastian das klappt so...

ich finde es nicht ganz einfach, mich in die Materie der Komponenten-Welt einzuarbeiten..

Gibt es dafür irgendwo evtl noch ein gutes Tutorial? ich habe mir eines von Delphi-Treff
runtergeladen, aber so ausführlich ist das auch nicht, zumindest verstehe ich da
nicht so die Hintergründe.

Aber es geht trotzdem voran.

Es handelt sich um eine Maschinensteuerung, und die hat nunmal so viele Sensoren, das wollte ich
eben mit den properties abdecken.

DeddyH 30. Aug 2017 06:38

AW: Noch mal zu neuen Komponenten - Neue Events - Methoden
 
Wie im anderen Thread bereits gesagt: mach doch eine Menge daraus, dann kannst Du auf einen Schlag gezielt Sensoren ein- und ausschalten. Sind es mehr als 256, kann man sie ja noch irgendwie thematisch bzw. aufgabenspezifisch in mehrere Mengen unterteilen.

SebastianZ 30. Aug 2017 09:44

AW: Noch mal zu neuen Komponenten - Neue Events - Methoden
 
Zitat:

Zitat von DeddyH (Beitrag 1379865)
Doch, ist es. Private Felder und globale Variablen werden mit ihrer 0-Entsprechung (0, nil, Leerstring, false) initialisiert.


Wieder was gelernt :-D

himitsu 30. Aug 2017 09:52

AW: Noch mal zu neuen Komponenten - Neue Events - Methoden
 
Zitat:

Private Felder
Alle Felder (die Variablen in der Klasse)
Felder und Global, da wird der Speicher einfach komplett leer erstellt (mit Nullen gefüllt).

Lokale Variablen werden nicht initialisiert. (Außnahme sind gemanagte Typen wie String, dyn. Arrays und Interfaces)

Und Result wird nicht dort initialisiert, wo fast alle es denken ... auch wenn der Compiler hier nicht meckert, ist dieses IMMER als "nicht initialisiert" anzusehn.

josef-b 30. Aug 2017 15:47

AW: Noch mal zu neuen Komponenten - Neue Events - Methoden
 
Habe jetzt mal ein paar Mengentypen gemacht

Delphi-Quellcode:

unit Elevator;

interface

uses
  System.SysUtils, System.Classes, Vcl.Controls, graphics, dialogs;

type

  //Anfang Mengentyp SPS_Modbus_Adressen
  TSPS_Modbus_Adressen = Class(TPersistent)
    private
    FAdr_Meldung_Motorschutz: Integer;
    FAdr_Meldung_Motor_Ein: Integer;
    FAdr_Meldung_Stern_Ein: Integer;
    FAdr_Meldung_Dreieck_Ein: Integer;
    FAdr_Meldung_Schieflauf_Oben: Integer;
    FAdr_Meldung_Schieflauf_Unten: Integer;
    FAdr_Meldung_Drehzahlwaechter: Integer;

    published
    property Adresse_Motorschutz: Integer read FAdr_Meldung_Motorschutz write FAdr_Meldung_Motorschutz;
    property Adresse_Motor_Ein: Integer read FAdr_Meldung_Motor_Ein write FAdr_Meldung_Motor_Ein;
    property Adresse_Stern_Ein: Integer read FAdr_Meldung_Stern_Ein write FAdr_Meldung_Stern_Ein;
    property Adresse_Dreieck_Ein: Integer read FAdr_Meldung_Dreieck_Ein write FAdr_Meldung_Dreieck_Ein;
    property Adresse_Schieflauf_Oben: Integer read FAdr_Meldung_Schieflauf_Oben write FAdr_Meldung_Schieflauf_Oben;
    property Adresse_Schieflauf_Unten: Integer read FAdr_Meldung_Schieflauf_Unten write FAdr_Meldung_Schieflauf_Unten;
    property Adresse_Drehzahlwächter: Integer read FAdr_Meldung_Drehzahlwaechter write FAdr_Meldung_Drehzahlwaechter;
  End;

  //Ende Mengentyp SPS_Modbus_Adressen

  //Anfang Mengentyp SPS_Zustände
  TSPS_Zustaende = Class(TPersistent)
    private
    FMeldung_Motorschutz: boolean;
    FMeldung_Motor_Ein: boolean;
    FMeldung_Stern_Ein:boolean;
    FMeldung_Dreieck_Ein:boolean;
    FMeldung_Schief_o:boolean;
    FMeldung_Schief_u:boolean;
    FMeldung_Drehzahl:boolean;

    published
    property Meldung_Motorschutz: boolean read FMeldung_Motorschutz write FMeldung_Motorschutz;
    property Meldung_Motor_Ein : boolean read FMeldung_Motor_Ein write FMeldung_Motor_Ein;
    property Meldung_Stern_Ein : boolean read FMeldung_Stern_Ein write FMeldung_Stern_Ein;
    property Meldung_Dreieck_Ein : boolean read FMeldung_Dreieck_Ein write FMeldung_Dreieck_Ein;
    property Meldung_Schieflauf_oben : boolean read FMeldung_Schief_o write FMeldung_Schief_o;
    property Meldung_Schieflauf_unten : boolean read FMeldung_Schief_u write FMeldung_Schief_u;
    property Meldung_Drehzahl : boolean read FMeldung_Drehzahl write FMeldung_Drehzahl;
  End;

  TSPS_Options = class(TPersistent)
    private
    FFreigabe:boolean;
    FZeit_Stern : integer;
    FZeit_Nachlauf: integer;
    FStern_Dreieck_Schaltung: boolean;
    FAktiv :boolean;
    published
    property Freigabe : boolean read FFreigabe write FFreigabe;
    property Zeit_Stern :Integer read FZeit_Stern write FZeit_Stern default 10;
    property Zeit_Nachlauf: integer read FZeit_Nachlauf write FZeit_Nachlauf default 30;
    property Stern_Dreieck_Schaltung: boolean read FStern_Dreieck_Schaltung write FStern_Dreieck_Schaltung;
    property Aktiv: boolean read FAktiv write FAktiv;
  end;

  TElevator = class(TGraphicControl)
  private
    { Private-Deklarationen }
     //Eingänge nur lesen

    FModbus_Adressen: TSPS_Modbus_Adressen;
    FSPS_Zustaende : TSPS_Zustaende;
    FSPS_Options : TSPS_Options;

  protected
    { Protected-Deklarationen }

  procedure Paint; override;

    public
    { Public-Deklarationen }

    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;



  published
    { Published-Deklarationen }
    //hiermit wird das im Obkektinspektor angezeigt
    property onclick;
    property SPS_Modbus_Adressen : TSPS_Modbus_Adressen read FModbus_Adressen write FModbus_Adressen;
    property SPS_Zustände : TSPS_Zustaende read FSPS_Zustaende write FSPS_Zustaende;
    property SPS_Optionen : TSPS_Options read FSPS_Options write FSPS_Options;

    procedure starten(var starten,motorschutz,stern_ein,
          dreieck_ein,motor_ein,schief_oben,schief_unten,drehzahl: boolean);


  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('SPS', [TElevator]);
end;

constructor TElevator.Create(AOwner: TComponent);
begin
  inherited;
  FModbus_Adressen := TSPS_Modbus_Adressen.Create;
  FSPS_Zustaende := TSPS_Zustaende.Create;
  FSPS_Options := TSPS_Options.Create;
end;

destructor TElevator.Destroy;
begin
  inherited;
end;

procedure TElevator.Paint;
begin
  inherited; // <--- Wichtig!!!

  width := 70;
  height := 400;

  with canvas do
    begin
    //Silo-Körper
    pen.Color := clblack;
    Brush.Color := clgray;
    Brush.Style := bsSolid;
    rectangle(0,0,30,300);
    end;
  //noch nicht fertig
end;

procedure TElevator.starten(var starten,motorschutz,stern_ein,
          dreieck_ein,motor_ein,schief_oben,schief_unten,drehzahl: boolean);
begin

  //das wird noch vereinfacht

FSPS_Zustaende.FMeldung_Motorschutz := motorschutz;
FSPS_Zustaende.FMeldung_Motor_Ein := motor_ein;
FSPS_Zustaende.FMeldung_Stern_Ein := stern_ein;
FSPS_Zustaende.FMeldung_Dreieck_Ein := dreieck_ein;
FSPS_Zustaende.FMeldung_Schief_o:= schief_oben;
FSPS_Zustaende.FMeldung_Schief_u:= schief_unten;
FSPS_Zustaende.FMeldung_Drehzahl:= drehzahl;

if (FSPS_Zustaende.FMeldung_Motorschutz = false) and
     (FSPS_Zustaende.FMeldung_Schief_O = false) and
     (FSPS_Zustaende.FMeldung_Schief_u = false) and
     (FSPS_Zustaende.Fmeldung_Drehzahl = false)
then
  begin
  //do something going on
  end;
end;

end.

himitsu 30. Aug 2017 16:23

AW: Noch mal zu neuen Komponenten - Neue Events - Methoden
 
Mengentypen (ENUMs) ... das, was du da hast sind Daten-Klassen.
Nur, damit du den richtigen Namen verwendest. :zwinker:



NIEMAL mit TRUE oder FALSE vergleichen!

Delphi-Quellcode:
var
  B: Boolean;

B := False;
if (B = False) then ShowMessage('1a: False');
if (B = True) then ShowMessage('1a: True');
if not B then ShowMessage('1b: False');
if B then ShowMessage('1b: True');

B := False;
if (B = False) then ShowMessage('2a: False');
if (B = True) then ShowMessage('2a: True');
if not B then ShowMessage('2b: False');
if B then ShowMessage('2b: True');

B := Boolean(3); // Es gibt 255 Werte für TRUE, aber die Konstante kennt nur EINEN davon
if (B = False) then ShowMessage('3a: False'); // das nicht
if (B = True) then ShowMessage('3a: True');  // UND auch das nicht ;)
if not B then ShowMessage('3b: False');
if B then ShowMessage('3b: True');

DeddyH 30. Aug 2017 17:06

AW: Noch mal zu neuen Komponenten - Neue Events - Methoden
 
Und noch ein Tipp: wenn Deine Komponente intern Klasseninstanzen erzeugt, die nach außen als Property weitergegeben werden, dann solltest Du diese unbedingt entweder ReadOnly deklarieren oder in einem Setter nur die Werte kopieren (TPersistent.Assign), sonst hast Du Dir ganz schnell Speicherlecks eingefangen, sobald jemand den Properties Instanzen zuweist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:48 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz