Comment créer ses propres composants ?

Laurent Le Brun

Comment créer ses propres composants ? ♪

Ce tutoriel a pour ambition d'expliquer rapidement aux débutants comment réaliser ses propres composants. Il n'est pas exhaustif et vous pourrez sûrement trouver ailleurs des tutoriels plus complets sur ce sujet. Car mon but n'est pas de tout vous expliquer. D'ailleurs, je ne connais pas tout… loin de là. J'essaie seulement de montrer aux débutants les principes de la création de composants.
Tout au long du tutoriel, je prendrai l'exemple d'un composant tout simple qui améliore le TLabel. Vous pourrez appliquer les explications pour tout autre composant. Si vous débutez, je vous conseille d'essayer de réaliser par vous-même le composant. Vous trouverez à la fin de ce cours, le composant que j'ai fait. Si vous avez des problèmes pendant le tutoriel, je vous incite à le télécharger et à y jeter un coup d'œil.

- Titre : Comment créer ses propres composants ?

- Auteur : Laurent Le Brun

- Parution : 20 avril 2005

- Mise à jour : 20 avril 2005

- Licence : Copyright ® 2005 Laurent Le Brun. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. La « création » du composant

- II. Le codage du composant

I - La « création » du composant

Pour créer un composant, il faut aller dans « Composant » puis « Nouveau composant ». Une boîte de dialogue apparaît. Vous devez d'abord choisir le type ancêtre de votre composant. Il faut choisir la classe de base qui correspond le plus au type de composant à créer. Pour notre exemple, on va prendre la classe TCustomLabel.

