Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

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/)
-   -   Delphi Eigene Komponente von TCustomControl > Eigenschaftseditor! (https://www.delphipraxis.net/67231-eigene-komponente-von-tcustomcontrol-eigenschaftseditor.html)

cherry 11. Apr 2006 14:33


Eigene Komponente von TCustomControl > Eigenschaftseditor
 
Tach wohl...

Ich will mir mein eigener Button Programmieren, wie bereits im Titel erwähnt, leite ich meine
Komponente von TCustomControl ab...

Ich möchte jetzt, um die Farbe des Buttons verändern zu können, ein Eigenschaftseditor
einbinden (TColorProperty)

Nur habe ich mühe dabei..
Das Konkrete Fehlermeldung lautet:
[Fehler] EButton_API.pas(10): Undefinierter Bezeichner: 'TPropertyColor'

Hier meine zwei Dateien:
Zwei Dateien sind notwendig weil es nicht erlaubt ist die Editoren ausserhalb IDE
zu verwenden oder so.. Hier die Erklärung dazu

Datei1: EButton.pas:

Delphi-Quellcode:
unit EButton;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, Graphics;

type
  TEButton = class(TCustomControl)
  private
    FFont : TFont;
    { Private-Deklarationen }
  protected
    procedure Paint; override;
    { Protected-Deklarationen }
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Public-Deklarationen }
  published
    property Font: TFont read FFont write FFont;
    { Published-Deklarationen }
   
  end;

procedure Register;

implementation

procedure Register; //Procedure wird bei der Komponenteninstallation verwendet!
begin
  RegisterComponents('RComponents', [TEButton]);
end;

{------------------------------------------------}
{                                                }
{                                                }
{                  TRButton                     }
{                                                }
{------------------------------------------------}

constructor TEButton.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 FFont:=TFont.Create;
end;

destructor TEButton.Destroy;
begin
 FFont.Free;
 inherited Destroy;
end;

procedure TEButton.Paint;
begin
 inherited;//Zeichen Procedure des Vorfahren aufrufen.
 if csDesigning in ComponentState then //Wenn sich die Komponente in Entwicklung befindet.
 begin
  {Zeichung eines Rahmens}
   Canvas.Brush.Style := bsSolid;
   Canvas.Brush.Color := clblue;
   Canvas.Pen.Color := clblack;
   Canvas.Rectangle(0,0,width,height);//Rechteck zeichnen

   {Namen der Komponente in die Mitte schreiben}
   canvas.Font := FFont;
   canvas.TextOut((width - Canvas.TextWidth(Name)) div 2,(height - Canvas.TextHeight(Name)) div 2,name);

   {Keine weitern Zeichnungen mehr ausführen}
   exit;//Verlässt die Procedure
 end;

 {Zeichung eines Rahmens}
 Canvas.Brush.Style := bsSolid;
 Canvas.Brush.Color := clblue;
 Canvas.Pen.Color := clblack;
 Canvas.Rectangle(0,0,width,height);//Rechteck zeichnen

 {Namen der Komponente in die Mitte schreiben}
 canvas.Font := FFont;
 canvas.TextOut((width - Canvas.TextWidth(Name)) div 2,(height - Canvas.TextHeight(Name)) div 2,name);

 {Keine weitern Zeichnungen mehr ausführen}
 exit;//Verlässt die Procedure
end;

{------------------------------------------------}
{                                                }
{                                                }
{                   TEColor                     }
{                                                }
{------------------------------------------------}


end.
Datei2: EButton_API.pas:

Delphi-Quellcode:
unit EButton_API;

interface

uses
   {$ifdef ver150} DesignIntf, DesignEditors,{$else} DsgnIntf,{$endif}
   EButton,SysUtils,Classes,Controls,QGraphics;

type
  TEColor = class(TColorProperty)
  public
   procedure Edit; override;
   function GetColor : TPropertyColor; override;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('RComponents', [TEButton]);
  RegisterPropertyEditor(TypeInfo(TColor), TEButton, 'Color', TRColor);
end;

{ TRColor }

procedure TColorProperty.Edit;
var
 ColorDialog: TColorDialog;
