Board index » delphi » Best way to encapsulate two Dephi components?

Best way to encapsulate two Dephi components?

How do I best encapsulate two or more Delphi components (e.g. a TLabel and
a TEdit), in one component, so that I only have to call one create method,
but assign values to both components.

Mvh / Best regards
  Jesper Lauridsen
  E-mail: j...@post1.tele.dk
  Homepage: http://home1.inet.tele.dk/jel/index.html

 

Re:Best way to encapsulate two Dephi components?


Hi, Jesper!

It's really pretty simple - here's a quick (and not really
functional) example to get you started; it's a simple panel
that contains a TLabel and TEdit :

interface

uses { Whatever }

type
    TComboComponent = class(TPanel)
    private
        FCaption: TLabel;
        FEdit   : TEdit;
        function GetCaption: String;
        procedure SetCaption( Value: String );
        { Other private methods used for properties }
    public
        constructor Create( AOwner: TComponent ); override;
        destructor Destroy; override;
    published
        property Caption: String read GetCaption write SetCaption;
    end;

implementation  

constructor TComboComponent.Create(AOwner: TComponent);
begin
    inherited Create(AOwner);
    FCaption := TLabel.Create(Self);
    FEdit := TEdit.Create(Self);
end;

destructor TComboComponent.Destroy;
begin
    { Have to free the child components first }
    FCaption.Free;
    FEdit.Free;
    inherited Destroy;
end;

function TComboComponent.GetCaption: String;
begin
    { Returns the TLabel's Caption }
    Result := FCaption.Caption;
end;

procedure TComboComponent.SetCaption( Value: String );
begin
    if (Value <> FCaption.Caption) then begin
        FCaption.Caption := Value;
        FCaption.Refresh;
    end;
end;

HTH!

Ken
--
kwh...@westelcom.com
qpwpla...@aol.com

Clipper Functions 3.0 for Delphi
Demos at http://members.aol.com/qpwplatts/cfdemo.htm

Quote
Jesper Lauridsen wrote:

> How do I best encapsulate two or more Delphi components (e.g. a TLabel and
> a TEdit), in one component, so that I only have to call one create method,
> but assign values to both components.

> Mvh / Best regards
>   Jesper Lauridsen
>   E-mail: j...@post1.tele.dk
>   Homepage: http://home1.inet.tele.dk/jel/index.html

Re:Best way to encapsulate two Dephi components?


Quote
Ken White <kwh...@westelcom.com> wrote:
>constructor TComboComponent.Create(AOwner: TComponent);
>begin
>    inherited Create(AOwner);
>    FCaption := TLabel.Create(Self);
>    FEdit := TEdit.Create(Self);
>end;

Bad boy! Bad, bad boy! I know that your example was FTOYH, but you
forgot to set the Parent properties:

constructor TComboComponent.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCaption := TLabel.Create(Self);
  FCaption.Parent := self;
  FEdit := TEdit.Create(Self);
  FEdit.Parent := self;
end;

and... it is not necessary to destroy owned components explicit.
TObject.Destroy does that for you.

Destructor TComboComponent.Destroy;
begin
  { Don't have to free the child components first }
  inherited Destroy;
end;

Share and Enjoy!

+--------------------from usenet----------------------+
|  Anders Bo Melander    | Phone: (+45) 31 87 91 26   |
|  Finsensvej 79, 2. tv. | mailto:a...@biocat.ruc.dk  |
|  DK-2000 Frederiksberg | work: a...@lrsoftware.dk    |
|  Denmark               | flameto:bi...@microsoft.com|
+------------------------+----------------------------+
| http://ftp.frontier.dk/public/Delphi2/tbedit01.html |
+-----------------------------------------------------+

Re:Best way to encapsulate two Dephi components?


Good point, Anders!

That'll teach me to respond to NG questions after pulling a
couple of all-nighters at the office! :-)

Ken
--
kwh...@westelcom.com
qpwpla...@aol.com

Clipper Functions 3.0 for Delphi
Demos at http://members.aol.com/qpwplatts/cfdemo.htm

Quote
> Bad boy! Bad, bad boy! I know that your example was FTOYH, but you
> forgot to set the Parent properties:

Re:Best way to encapsulate two Dephi components?


On 26 Feb 1997 01:27:09 -0700, ben...@primenet.com (Benson Trinh)
wrote:

Quote
>What would be the best ways to override event handlers for the
>contained components, i.e. the label and the Edit component?  I think
>that deriving components from Label and Edit and then including those
>in your component.  But what about assigning event handlers in the
>constructor:

>constructor TComboComponent.Create(AOwner: TComponent);
>begin
>    inherited Create(AOwner);
>    FCaption := TLabel.Create(Self);
>    FEdit := TEdit.Create(Self);

>   // New event handlers here:
>   FEdit.OnKeyDown := newOnKeyDown;
>end;

>procedure TComboComponent.newOnKeyDown(xxxxxxxxxxxxxxx);
>begin
>   //an event handler for Edit's on key down goes here?

>   inherited;

^^^^^^^^^^^

[snip]

You can't call inherited on the edit control, because you didn't
inherit it (it's a field). But you can raise a corresponding event in
your TComboComponent. Something like DoOnEditKeyDown, and declare your
OnEditKeyDown event, and the same for the label component.

PS

Re:Best way to encapsulate two Dephi components?


Quote
ben...@primenet.com (Benson Trinh) wrote:
>What would be the best ways to override event handlers for the
>contained components, i.e. the label and the Edit component?  I think
>that deriving components from Label and Edit and then including those
>in your component.  But what about assigning event handlers in the
>constructor:

Depending on what you are trying to do you are likely better off using
TWinControl or TGraphicControl as the base class rather than a TPanel
(or even use TCustomPanel).  To add an event handler to any component
just "publish" the property, to add additional processing to the event
override the protected event handler I.E.

TComboComponent = class(TWinControl)
private
    FEdit: TEdit;
    FLabel: TLabel;
    ...
protected
    procedure KeyDown(var Key: Word; Shift: TShiftState);
    procedure KeyUp(var Key: Word; Shift: TShiftState);
    ...
published
    // redeclaring these properties as published doesn't
    // override them, simply makes them available
    property OnKeyDown;
    property OnKeyUp;
    ...
end;

I find the using TWinControl or TGraphicsControl (or even one of the
TCustomXXXX) classes a better base class as it gives you more control
over what properties and events are available in the Object inspector.
One further note.  It is the KeyXXX procedures that tests to see if
the OnKeyXXX properties have been assigned.  That means if you don't
call the inherited KeyXXX functions you will need to handle those
properties yourself.  I.E.

TComboComponent = class(TWinControl)
private
    FOnKeyDown: TKeyDownEvent;
    ...
protected
    procedure KeyDown(var Key: Word; Shift: TShiftState);
    ...
published
    property OnKeyDown read FOnKeyDown write FOnKeyDown;
    ...
end;

procedure TComboComponent.KeyDown(var Key: Word; Shift: TShiftState);
begin
  ...   // do your stuff here
  if Assigned(FOnKeyDown) then FOnKeyDown(Self, Key, Shift);
end;

Hope this helps
Keith

Other Threads