Delphi contient plusieurs classes qui peuvent servir comme classe de base pour de nouveaux composants. Ces classes commencent par TCustom. Une classe TCustom contient les propriétés susceptibles d'être d'être utilisées dans une classe dérivée du composant correspondant. Mais, les propriétés ne sont pas publiées (c'est-à-dire, qu'elles n'apparaissent pas dans l'inspecteur d'objet). Cela vous permet donc de choisir les propriétés que vous souhaitez publier.

On utilise donc la classe TCustomLabel au lieu de TLabel. On change ensuite le nom de classe du composant à créer. Dans notre exemple, on choisira : TAdvancedLbl. Le champ « Page de palette » permet de spécifier l'endroit où votre composant apparaîtra, dans la palette. Là, je vous laisse le choix. Vous pouvez le mettre où vous voulez. Si vous créez beaucoup de composants, je vous conseille de tous les regrouper dans une même palette. Le fichier unité indique le nom du fichier où sera enregistré le code. Ce n'est pas la peine de le changer. Cliquez sur OK.

Le code source doit s'afficher. Vous trouvez dedans la procédure Register. Elle sert à recenser les composants, en leur indiquant leur nom et le nom de la page de la palette des composants. Normalement, vous n'avez pas à y toucher.

II - Le codage du composant

Il faut indiquer quelles sont les propriétés du TLabel que l'on va utiliser. Car, comme on a choisi le TCustomLabel, il nous faut trier les propriétés. Il faut les redéclarer dans la partie published. Cela nous donne :

published
{ Déclarations publiées }
property Align;
property Alignment;
property Anchors;
property AutoSize;
property BiDiMode;
property Caption;
property Color;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property FocusControl;
property Font;
property ParentBiDiMode;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowAccelChar;
property ShowHint;
property Transparent;
property Layout;
property Visible;
property WordWrap;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
end;

Bien sûr, ne vous embêtez pas à tout retaper. Il vous suffit d'aller voir le code source du TLabel et de faire un copier/coller des propriétés. Maintenant, notre composant est identique à un TLabel. Vous pouvez déjà le tester. Pour cela, enregistrez votre fichier. Allez dans « Composant » puis « Installer un composant ». Sélectionnez le fichier dans le champ « Nom d'unité » et validez. Le composant devrez être ajouté dans la palette des composants, à la page que vous aviez choisie au début. Ajoutez le composant sur un nouveau projet. Faites ce que vous voulez avec, modifiez ses propriétés, normalement, il doit réagir comme un TLabel. C'est déjà une première étape.

C'est déjà bien. Mais, il faut maintenant ajouter des fonctions, procédures et méthodes pour qu'il se distingue du TLabel. Pour cela, on va ajouter l'option de clignotement. La fréquence sera modifiable via l'inspecteur d'objet. On déclare les variables suivantes dans la partie private :

private
FFlashEnabled: Boolean; // s'il vaut True, le clignotement est activé
FFlashRate:    Integer; // période entre 2 clignotements, en millisecondes
Timer:         TTimer;  // Timer qui sert pour le clignotement

N'oubliez pas d'ajouter « ExtCtrls » dans la liste uses, car le Timer est défini dans le fichier « ExtCtrls.dcu » Ensuite, il faut déclarer les procédures qui seront appelées à chaque fois que la propriété changera :

protected
procedure SetFlashEnabled(AFlashEnabled: Boolean);
procedure SetFlashRate(AFlashRate: Integer);

Et enfin, on déclare les propriétés :

published
property FlashEnabled: Boolean read FFlashEnabled write SetFlashEnabled default True;
property FlashRate: Integer read FFlashRate write SetFlashRate default 800;

Petites explications : dans l'inspecteur d'objets, les propriétés porteront les noms respectifs FlashEnabled et FlashRate. Pour FlashEnabled, la valeur donnée sera de type booléen. La valeur affichée sera celle contenue dans la variable FFlashEnabled. Si cette valeur change (en mode conception (par l'inspecteur d'objets) ou pendant l'exécution du programme), la procédure SetFlashEnabled sera appelée, avec comme paramètre la nouvelle valeur. La valeur par défaut sera True.

Il nous reste à entrer le code correspondant :

procedure TAdvancedLbl.SetFlashEnabled(AFlashEnabled: Boolean);
begin
// On affiche la nouvelle valeur
FFlashEnabled := AFlashEnabled;
// On (dés)active le Timer
Timer.Enabled := FFlashEnabled;
end;

procedure TAdvancedLbl.SetFlashRate(AFlashRate: Integer);
begin
// On affiche la nouvelle valeur
FFlashRate := AFlashRate;
// On assigne au Timer le nouvel interval
Timer.Interval := AFlashRate;
end;

Il reste le plus important : le code du Timer qui fera clignoter notre TAdvancedLbl. Ajoutez donc ceci :

protected
procedure OnTimer(Sender: TObject); virtual;

{...}

procedure TAdvancedLbl.OnTimer(Sender: TObject);
begin
Visible := not Visible;
end;

N'essayez pas encore le composant, car il génèrera une erreur. En effet, il faut créer le Timer en mémoire. On le fera lors de la création du composant. Ajoutez :

constructor Create(AOwner: TComponent); override;

dans la partie public. Et copiez le code suivant :

constructor TAdvancedLbl.Create(AOwner: TComponent);
begin
inherited;
FFlashEnabled := True;
FFlashRate := 800;
Timer := TTimer.Create(Self);
Timer.Interval := FFlashRate;
Timer.OnTimer := OnTimer;
end;

On profite de la création du composant pour initialiser toutes les variables, ainsi que le Timer. Maintenant, vous pouvez tester le composant, en faisant varier les différents paramètres…

Astuce : Elle vous sera sûrement très utile si vous continuez à faire des composants : la propriété ComponentState. Elle permet de détecter si on est en mode conception ou pas. On l'utilise ainsi :

If csDesigning in ComponentState then {instructions}

Dans cet exemple, les instructions ne sont exécutées que si on est en mode conception.

Le composant doit maintenant être fonctionnel. Si vous avez des problèmes, vous pouvez le télécharger (ici). Il est un peu plus complet que l'exemple décrit, en ce sens qu'il possède une propriété supplémentaire : il a la faculté de pouvoir changer de couleur (aléatoirement) à chaque fois.

Si vous avez aimé ce cours, ou même si vous ne l'avez pas aimé, ce serait sympa de m'envoyer un mail… Merci !

Un mot d'encouragement ou un compliment fait toujours plaisir.