Einzelnen Beitrag anzeigen

Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.837 Beiträge
 
Delphi 10 Seattle Enterprise
 

Re: Eigene Komponente von TCustomControl > Eigenschaftsed

  Alt 12. Apr 2006, 13:06
Zitat von cherry:
Also ich bin ja kein Deutscher und die Sprache liegt mir auch nicht besonders, aber irgendwie passt hier (nach meinem Gefühl) "obiges" nicht. Oder!?
Zitat von MaBuSE:
Das ist nur mein Standard Header für Pascal Dateien, die ich in die DP stelle.
Damit muß ich nicht jedesmal einen neuen erfinden
Und da du diesen Header standardmässig verwendest, dachte ich, mache ich dich darauf aufmerksam.
Danke.
(Ich habe den Header zum Glück erst zwei, drei mal verwendet

Hier mal ein Beispiel zu einem "echtem" PropertyEditor:

Die Komponente TmyPersonComponent hat eine Eigenschaft Person die vom Typ TPerson ist.
Ich habe es mir einfasch gemacht und TPerson vom Typ TPersistent abgeleitet. Im Prinzip geht auch TObject oder ein Record. Dann muß man aber die GetProperties Methode selbst implementieren, damit sich beim Drücken auf das [+] auch weitere Untereigenschaften öffnen.


Hier ist der Objektinspektor zu sehen.


Wenn man auf den [...] Button klickt öffnet sich der PropertyEditor.


Analog dazu kann man auch die Untereigenschaften von TPerson ändern


Also hier die Komponente:
Delphi-Quellcode:
///////////////////////////////////////////////////////////////////////////////
// TmyPersonComponent
//
// Beispielprogramm zur Komponentenerstellung
//
// Folgende Dinge sind zu sehen:
// - komplexe Properties werden verwendet (Objekt TPerson)
// - Einfacher Propertyeditor wird verwendet (s. myPersonComponent_dsgn.pas)
//
// Dieser Quelltext liegt auch auf [url]www.delphipraxis.net[/url]
// ( [url]http://www.delphipraxis.net/topic80394_eigene+komponente+von+tcustomcontrol+eigenschaftseditor.html[/url] )
//
///////////////////////////////////////////////////////////////////////////////
// Das Programm ist Freeware und darf beliebig benutzt und erweitert werden.
// Es wäre nett, wenn dann auch der geänderte Quelltext in obige URL-Adresse
// gesendet wird. Dann haben alle was davon.
// Es wäre auch nett wenn mein (unser) Name in den Dateien enthalten bleibt.
// Das Programm wird von Ihnen auf eigenes Risiko eingesetzt. Ich übernehme
// keine Haftung für Schäden die durch das Programm oder die Benutzung des
// Programms entstanden sind bzw. entstehen.
///////////////////////////////////////////////////////////////////////////////
// (C) 2005, MaBuSE, member of DelphiPraxis.net
///////////////////////////////////////////////////////////////////////////////
// ReleaseNotes:
// v1.0 - 12.04.2006 - MaBuSE: Erste Version war in 25 min programmiert
// (inkl. PropertyEditor)
///////////////////////////////////////////////////////////////////////////////
unit myPersonComponent;

interface

uses
  SysUtils, Classes, Controls, StdCtrls;

type
  // Das ist ein Objekt, das die Daten einer Person speichert.
  // im Beispiel nur Vor- und Nachname :-)
  TPerson = class(TPersistent)
  private
    FVorname: string;
    FNachname: string;
  public
    function getDisplayValue: string;
  published
    property Nachname: string read FNachname write FNachname;
    property Vorname: string read FVorname write FVorname;
  end;

  // Das ist die Komponente die als Property eine Person beinhaltet
  // Die Person kann über die Untereigenschaften [+] oder über
  // den Propertyeditor Dialog [...] bearbeitet werden.
  TmyPersonComponent = class(TComponent)
  private
    FPerson: TPerson;
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published-Deklarationen }
    property Person : TPerson read FPerson write FPerson;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Beispiele', [TmyPersonComponent]);
end;

{ TmyPersonComponent }

constructor TmyPersonComponent.Create(AOwner: TComponent);
begin
  inherited;
  FPerson := TPerson.Create;
end;

destructor TmyPersonComponent.Destroy;
begin
  FPerson.Free;
  FPerson := nil;
  inherited;
end;

{ TPerson }

