Interface delegates and implements

_at_zclient(dec(spam)).com
Date: 12/15/03


Date: Mon, 15 Dec 2003 12:15:33 -0600

I am trying to extend a set of GUI components with a set of common data
properties that are independent of the widgets normal behaviors. To my
understanding this is a case well suited to interface delegation -
define an interface with new properties in it, implement that in a class
and the extend the UI components to implement the interface and the
delegate that to the same class for all controls.

When I try to do this I run into two issues

1) The properties in the interface are not being stream out with the
form. Actually the whole delegate class instance is not being streamed.

2) I cannot write TExtendedWidget.interfaceProperty with out the
complier complaining that interfaceProperty is not defined.

I have a simple example done up here using a TComponent descendant...

unit Implements;

interface
uses
   classes;
type

IMyInterface = interface(IInterface)
   function getNumber : integer;
   procedure setNumber (value : integer);
   property Number : integer read getNumber write setNumber;
end;

TMyDelegate = class(TComponent, IMyInterface)
   protected
     fNumber : integer;
   published
     function getNumber : integer;
     procedure setNumber(value : integer);
     property Number : integer read getNumber write setNumber;
end;

TMyComponent = class(TComponent, IMyInterface)
   protected
     fDelegate : TMyDelegate;
   public
     constructor Create(AOwner : TComponent); override;
   published
     property delegate : TMyDelegate read fDelegate write fDelegate
implements IMyInterface;
end;

implementation

{ TMyDelegate }

function TMyDelegate.getNumber: integer;
begin
   result := fNumber;
end;

procedure TMyDelegate.setNumber(value: integer);
begin
   fNumber := value;
end;

{ TMyComponent }

constructor TMyComponent.Create(AOwner: TComponent);
begin
   inherited;
   fDelegate := TMyDelegate.create(self);
end;

end.

unit ImplementsTest;

interface

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
   Dialogs, Implements, StdCtrls;

type
   TForm1 = class(TForm)
     MyComponent1: TMyComponent;
     Button1: TButton;
     procedure Button1Click(Sender: TObject);
   private
     { Private declarations }
   public
     { Public declarations }
   end;

var
   Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
//can set this in object inspector but is not save to .dfm
//MyComponent1.number := 1000; {compiler complains here}
end;

end.

object Form1: TForm1
   Left = 191
   Top = 129
   Width = 251
   Height = 197
   Caption = 'Form1'
   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 Button1: TButton
     Left = 72
     Top = 8
     Width = 75
     Height = 25
     Caption = 'Button1'
     TabOrder = 0
     OnClick = Button1Click
   end
   object MyComponent1: TMyComponent
     Left = 16
     Top = 8
   end
end