begin
  **ColorDialog := TColorDialog.Create(Application);**********{ Editor erzeugen}
  try
    ****ColorDialog.Color := GetOrdValue;*********************{ Vorhandenen Wert verwenden }
    ****if ColorDialog.Execute then************************** { Wenn der Anwender auf OK klickt ... }
      ******SetOrdValue(ColorDialog.Color);*******************{ ...das Ergebnis verwenden, um den Wert zu setzen}

  finally
    ****ColorDialog.Free;*************************************{ Editor freigeben }
  *end;
*end;

end.
Wäre echt cool wenn man da was machen könnte...

Freundliche Grüsse
und Danke zum Voraus

Cherry

uligerhardt 11. Apr 2006 15:28

Re: Eigene Komponente von TCustomControl > Eigenschaftsed
 
Ich hab's jetzt nicht nachgeprüft, aber hätte gedacht, dass Delphi für Eigenschaften vom Typ TColor automatisch den passenden Editor im OI anbietet. Hast du schon mal probiert, den RegisterPropertyEditor-Aufruf einfach wegzulassen?

Außerdem benutzt du einmal die Unit Graphics und einmal die QGraphics. Ich würde mich an deiner Stelle für eine Variante entscheiden. :-)

Und in der Unit EButton kannst du die Routine Register rausschmeißen - die muss nur im Designzeitpackage sein.

cherry 11. Apr 2006 15:36

Re: Eigene Komponente von TCustomControl > Eigenschaftsed
 
Danke für deine Antwort...

Danke für deine Tipps..
Ich habe in der Zwischenzeit noch ein bisschen herumgesurft und getestet.
Du hast vollkommen Recht was dies angeht:

Zitat:

Zitat von uligerhardt
Ich hab's jetzt nicht nachgeprüft, aber hätte gedacht, dass Delphi für Eigenschaften vom Typ TColor automatisch den passenden Editor im OI anbietet.

Ich habs jetzt ganz normal gemacht und es funktioniert bestens..
Allerdings habe ich da noch eine Frage:

Was hatt es eigentlich damit auf sich?

Ich Zitiere von MaBuSE -> Referenz
"In Delphi 5 Komponenten wird oft die Unit DsgnIntf verwendet.

Damit ist es möglich "Component-" und "Propertyeditoren" zu programmieren, die dann in der IDE ausgeführt werden. Diese Design-Editoren sind ausschließlich für die IDE lizenziert und dürfen nicht in die eigenen Programme, welche außerhalb der IDE laufen eingebunden werden. Da es einige Verstöße (meistens wohl aus Unwissenheit) gab, wurden die Units getrennt und durch "Compiler-Magic" können die Editoren jetzt nicht mehr in Programme außerhalb der IDE eingebunden werden.
"

Gruss

MaBuSE 11. Apr 2006 16:20

Re: Eigene Komponente von TCustomControl > Eigenschaftsed
 
Zitat:

Zitat von uligerhardt
Ich hab's jetzt nicht nachgeprüft, aber hätte gedacht, dass Delphi für Eigenschaften vom Typ TColor automatisch den passenden Editor im OI anbietet. Hast du schon mal probiert, den RegisterPropertyEditor-Aufruf einfach wegzulassen?

Stimmt. Ich habe mal ein Beispielprogramm geschrieben (TMyColorButton)

Zitat:

Zitat von uligerhardt
Außerdem benutzt du einmal die Unit Graphics und einmal die QGraphics. Ich würde mich an deiner Stelle für eine Variante entscheiden. :-)

Stimmt. Graphics ist die VCL Variante (meine Empfehlung) und QGraphics ist die CLX Variante (nur zu empfehlen, falls Projekte auch mit Kylix kompiliert werden sollen)

Zitat:

Zitat von uligerhardt
Und in der Unit EButton kannst du die Routine Register rausschmeißen - die muss nur im Designzeitpackage sein.

Stimmt, aber wenn er keine Designtimepackage braucht, dann kann er es drinn lassen.