// getdisplayText wird im PropertyEditor verwendet um im Objektinspektor
// Den Namen anzuzeigen. '(Nachname, Vorname)'
function TPerson.getDisplayValue: string;
var
  s: string;
begin
  if (FNachname = '') or (FVorname = '') then
  begin
    s := FNachname + FVorname;
    if s = 'then
    begin
      s := 'leer'
    end;
  end
  else
  begin
    s := FNachname + ', ' + FVorname;
  end;
  Result := '('+s+')';
end;

end.
Und hier der PropertyEditor:

Delphi-Quellcode:
///////////////////////////////////////////////////////////////////////////////
// PropertyEditor zu TmyPersonComponent
//
// Beispielprogramm zur Komponentenerstellung
//
// Folgende Dinge sind zu sehen:
// - komplexe Properties werden verwendet (Objekt TPerson)
// - Einfacher Propertyeditor wird verwendet (s. myPersonComponent_dsgn.pas)
//
// Dieser Quelltext liegt auch auf [url]www.delphipraxis.net[/url]
// ( [url]http://www.delphipraxis.net/topic80394_eigene+komponente+von+tcustomcontrol+eigenschaftseditor.html[/url] )
//
///////////////////////////////////////////////////////////////////////////////
// Das Programm ist Freeware und darf beliebig benutzt und erweitert werden.
// Es wäre nett, wenn dann auch der geänderte Quelltext in obige URL-Adresse
// gesendet wird. Dann haben alle was davon.
// Es wäre auch nett wenn mein (unser) Name in den Dateien enthalten bleibt.
// Das Programm wird von Ihnen auf eigenes Risiko eingesetzt. Ich übernehme
// keine Haftung für Schäden die durch das Programm oder die Benutzung des
// Programms entstanden sind bzw. entstehen.
///////////////////////////////////////////////////////////////////////////////
// (C) 2005, MaBuSE, member of DelphiPraxis.net
///////////////////////////////////////////////////////////////////////////////
// ReleaseNotes:
// v1.0 - 12.04.2006 - MaBuSE: Erste Version war in 25 min programmiert
// (inkl. PropertyEditor)
///////////////////////////////////////////////////////////////////////////////
unit myPersonComponent_dsgn;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, DesignIntf, DesignEditors, myPersonComponent;

type
  // Formular des PropertyEditors
  TfrmPersonPropertyEditor = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  // Der eigentliche PropertyEditor
  TmyPersonPropEditor = class(TClassProperty)
  protected
    // zwei Hilfsfunktionen um auf TPerson zuzugreifen
    function GetPerson: TPerson;
    procedure SetPerson(const Value: TPerson);
  public
    // hier wird das Formular aufgerufen
    procedure Edit; override;
    // hier wird bestimmt, die das Property im Objektinspektor angezeigt wird
    function GetAttributes: TPropertyAttributes; override;
    // das wird im Objektinspektor angezeigt
    function GetValue: string; override;
  end;

procedure Register;

implementation

{$R *.dfm}

procedure Register;
begin
  // Der PropertyEditor TmyPersonPropEditor (4. Parameter)
  // wird für alle Properties:
  // - vom Typ TPerson (1. Parameter)
  // - in der Komponente TmyPersonComponent inkl. Nachfahren (2. Parameter)
  // - mit dem Namen 'Person'
  // in der Delphi IDE verwendet.
  // Wenn als 2. Parameter nil übergeben wird, dann wird der PropertyEditor von
  // allen Komponenten verwendet.
  // Wenn als 3. Parameter '' übergeben wird, dann wird der PropertyEditor von
  // allen Eigenschaften des Typs TPerson verwendet.
  RegisterPropertyEditor(TypeInfo(TPerson), TmyPersonComponent, 'Person', TmyPersonPropEditor);
end;

{ TmyPersonPropEditor }

procedure TmyPersonPropEditor.Edit;
begin
  inherited;
  // Get Person sollte immer <> nil sein, da es im Constructor der Komponente
  // erzeugt wird.
  if GetPerson = nil then
  begin
    SetPerson(TPerson.Create);
  end;

  // Form erzeugen, füllen und aufrufen.
  // Wenn OK gedrückt wurde Werte übernehmen.
  // Zuletzt Form wieder aus Speicher entfernen.
  with TfrmPersonPropertyEditor.Create(nil) do
  try
    Edit1.Text := GetPerson.Nachname;
    Edit2.Text := GetPerson.Vorname;
    if ShowModal = idOk then
    begin
      getPerson.Nachname := Edit1.Text;
      getPerson.Vorname := Edit2.Text;
    end;
  finally
    Free;
  end;
