Standardklasse erweitern?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1651
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Standardklasse erweitern?

Beitrag von fliegermichl »

Hallo,

in meinem Delphiprojekt habe ich TEdit.OEMConvert mißbräuchlich verwendet um mir damit anzuzeigen, ob der Wert gespeichert werden soll oder nicht.
Diese Eigenschaft gibt es ja bei Lazarus aber nicht.

Da war doch letztens das Thema, daß man bestehende Klassen erweitern kann ohne den Quellcode der betreffenden Klasse ändern zu müssen.

Kann ich das dazu verwenden?

hum4n0id3
Beiträge: 320
Registriert: So 5. Mai 2019, 15:23

Re: Standardklasse erweitern?

Beitrag von hum4n0id3 »

Du kannst deine eigene Klasse erstellen und von der Mutterklasse alle Eigenschaften und Methoden erben, oder überschreiben. Vorausgesetzt die Klasse läßt das zu.

Mal schnell im Netz gefunden, https://stackoverflow.com/questions/258 ... al-lazarus

Benutzeravatar
theo
Beiträge: 10922
Registriert: Mo 11. Sep 2006, 19:01

Re: Standardklasse erweitern?

Beitrag von theo »

fliegermichl meint wahrscheinlich Class Helper.
Er ist halt erst 12 Jahre dabei und kann die Fragen deshalb noch nicht so richtig auf den Punkt bringen.
Das wird schon noch! :lol:

https://wiki.freepascal.org/Helper_types

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1651
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Standardklasse erweitern?

Beitrag von fliegermichl »

Genau das war's. Danke. :lol:

Benutzeravatar
theo
Beiträge: 10922
Registriert: Mo 11. Sep 2006, 19:01

Re: Standardklasse erweitern?

Beitrag von theo »

fliegermichl hat geschrieben: Sa 1. Jul 2023, 11:43 Genau das war's. Danke. :lol:
Dann fragt sich noch, wie du das mir unbekannte "TEdit.OEMConvert mißbräuchlich verwendet" hast.
Eine starke Einschränkung bei Class Helpern ist, dass man keine neuen Felder definieren kann.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1651
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Standardklasse erweitern?

Beitrag von fliegermichl »

Ja, das hab ich eben auch herausgefunden.
Ich habe jetzt eine von TEdit abgeleitete Klasse definiert, welche dieses Feld bekommen hat.

Zu deiner Frage:
Ich habe eine Datenstruktur mit Eingabewerten, die auch gespeichert werden müssen.
In den Eingabeformularen können aber mehr Eingabewerte enthalten sein.

Es gibt beispielsweise ein Eingabefeld Dachneigung. Das muß gespeichert werden.
Dann gibt es ein Eingabefeld Sparrenlänge. Aus der Gebäudebreite und der Sparrenlänge lässt sich die Dachneigung berechnen und umgekehrt läßt sich aus der Dachneigung die Sparrenlänge berechnen. Bei dem Eingabefeld für Sparrenlänge habe ich OEMConvert auf true gestellt.
Dann weiss die Speicherfunktion, daß dieser Wert nicht abgespeichert wird.

Benutzeravatar
theo
Beiträge: 10922
Registriert: Mo 11. Sep 2006, 19:01

Re: Standardklasse erweitern?

Beitrag von theo »

Ich würde da eher das Property "TComponent.Tag" verwenden, da das mit dem "OEMConvert" doch recht undurchsichtig ist und Nebenwirkungen zeigen könnte.
"Tag" ist für die "freie Benutzung" gemacht.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1651
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Standardklasse erweitern?

Beitrag von fliegermichl »

Tag wird auch schon anderweitig verwendet.
Ich hab die Verwendung von OEMConvert im Source dokumentiert.
Hat bislang keine Probleme gemacht.

Benutzeravatar
theo
Beiträge: 10922
Registriert: Mo 11. Sep 2006, 19:01

Re: Standardklasse erweitern?

Beitrag von theo »

Habe mal ein bisschen herumgespielt.
Im Prinzip kann man den "Tag" natürlich dazu verwenden, um trotz Helper neue Felder einzubauen.
Wie sinnvoll das ist weiss ich nicht, aber ich würde es dem "Missbrauch" zufällig vorhandener Properties eventuell vorziehen.
Man sollte natürlich den "Tag" nicht noch anderweitig verwenden, aber das ist ja immer so mit dem "Tag".

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  {TExtensionClass}

  TExtensionClass = class
  private
    FTest: integer;
  public
    property Test: integer read FTest write FTest;
  end;

  { TEditHelper }

  TEditHelper = class helper for TEdit
  private
    function GetTest: integer;
    procedure SetTest(AValue: integer);
  public
    property Test: integer read GetTest write SetTest;
    procedure CheckExtension;
    procedure FreeExtension;
  end;

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TEditHelper }