@cherry: Ich habe mir Deine Komponente mal angeschaut und ein kleines Beispiel gemacht.
(Die Font und Caption Eingenschaften habe ich bewust weggelassen, damit das Beispiel kleiner bleibt.)

Delphi-Quellcode:
///////////////////////////////////////////////////////////////////////////////
// TMyColorButton
//
// Beispielprogramm zur Komponentenerstellung
//
// Folgende Dinge sind zu sehen:
//   - eine einfache Message wird behandelt ( CM_MOUSEENTER und CM_MOUSELEAVE )
//   - Propertys werden verwendet
//   - bei TColor und TBrushStyle werden automatisch
//     die Standard Property Editoren verwendet
//   - ein protected Event wird published (OnClick)
//
// 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 - 11.04.2006 - MaBuSE:     Erste Version war in 10 min programmiert
///////////////////////////////////////////////////////////////////////////////

unit MyColorButton;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, Graphics, Messages;

type
  TMyColorButton = class(TcustomControl)
  private
    { Private-Deklarationen }
    FmyActiveBrushColor: TColor;
    FmyBrushColor: TColor;
    FmyBrushStyle: TBrushStyle;
    FmyMouseOver: Boolean;
    FmyPenColor: TColor;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure SetmyActiveBrushColor(const Value: TColor);
    procedure SetmyBrushColor(const Value: TColor);
    procedure SetmyBrushStyle(const Value: TBrushStyle);
    procedure SetmyPenColor(const Value: TColor);
  protected
    { Protected-Deklarationen }
    procedure Paint; override;
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent); override;
  published
    { Published-Deklarationen }
    property myActiveBrushColor: TColor read FmyActiveBrushColor write SetmyActiveBrushColor;
    property myBrushColor: TColor read FmyBrushColor write SetmyBrushColor;
    property myBrushStyle: TBrushStyle read FmyBrushStyle write SetmyBrushStyle;
    property myPenColor: TColor read FmyPenColor write SetmyPenColor;
    property OnClick;
  end;

procedure Register;

implementation

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

{ TMyColorButton }

procedure TMyColorButton.CMMouseEnter(var Message: TMessage);
begin
  // wird automatisch aufgerufen wenn der Mauszeiger über dem Control ist.
  inherited;
  FmyMouseOver := true;
  RePaint;
end;

procedure TMyColorButton.CMMouseLeave(var Message: TMessage);
begin
  // wird automatisch aufgerufen wenn der Mauszeiger nicht mehr über dem Control ist.
  inherited;
  FmyMouseOver := false;
  RePaint;
end;

constructor TMyColorButton.Create(AOwner: TComponent);
begin
  inherited;
  FmyActiveBrushColor:= clRed;
  FmyBrushColor := clGreen;
  FmyBrushStyle := bsDiagCross;
  FmyMouseOver := false;
  FmyPenColor := clBlue;
end;

procedure TMyColorButton.Paint;
begin
  inherited;

  if (csDesigning in ComponentState) or (not FmyMouseOver) then
  begin
    Canvas.Brush.Color := FmyBrushColor;
  end
  else
  begin
    Canvas.Brush.Color := FmyActiveBrushColor;
  end;

  Canvas.Brush.Style := FmyBrushStyle;
  Canvas.Pen.Color := FmyPenColor;
  Canvas.Rectangle(0,0,width,height);
end;

// Die folgenden proceduren werden beim Ändern einer Property aufgerufen
// hier steht überall ein RePaint damit die geänderten Einstellungen
// auch sichtbar werden.

procedure TMyColorButton.SetmyActiveBrushColor(const Value: TColor);
begin
  FmyActiveBrushColor := Value;
  RePaint;
end;

procedure TMyColorButton.SetmyBrushColor(const Value: TColor);
begin
  FmyBrushColor := Value;
  RePaint;
end;

procedure TMyColorButton.SetmyBrushStyle(const Value: TBrushStyle);
begin
  FmyBrushStyle := Value;
  RePaint;
end;

procedure TMyColorButton.SetmyPenColor(const Value: TColor);
begin
  FmyPenColor := Value;
  RePaint;
end;

