Creating a new component by combining two controls (TEdit and TTrackBar) in Delphi VCL

Is the creation of a new component the best strategy for the multiple use of such a slider input?

Not necessarily true all the time. (by my standards at least).

What is the best way to create such a new component?

I know three ways to solve your problem.

Way number 1:

create the component using the new component wizard where you create dynamically the TEdit and the TTrackBar sub components in a TGroupBox descendant.

the following is how I would do that.

unit Combindedittrack;

interface

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

type
  TCombindEditTrack = class(TGroupBox)
  private
    { Private declarations }
    FEdit: TEdit;
    FTrackBar: TTrackBar;
    procedure EditOnChangeProc(Sender: TObject);
    procedure TrackBaroOnChangeProc(Sender: TObject);
  protected
    { Protected declarations }

  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TCombindEditTrack]);
end;

constructor TCombindEditTrack.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  SetBounds(0, 0, 250, 50);
  FEdit := TEdit.Create(Self);
  with FEdit do
  begin
    Text := ''; //<-- you control the appearence here
    Top := 10;
    Left := 10;
    Height := 27;
    Width := 50;
    Parent := Self;
    OnChange := EditOnChangeProc; // your Onchange event handler for the Tedit
  end;

  FTrackBar := TTrackBar.Create(self);
  with FTrackBar do
  begin
    Top := 10; //<-- you control the appearence here
    Left := 60;
    Height := 30;
    Width := 50;
    Parent := self;
    Onchange := TrackBaroOnChangeProc; // your Onchange event handler for the Ttrackbar
  end;
end;

destructor TCombindEditTrack.Destroy;
begin
  FTrackBar.Free;
  FEdit.Free;
  inherited;
end;

procedure TCombindEditTrack.TrackBaroOnChangeProc(Sender: TObject);
begin
  // <-- track bar onchange handling here.
end;

procedure TCombindEditTrack.EditOnChangeProc(Sender: TObject);
begin
  // <-- edit onchange handling here.
end;

end.

Way number 2:

Use frames like this (I'm on delphi 10 seattle).

  1. File-->New-->Other-->(search for frames on delphi files).

  2. Now add the edit and the track bar and set their Onchange events.

  3. Save the unit.

  4. on the tool palette (the standard component section) click on the frame component.

  5. choose the frame you just created.

You will have a replica of the frame each time you use it.

Way number 3:

Use component template like this (again I'm on delphi 10 seattle)

  1. Select your already created and modified tedit and ttrackbar.

  2. On the toolbar's "component" click "create component template".

  3. Name your template and press OK.

  4. Select the Template palette and then your template.

Now notice that even your code (events) are added as well to your project.

Finally

With the level I have on delphi and the IDE I'm really unable to give you a clear answer to which is the best way but nevertheless I have shared all what I know that could help you.


edit: Since a lot of comments are insisting that the answer should state which is the best way to do this. this is the best way based on the following.

let's put some of the key point that should be accounted for when choosing

1. Ease of modifying the combined control(s) if you wish so (by my experience you will).

2. time needed to complete this task (it means the time it will take you to fully complete the task with minimum debugging and coding).

3. general source code readability.

4. usefulness for the future of your projects.

Now lets start criticizing the three methods based on the those criteria.

Way number 1:

C1(criteria number 1): Just modify the the source implementation of the component and each replica/use will have the same effects and properties. However this is not the case for way number 3.

C2: It depends on your knowledge of component writing but for this component it took me 5 min to create it and I'm only a beginner in delphi. For the debugging if something went wrong and the problem is in the component implementation than you just need to fix once (see C1)

C3: their is no implementation in your form(s) source code for your component just add it to your form and every thing is hidden (for example add a tedit and go to see the implementation in your forms source).

C4: You are creating a component after all this will open the door for you to create your own set of components like the Flatstyle or Indy open source components. so next time you need some thing like this you just drop it in your form designer and you are done.

Way number 2: frames

C1: It is like way number 1 because you are creating a component but it is visually this time. modifying the source frame will change the effects and properties of the replicas, also you can add extra handling to your replicas.

the event handler of the replica's Onchange event is like this

procedure TForm1.Frame2Edit1Change(Sender: TObject);
begin
  Frame2.Edit1Change(Sender); //<-- this is the original onchange event you setup at the beginning 
  //<-- you can extra handling here if you want one of the replicas to behave differently than the original  
end;

C2: same time and maybe faster than way number 1.

C3: over all, it has the same out come as way number 1.

C4: unlike way number 1 you can not use frames created in project A in project B. So your coding and debugging will stay in project A.

Way number 3: component template.

C1: you are not creating a component you are creating a repleca/macro of the exact steps you did in your last project. changing one will not change the others they are separated.

C2: same time and maybe faster than way number 1.

C3: each time you add a template to your form the events code will be added (not a good view if it is a long Onchange code).

C4: You can use templates created in project A in project B. However what you wrote in project A will be in project B (see c1) even the references of variables that don't exist in project B (this can be hard to debug and misleading, considering the period of time between each use of the template).

Conclusion: each of the ways presented will consume time to code and debug and all of them will do the task, How ever for the sake of simplicity and the reuse with minimum risks Way number 1 is the safe choice here because it will give you the chance to update and upgrade safely. also debug faster.

the good thing also about way number 1 is that after a while when you will forget the implementation and how things are working internally. The only thing that should stay in mind is the purpose of the component because it will become one of the various component you use (you don't know how Tedit is implemented and you don't need to but yet you use it in every single project you create).

based on the criteria given Way number 1 is the best.


Maybe using a container control that contains both controls is a simpler alternative. I am using ccpack for this.

https://sourceforge.net/projects/ccpack/

Custom Containers Pack (CCPack) is an integrated tool and component mini- library to produce and maintain composite controls (or simply “composites”) and other containers (forms, data modules and frames). The process of building composite components looks like ActiveForm and Frame creating, but the result is the native VCL component. You can create new composites just as usual forms.