Component Development: Picking a base class

VCL, FMX or any component library contains hundreds of classes. That sometimes makes it very hard to find a class to derive from.

The first question you have to ask yourself:

Do you write a completely new control or do you need a custom variant of a component that is already there?

If you just want to customize some aspects of a control, simply derive from that control. E.g. I often derive from components that can be found in the toolbox to set up my own default values. TAdvStringgrid  is a perfect example. The company chose no doubt default values that suit the customer base best, but sometimes I just want a different starting point. Thus, I created a new component TFlxAdvStringgrid  with my own default values.
If you really need to start writing your own component, use this step-by-step list to determine the ancestor:

Is it a graphical component?

Anything that draws itself on a canvas on the form is considered graphical. If your component is not graphical it is being represented by a 16×16 pixel rectangle in the form designer. If you do not develop a graphical component, then you simply derive from TComponent.

Do you need a HWND?

This question is the most tricky to answer if you get started. Everything that gets focus in Windows or may accept keyboard input needs its own “handle”. In Windows terminology called a Window Handle, in the Windows API referred to as a HWND . It even is a datatype in the Windows API which maps to an integer data type.

Do not make the mistake to set the requirement for a window handle equal to user-interaction. That is definitely wrong, as OnClick  and OnDblClick  are also “user-interaction” and these are available for components without an HWND .

If you do not need an handle, you may select TGraphicComponent  as your base class.

If you do need an handle, there is one more selection to make.

Custom Painting

If you need custom painting, select TCustomControl . If not, select TWinControl .

Let’s look at TCustomControl in detail:

TCustomControl = class(TWinControl)
    FCanvas: TCanvas;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure Paint; virtual;
    procedure PaintWindow(DC: HDC); override;
    property Canvas: TCanvas read FCanvas;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

We see right away that it derives from TWinControl  and adds only one method and one property. Basically, the canvas allows you to perform your draw operations more easily by overriding the Paint  method. This all would be able to do with TWinControl  as well, but the VCL offers a bit more comfort using TCustomControl .

As I am a person that can only remember these things if it has a sketch or chart of some sort, I created the following (small) mind map to select the base component. The full resolution image is available if you click it.

How to select the Base Component Class

Tags: , , , , ,