end.
Ich hoffe das hilft Dir.
Viel Spaß

[edit] url oben in Quelltext eingefügt [/edit]

MaBuSE 11. Apr 2006 16:22

Re: Eigene Komponente von TCustomControl > Eigenschaftsed
 
Zitat:

Zitat von cherry
Was hatt es eigentlich damit auf sich?

Ich Zitiere von MaBuSE -> Referenz
"In Delphi 5 Komponenten wird oft die Unit DsgnIntf verwendet.

Damit ist es möglich "Component-" und "Propertyeditoren" zu programmieren, die dann in der IDE ausgeführt werden. Diese Design-Editoren sind ausschließlich für die IDE lizenziert und dürfen nicht in die eigenen Programme, welche außerhalb der IDE laufen eingebunden werden. Da es einige Verstöße (meistens wohl aus Unwissenheit) gab, wurden die Units getrennt und durch "Compiler-Magic" können die Editoren jetzt nicht mehr in Programme außerhalb der IDE eingebunden werden.
"

Man kann auch eigene Property- und Component Editoren schreiben.
Dazu verwendet man Objekte von Borland, die nicht zur Weitergabe freigegeben sind.
Das ist alles.

Mal schauen, vieleicht schreib ich Dir Morgen mal ein kleines Beispiel.

cherry 11. Apr 2006 16:28

Re: Eigene Komponente von TCustomControl > Eigenschaftsed
 
Vielen Dank MaBuSE

Ist echt net von dir!! :thumb:
Ich werde entweder noch an meiner Version versuchen weiter zu basteln,
oder vielleicht werde ich auch an deinem Beispiel weitermachen.
Auf jedenfall stelle ich den Quellcode dann wieder unter diesem Thread zur Verfügung!

Namen bleiben ;)

Nochmals recht herzlichen Dank!

Freundliche Grüsse

Cherry

MaBuSE 12. Apr 2006 06:51

Re: Eigene Komponente von TCustomControl > Eigenschaftsed
 
Zitat:

Zitat von cherry
Vielen Dank MaBuSE

Keine Ursache, gern geschehen.

Zitat:

Zitat von cherry
Namen bleiben ;)

In diesem Fall lege ich auf den Namen keinen großen Wert, da ich ja nicht viel Zeit investiert habe :-)
Das ist nur mein Standard Header für Pascal Dateien, die ich in die DP stelle.
Damit muß ich nicht jedesmal einen neuen erfinden ;-)

cherry 12. Apr 2006 10:33

Re: Eigene Komponente von TCustomControl > Eigenschaftsed
 
Zitat:

Zitat von MaBuSE
// Es wäre nett, wenn dann auch der geänderte Quelltext in obiges URL-Adresse
// gesendet wird. Dann haben alle was davon.

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!?

URL = Uniform Resource Locator !
obiges Uniform Resource Locator ??

Eben wie gesagt, vielleicht liege ich falsch aber ich wurde einfach schreiben " ... in die obige URL-Adresse ... "

Zitat:

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. :cyclops:

MaBuSE 12. Apr 2006 13:06

Re: Eigene Komponente von TCustomControl > Eigenschaftsed
 
Zitat:

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:

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. :cyclops:

:oops: 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 12. Apr 2006 13:20

Re: Eigene Komponente von TCustomControl > Eigenschaftsed
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von MaBuSE
Hier mal ein Beispiel zu einem "echtem" PropertyEditor:...

Der Beitrag ist wegen des Quellcodes ziemlich lang geworden.

Da im Quelltext durch die Kommentare (die grüne Schrift :-)) meinen Beitrag sehr kurz werden lies, habe ich das in Kauf genommen.

Für alle die es nun auch zuhause ausprobieren wollen:

Hier ist der komplette Quelltext:
  • myPersonComponent.pas
  • myPersonComponent_dsgn.dfm
  • myPersonComponent_dsgn.pas
  • Package1.dpk
  • Package1.res
  • PropertyEditor1.jpg
  • PropertyEditor2.jpg
  • PropertyEditor3.jpg


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:19 Uhr.
Seite 1 von 4  1 23     Letzte »    

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