function TEditHelper.GetTest: integer;
begin
  CheckExtension;
  Result := TExtensionClass(Tag).Test;
end;

procedure TEditHelper.SetTest(AValue: integer);
begin
  CheckExtension;
  TExtensionClass(Tag).Test := AValue;
end;

procedure TEditHelper.CheckExtension;
begin
  if not (TObject(Tag) is TExtensionClass) then Tag := PtrUint(TExtensionClass.Create);
end;

procedure TEditHelper.FreeExtension;
begin
  if (TObject(Tag) is TExtensionClass) then TExtensionClass(Tag).Free;       
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Test := 23;
  Caption := IntToStr(Edit1.Test);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Edit1.FreeExtension;
end;

end.

hum4n0id3
Beiträge: 320
Registriert: So 5. Mai 2019, 15:23

Re: Standardklasse erweitern?

Beitrag von hum4n0id3 »

Warum nicht eine Klasse erstellen wo das alles gespeichert wird.

Klasse Dach:
Double Laenge;
Double Neigung;

Dann dazu Methoden die bei Gebrauch genutzt werden können.

Sorry, schreibe vom Smartphone, bin gerade unterwegs.

hum4n0id3
Beiträge: 320
Registriert: So 5. Mai 2019, 15:23

Re: Standardklasse erweitern?

Beitrag von hum4n0id3 »

theo hat geschrieben: Sa 1. Jul 2023, 11:38 fliegermichl meint wahrscheinlich Class Helper.
Er ist halt erst 12 Jahre dabei und kann die Fragen deshalb noch nicht so richtig auf den Punkt bringen.
Das wird schon noch! :lol:
Naja, man kann auch nicht an alles denken. Gut ist dann wenn man Forumkollegen hat, bei denen man nachfragen kann 😉

Grad nachgeschaut wie lange ich schon hier bin... 2019 ... Sicher? Ich kann mich erinnern ich konnte mich sehr lange nicht registrieren... Sind schon echt 4 Jahre rum? 😱

Benutzeravatar
theo
Beiträge: 10922
Registriert: Mo 11. Sep 2006, 19:01

Re: Standardklasse erweitern?

Beitrag von theo »

hum4n0id3 hat geschrieben: Sa 1. Jul 2023, 17:08 Warum nicht eine Klasse erstellen wo das alles gespeichert wird.
Ja, kann man auch und das ist wahrscheinlich bei grösseren Erweiterungen auch besser.
Der Vorteil der Helper ist halt, dass man in diesem Beispiel das normale, in der IDE registrierte TEdit verwenden kann ohne dass man die IDE neu bauen oder das TMyEdit im Code erzeugen muss.

Soner
Beiträge: 734
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Standardklasse erweitern?

Beitrag von Soner »

Du kannst machen was ich öfters mache, bestehende Komponenten und Klassen erweitern und eigene Komponenten mit gleichen Namen einbinden.
Wenn ich die erweiterte Komponente in mehreren Units/Programme verwenden möchte dann lagere ich es in neue Unit aus, so:

Code: Alles auswählen

// unit mit erweiterte Komponente
unit Unit2;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, StdCtrls;

type

  { TMyEdit }

  TMyEdit = class(TEdit)
  public
    function SagHallo: string;
  end;

implementation

{ TMyEdit }

function TMyEdit.SagHallo: string;
begin
  Result:= 'Hallo!';
end;

end. 
Hauptprogramm:

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, 
  unit2 // einbinden
  ;

type
  TEdit = class(TMyEdit) //und hier defineren
  end;

  { TForm1 }

  TForm1 = class(TForm)
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  Caption:= Edit1.SagHallo;   // Beispiel für eine Benutzung
end;

end. 
Mann kann es sogar ohne externe Datei verwenden, wenn es nur in ein Formular verwendet werden soll:

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  TEdit = class(StdCtrls.TEdit)
  public
    function SagHallo: string;
  end;

  { TForm1 }

  TForm1 = class(TForm)
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TEdit }

function TEdit.SagHallo: string;
begin
  Result:= 'Hallo!';
end;


{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  Caption:= Edit1.SagHallo;
end;

end.

Antworten