end;

function TmyPersonPropEditor.GetAttributes: TPropertyAttributes;
begin
  // inherited GetAtributes liefert [paSubProperties] zurück,
  // das ist schon in TClassProperty implementiert.

  // paSubProperties:
  // Die Eigenschaft verfügt über Untereigenschaften, die unterhalb der
  // aktuellen Eigenschaft stehen und mit einer Einrückung versehen werden.
  // Wenn paSubProperties gewählt wird, muss die Eigenschaft GetProperties
  // so überschrieben werden, dass Sie Untereigenschaften übergibt.
  // In der TClassProperty ist glücklicherweise schon GetProperties
  // implementiert, so das wir uns das sparen können.

  // paDialog:
  // Die Methode Edit öffnet ein Dialogfeld. Außerdem wird im Objektinspektor
  // neben der Eigenschaft eine Ellipsen-Schaltfläche [...] platziert.

  // Es sind noch weitere Werte möglich. Einfach die Onlinehilfe zu
  // TPropertyAttributes aufrufen.

  Result := inherited GetAttributes + [paDialog];
end;

function TmyPersonPropEditor.GetPerson: TPerson;
begin
  // Das ist ein kleiner Trick. Das Objekt TPerson wird einfach mit
  // Longint(TPerson) einer Integer Variablen zugewiesen.
  // Mit TPerson(Integerwert) kann dann wieder auf das Objekt zugegriffen werden.
  // Es wird also quasi der "Pointer" auf das Objekt weitergegeben.

  // Folgende Zeile würde eigentlich reichen, da TPerson im Constuctor der
  // Komponente erzeugt wird:
  // Result := TPerson(GetOrdValue);
  // Die Überprüfung auf nil ist nur zusätzliche Sicherheit
  if GetOrdValue <> 0 then
  begin
    Result := TPerson(GetOrdValue);
  end
  else
  begin
    Result := nil;
  end;
end;

function TmyPersonPropEditor.GetValue: string;
begin
  // Hier wird der Wert zurückgegeben, der im Objektinspektor angezeigt wird.

  // Folgende Zeile würde eigentlich reichen, da TPerson im Constuctor der
  // Komponente erzeugt wird:
  // Result := GetPerson.getDisplayValue;
  // Die Überprüfung auf nil ist nur zusätzliche Sicherheit
  if GetPerson <> nil then
  begin
    Result := GetPerson.getDisplayValue;
  end
  else
  begin
    Result := '(nil)';
  end;
end;

procedure TmyPersonPropEditor.SetPerson(const Value: TPerson);
begin
  // Das ist ein kleiner Trick. Das Objekt TPerson wird einfach mit
  // Longint(TPerson) einer Integer Variablen zugewiesen.
  // Mit TPerson(Integerwert) kann dann wieder auf das Objekt zugegriffen werden.
  // Es wird also quasi der "Pointer" auf das Objekt weitergegeben.
  SetOrdValue(Longint(Value));
end;

end.
Die Dfm Datei des PropertyEditors sieht wie folgt aus:
Delphi-Quellcode:
object frmPersonPropertyEditor: TfrmPersonPropertyEditor
  Left = 588
  Top = 336
  Width = 354
  Height = 133
  Caption = 'Propertyeditor'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 8
    Top = 12
    Width = 31
    Height = 13
    Caption = 'Name:'
  end
  object Label2: TLabel
    Left = 8
    Top = 36
    Width = 45
    Height = 13
    Caption = 'Vorname:'
  end
  object Edit1: TEdit
    Left = 72
    Top = 8
    Width = 265
    Height = 21
    TabOrder = 0
    Text = 'Edit1'
  end
  object Edit2: TEdit
    Left = 72
    Top = 32
    Width = 265
    Height = 21
    TabOrder = 1
    Text = 'Edit2'
  end
  object BitBtn1: TBitBtn
    Left = 152
    Top = 64
    Width = 89
    Height = 25
    TabOrder = 2
    Kind = bkOK
  end
  object BitBtn2: TBitBtn
    Left = 248
    Top = 64
    Width = 89
    Height = 25
    TabOrder = 3
    Kind = bkCancel
  end
end
Ich hoffe das bringt Dich weiter.
Viel Spaß

ps: Ich werde mal bei Gelegenheit um die Beispielkomponenten ein kleines Tutorial zur Komponentenentwicklung schreiben...
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
  Mit Zitat antworten Zitat