Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create Delphi component inherited from few other components?

Tutorials that I found about how to create delphi components were nice, but they only used one of existing components as object to inherit actions from. Something like this

unit CountBtn;

interface

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

type
 TCountBtn = class(TButton)
  private
  FCount: integer;
  protected
  procedure Click;override;
  public
  procedure ShowCount;
  published
  property Count:integer read FCount write FCount;
  constructor Create(aowner:Tcomponent); override;
 end;

procedure Register;

implementation

procedure Register;
begin
 RegisterComponents('Mihan Components', [TCountBtn]);
end;

constructor TCountBtn.Create(aowner:Tcomponent);
begin
 inherited create(Aowner);
end;

procedure Tcountbtn.Click;
begin
 inherited click;
 FCount:=FCount+1;
end;

procedure TCountBtn.ShowCount;
begin
 Showmessage('On button '+ caption+' you clicked: '+inttostr(FCount)+' times');
end;

end.

But what should I do if I need component which use few elements? Lets say, I got Button and Edit field. And on button click there in edit field should appers text the same as on button. I start to make it like this, but seems like it's not gonna work as I want:

unit TestComp;

interface

uses
  System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TUiCompU = class(TCustomControl)
  private
    { Private declarations }
    FButton: TButton;
    FEdit: TEdit;

  protected
    { Protected declarations }
    procedure Paint; override;
    //wrong!
    procedure FButton.Click;override
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
  published
    { Published declarations }
    //wrong!
     property ButtonText: String read FButton.Caption write FButton.Caption;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Ui', [TUiCompU]);
end;

{ TUiCompU }

constructor TUiCompU.Create(AOwner: TComponent);
begin
  inherited;
  Width := 200;
  Height := 50;

  FButton := TButton.Create(Self);
  FButton.SetSubComponent(True);
  FButton.Parent := Self;
  FButton.Top := 8;
  FButton.Left := 50;
  FButton.Width := 35;
  FButton.Name := 'Button';

  FEdit := TEdit.Create(Self);
  FEdit.SetSubComponent(True);
  FEdit.Parent := Self;
  FEdit.Top := 8;
  FEdit.Left := 84;
  FEdit.Width := 121;
  FEdit.Name := 'Edit';
end;

procedure TUiCompU.Paint;
begin
  Canvas.Rectangle(ClientRect);
end;

end.

How should I add here Click procedure, which is realte to click on the button? And is there are good tutorial about how to made good components using others? (I need to create something like slideshow component btw). Thank you, and sorry for my english.

like image 579
DanilGholtsman Avatar asked Dec 21 '13 21:12

DanilGholtsman


1 Answers

You can write methods for the subcomponent events, but it has one big weakness; if you publish those subcomponents, there is a risk that someone will steal you this binding by writing own method:

type
  TUiCompU = class(TCustomControl)
  private
    FEdit: TEdit;
    FButton: TButton;
    procedure ButtonClick(Sender: TObject);
    procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  public
    constructor Create(AOwner: TComponent); override;
  end;

implementation

constructor TUiCompU.Create(AOwner: TComponent);
begin
  inherited;

  FButton := TButton.Create(Self);
  ...
  FButton.OnClick := ButtonClick;

  FEdit := TEdit.Create(Self);
  ...
  FEdit.OnKeyDown := EditKeyDown;
end;

procedure TUiCompU.ButtonClick(Sender: TObject);
begin
  // do whatever you want here
end;

procedure TUiCompU.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  // do whatever you want here
end;
like image 50
TLama Avatar answered Nov 15 '22 14:11

TLama