I have a custom component that has a custom property that itself is an object (descended from TComponent). I've managed to create a property editor for this new property and everything seems to work properly when setting property values at design time. Changes in either the Object Inspector, or in my property editor are displayed correctly in the Object inspector. However, when I run my app changes to the property values are not reflected in the executable. Here is the code for ecerything...the custom property, the property editor, and the custom component. What am I doing wrong?
unit MyCustomComponent;
//{$mode objfpc}{$H+}
{$mode delphi}{$H+}
interface
uses
Classes, SysUtils, StdCtrls, PropEdits, Forms, Buttons, Spin, Dialogs,
Controls;
Type
TMyCustomProperty = Class(TComponent)
Private
FMyInteger: Integer;
FMyString: String;
Procedure SetMyInteger(pMyInteger: Integer);
Procedure SetMyString(pMyString: String);
Public
Constructor Create(AOwner: TComponent); Override;
Destructor Destroy;
Procedure Copy(pMyCustomProperty: TMyCustomProperty);
Published
Property MyInteger: Integer read FMyInteger
write SetMyInteger;
Property MyString: String read FMyString
write SetMyString;
end;
{ TMyCustomPropertyPropertyEditor }
TMyCustomPropertyPropertyEditor = class(TClassPropertyEditor)
public
procedure Edit; override;
function GetAttributes: TPropertyAttributes; override;
end;
{ TfrmMyCustomPropertyPropertyEditor }
TfrmMyCustomPropertyPropertyEditor = class(TForm)
bitOK: TBitBtn;
bitCancel: TBitBtn;
txtString: TEdit;
Label1: TLabel;
Label2: TLabel;
speInteger: TSpinEdit;
Procedure FormCreate(Sender: TObject);
procedure speIntegerChange(Sender: TObject);
procedure txtStringChange(Sender: TObject);
private
{ private declarations }
FMyCustomProperty: TMyCustomProperty;
FMyCustomPropertyOrig: TMyCustomProperty;
Procedure SetMyCustomProperty(Value: TMyCustomProperty);
public
{ public declarations }
function Execute: Boolean;
Property MyCustomProperty: TMyCustomProperty read FMyCustomProperty
write SetMyCustomProperty;
end;
TMyCustomComponent = class(TEdit)
private
{ Private declarations }
FMyInteger: Integer;
FMyString: String;
FMyCustomProperty: TMyCustomProperty;
Procedure DoubleClick(Sender: TObject);
protected
{ Protected declarations }
public
{ Public declarations }
Constructor Create(AOwner: TComponent); Override;
Destructor Destroy; Override;
published
{ Published declarations }
Property MyCustomProperty: TMyCustomProperty read FMyCustomProperty
write FMyCustomProperty;
Property MyInteger: Integer read FMyInteger
write FMyInteger;
Property MyString: String read FMyString
write FMyString;
end;
procedure Register;
var
frmMyCustomPropertyPropertyEditor: TfrmMyCustomPropertyPropertyEditor;
implementation
{$R mycustompropertypropedit.lfm}
function TMyCustomPropertyPropertyEditor.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog, paSubProperties];
end; {GetAttributes}
procedure TMyCustomPropertyPropertyEditor.Edit;
var
lvDialog: TfrmMyCustomPropertyPropertyEditor;
begin
lvDialog := TfrmMyCustomPropertyPropertyEditor.Create(nil);
try
lvDialog.MyCustomProperty := TMyCustomProperty(GetOrdValue);
if lvDialog.Execute then
Begin
SetOrdValue(longint(lvDialog.MyCustomProperty));
end;
finally
lvDialog.Free;
end;
end;
Procedure TfrmMyCustomPropertyPropertyEditor.FormCreate(Sender: TObject);
Begin
If FMyCustomPropertyOrig = Nil Then
Begin
FMyCustomPropertyOrig := TMyCustomProperty.Create(Self);
end;
end;
procedure TfrmMyCustomPropertyPropertyEditor.speIntegerChange(Sender: TObject);
begin
FMyCustomProperty.MyInteger := speInteger.Value;
end;
procedure TfrmMyCustomPropertyPropertyEditor.txtStringChange(Sender: TObject);
begin
FMyCustomProperty.MyString := txtString.Text;
end;
Procedure TfrmMyCustomPropertyPropertyEditor.SetMyCustomProperty(Value: TMyCustomProperty);
Begin
FMyCustomPropertyOrig.Copy(Value);
FMyCustomProperty := Value;
speInteger.Value := FMyCustomProperty.MyInteger;
txtString.Text := FMyCustomProperty.MyString;
end;
function TfrmMyCustomPropertyPropertyEditor.Execute: Boolean;
Var
lvModalResult: TModalResult;
begin
lvModalResult := ShowModal;
If lvModalResult <> mrOK Then
FMyCustomProperty.Copy(FMyCustomPropertyOrig);
Result := (lvModalResult = mrOK);
end;
Procedure TMyCustomProperty.SetMyInteger(pMyInteger: Integer);
Begin
If pMyInteger <> FMyInteger Then
Begin
FMyInteger := pMyInteger;
end;
end;
Procedure TMyCustomProperty.SetMyString(pMyString: String);
Begin
If pMyString <> FMyString Then
Begin
FMyString := pMyString;
end;
end;
Procedure TMyCustomProperty.Copy(pMyCustomProperty: TMyCustomProperty);
Begin
FMyInteger := pMyCustomProperty.MyInteger;
FMyString := pMyCustomProperty.MyString;
end;
Constructor TMyCustomProperty.Create(AOwner: TComponent);
Begin
Inherited Create(AOwner);
end;
Destructor TMyCustomProperty.Destroy;
Begin
Inherited Destroy;
end;
Procedure TMyCustomComponent.DoubleClick(Sender: TObject);
Begin
Text := IntToStr(FMyInteger) + '; ' + FMyString;
end;
Constructor TMyCustomComponent.Create(AOwner: TComponent);
Begin
FMyCustomProperty := TMyCustomProperty.Create(Self);
FMyCustomProperty.MyInteger := 7;
FMyCustomProperty.MyString := 'Test';
Inherited Create(AOwner);
OnDblClick := DoubleClick;
end;
Destructor TMyCustomComponent.Destroy;
Begin
FMyCustomProperty.Free;
Inherited Destroy;
end;
procedure Register;
begin
RegisterComponents('RD Controls',[TMyCustomComponent]);
RegisterPropertyEditor(TypeInfo(TMyCustomProperty), nil, '', TMyCustomPropertyPropertyEditor);
end;
end.