Comment créer et installer un composant grâce à un paquet avec Lazarus

Tout en images

Gilles Vasseur

Comme je participe activement à la traduction de Lazarus, j'ai profité de celle en cours concernant la création et l'installation de paquets pour rédiger un tutoriel assez complet. Il propose entre autres la création d'un composant TGVUrlLabel, ce qui pourrait intéresser quelques apprentis programmeurs ayant dépassé le niveau de la découverte.

Commentez

- Titre : Comment créer et installer un composant grâce à un paquet avec Lazarus

- Auteur : Gilles Vasseur

- Parution : 21 mars 2015

- Public visé :

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2015 Gilles Vasseur. 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

- Public visé

- Objectif du tutoriel

- Définitions

- La création d'un paquet

- La création d'un composant pour le paquet : TGVUrlLabel

- Le composant TGVUrlLabel

- L'installation du paquet

- L'exploitation du composant créé

- Conclusion

- Téléchargement

Public visé

Ce tutoriel s'adresse aux programmeurs confirmés en programmation Pascal avec l'EDI Lazarus.

Objectif du tutoriel

Il s'agit d'étendre les possibilités de l'EDI Lazarus en créant et installant un paquet et les composants qu'il comprend. L'apprentissage se fera pas à pas et intégrera la création d'un composant réellement utilisable : TGVUrlLabel. Ce nouveau composant est un descendant de TLabel muni d'une aptitude à lancer le navigateur par défaut pour afficher une page spécifique d'Internet.

Les programmes fournis ont été testés avec les versions 1.2.6 et 1.4RC2 de Lazarus sur Windows 8.1 et Linux Mint 17.1. Ils devraient fonctionner avec toute version antérieure.

Définitions

Un composant est une classe qui descend de la classe TComponent qui peut être installée dans la palette de l'EDI Lazarus. Grâce à la gestion des flux, les propriétés de cette classe peuvent être sauvegardées et récupérées.

Un paquet est une « collection d'unités et de composants, contenant de l'information sur comment ils peuvent être compilés et comment ils peuvent être employés par des projets ou d'autres paquets ou l'EDI [Lazarus lui-même] » (http://wiki.freepascal.org/Lazarus_Packages).

La création d'un paquet

Afin de créer un paquet, choisissez tout d'abord l'option « Nouveau paquet… » du menu « Paquet » :

Lazarus vous demande immédiatement le nom du paquet que vous comptez créer. Par défaut, il propose le nom de fichier « NouveauPaquet.lpk » qu'il est conseillé de modifier pour rendre plus parlante son utilisation future :

Votre travail consiste à créer un paquet comprenant l'ensemble des productions de la société GVSoft. Changez donc le nom par défaut en tapant « gvsoft.lpk » avant de cliquer sur le bouton « Enregistrer » :

Lazarus active une nouvelle fenêtre dont la barre de titre contient le nom du paquet nouvellement créé :

Le paquet ne comprend pas de fichier, mais déjà un autre paquet nommé « FCL » qui sert de base de travail.

Afin d'ajouter des fichiers à ce paquet, il suffit de cliquer sur le bouton marqué « + Ajouter » :

La création d'un composant pour le paquet : TGVUrlLabel

Dans la fenêtre qui s'affiche, comme votre intention est de créer un composant, il faut activer l'onglet marqué « Nouveau composant » :

Vous remarquerez qu'il est tout à fait possible d'inclure de nouveaux fichiers dans le paquet ou encore d'ajouter des fichiers existants. L'onglet « Nouvelle condition » permet d'indiquer les conditions requises pour le paquet quant à la version minimale/maximale des autres paquets utilisés.

L'activation de l'onglet « Nouveau composant » produit l'affichage suivant :

Si vous vous étonnez de la mauvaise qualité (voire de l'absence !) de la traduction depuis l'anglais, rassurez-vous : elle est en cours d'élaboration.

Pour parfaire votre travail, remplissez les trois premières lignes d'édition (celles entourées de vert) selon le modèle suivant :

Le « type d'ancêtre » détermine sur quel composant déjà enregistré s'appuiera votre nouveau composant. Vous pouvez faire défiler le nom des composants disponibles afin d'en choisir un qui limitera d'ores et déjà votre travail si vous souhaitez en récupérer les propriétés et le comportement par héritage. Au minimum, pour un comportement sans lien avec un ancêtre connu, il faudrait choisir TComponent qui est l'ancêtre commun de n'importe quel composant.

Le « nom de classe » est tout simplement le nom du composant à créer. Comme il s'agit d'un type à définir, la tradition veut que ce nom commence par la lettre majuscule T.

La « page de palette » est le nom de la page où figurera ce nouveau composant. Afin de le repérer facilement, vous créez une nouvelle page « gvsoft », mais vous auriez pu décider de choisir une page déjà en cours d'utilisation en faisant défiler les éléments de la zone de liste modifiable.

Les éléments entourés de rouge sont générés automatiquement. À moins d'une bonne raison, il n'y a pas lieu de les modifier.

De manière optionnelle, il reste à choisir une image de type « PNG » dont le format doit être de 24x24 pixels. Cette image est celle qui s'affichera dans la palette de l'EDI Lazarus. Si vous ne la précisez pas, une icône par défaut sera fournie automatiquement.

Pour changer d'icône, cliquez sur le bouton en face du mot « icône » :

Après avoir choisi l'icône adaptée, cette dernière est affichée à la place du carré vide :

Vous pouvez à présent enregistrer vos choix en cliquant sur le bouton « Create New Component » (qui ne tardera pas à s'appeler « Créer le nouveau composant »!) :

Quasi immédiatement, Lazarus ouvre une fenêtre de l'éditeur qui contient le squelette du nouveau composant :

L'unité porte le nom généré automatiquement [1].

Le squelette de la classe TGVUrlLabel apparaît bien dans la partie interface de l'unité [2]. La seule section qui n'est pas nécessaire en général, mais qui revêt toute son importance lorsqu'on crée un composant, est celle des déclarations publiées (« published declarations »). Il s'agit des propriétés qui figureront dans l'éditeur de propriétés et que vous pourrez modifier pendant la conception.

Plus intéressante, la procédure Register est déclarée [3] puis définie [4] : c'est elle qui associe l'icône choisie au composant grâce au chargement d'un fichier ressource créé lui aussi automatiquement à partir de l'icône déterminée à l'étape précédente, puis qui procède à l'enregistrement du composant dans la bonne page de la palette des composants.

Bravo : votre composant est prêt à être intégré à l'EDI Lazarus ! Cependant, comme il ne fait que descendre du composant TLabel, il se comporterait tout comme lui, ce qui, vous en conviendrez, ne présente pas beaucoup d'intérêt ! À présent, votre travail va consister à apporter à ce squelette la chair dont il a besoin, c'est-à-dire les fonctionnalités que vous voulez ajouter à une simple étiquette bien connue.

Si vous êtes curieux, vous observerez que le répertoire de travail concernant ce projet contient alors, outre un sous-répertoire « backup » qui contient les versions précédentes des fichiers, le fichier « gvsoft.lpk » qui décrit le paquet, le fichier « gvurllabel.pas » qui contient le source vu ci-avant et un fichier « gvurllabel-icon.lrs » qui contient la ressource nécessaire à la gestion de l'icône :

Le composant TGVUrlLabel

Dans la partie interface de l'unité, complétez comme suit la définition de la nouvelle classe TGVUrlLabel :

TGVURLLabel

uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

{ TGVUrlLabel }

TGVUrlLabel = class(TLabel)
private
fURLHint: Boolean; // lien dans l'aide ?
procedure SetURLHint(AValue: Boolean); // changement de type de lien
protected
// entrée de la souris dans le champ du composant
procedure MouseEnter; override;
// sortie de la souris du champ du composant
procedure MouseLeave; override;
// clic sur le composant
procedure Click; override;
public
// création du composant
constructor Create(TheOwner: TComponent); override;
published
// URL dans l'aide contextuelle ?
property URLHint: Boolean read fURLHint write SetURLHint default True;
end;

Le composant s'appuie sur le clic de la souris pour l'affichage de la page Web désirée : on redéfinit par conséquent la procédure virtuelle Click. L'adresse de la page Web est contenue soit dans la propriété Hint (bulle d'aide) soit dans la propriété Caption (légende), suivant la valeur de la nouvelle propriété booléenne URLHint. Par défaut, l'adresse est dans la propriété Hint.

Enfin, on surcharge les procédures virtuelles MouseEnter (le curseur de la souris pénètre dans la zone d'affichage du composant) et MouseLeave (le curseur sort de cette même zone). La surcharge de ces procédures qui traitent les deux événements permet de rendre l'affichage plus agréable  : si la légende contient directement l'adresse, le texte sera écrit en bleu par défaut et deviendra rouge et souligné lorsque le curseur modifié en doigt pointé le survolera. Quand ce dernier quittera cette zone, l'affichage sera rétabli dans son état initial.

Pour générer de manière automatique le squelette du code source des méthodes, utilisez la combinaison de touches Ctrl-Maj-C. Cette façon de procéder évite les erreurs de frappe et économise beaucoup de temps.

Vous devriez voir apparaître les squelettes de méthodes suivantes dans la partie implémentation de l'unité :

Comme vous allez utiliser une procédure qui concerne les URL, ajoutez sous le mot implementation la clause uses suivante :

L'unité LCLIntf est à présent intégrée à votre projet.

La méthode SetURLHint permet de basculer entre l'affichage via la propriété Hint et celui via Caption :

SetURLHint

procedure TGVUrlLabel.SetURLHint(AValue: Boolean);
// *** changement de l'emplacement du lien ***
begin
if fURLHint = AValue then // même valeur ?
Exit; // on sort
fURLHint := AValue; // nouvelle valeur affectée
if not fURLHint then // pas dans l'aide contextuelle ?
Font.Color := clBlue // couleur bleue pour la police
else
Font.Color := clDefault;  // couleur par défaut pour la police
end;

En dehors de modifier si nécessaire la valeur booléenne du champ privé fURLHint, cette méthode adapte la couleur d'écriture afin qu'elle soit prise en compte immédiatement.

Quant à la méthode MouseEnter, elle ressemble à ceci :

MouseEnter

procedure TGVUrlLabel.MouseEnter;
// *** la souris entre dans la surface de l'étiquette ***
begin
inherited MouseEnter; // on hérite
if not URLHint then // lien dans l'étiquette ?
begin
Font.Color := clRed; // couleur rouge pour la police
Font.Style := Font.Style + [fsUnderline]; // on souligne le lien
Cursor := crHandPoint; // le curseur est un doigt qui pointe
end;
end;

On ne doit pas oublier d'hériter de son comportement défini par l'ancêtre TLabel. La seule modification apportée concerne l'affichage au cas où la légende contiendrait l'adresse Web à atteindre.

La méthode MouseLeave est le pendant de sa consœur MouseEnter :

MouseLeave

procedure TGVUrlLabel.MouseLeave;
// *** la souris sort de la surface de l'étiquette ***
begin
inherited MouseLeave; // on hérite
if not URLHint then // lien dans l'étiquette ?
begin
Font.Color := clBlue; // couleur bleue pour la police
Font.Style := Font.Style - [fsUnderline]; // on ne souligne plus le lien
Cursor := crDefault; // le curseur est celui par défaut
end;
end;

Elle hérite elle aussi de son ancêtre avant de rétablir si besoin les données concernant l'affichage.

La méthode Click est au cœur du nouveau travail qu'effectuera le composant TGVUrlLabel.

Après avoir hérité son comportement de son ancêtre, elle déclenche l'affichage de la page Web indiquée en fonction de la valeur de la propriété URLHint :

Click

procedure TGVUrlLabel.Click;
// *** clic sur l'étiquette ***
begin
inherited Click; // on hérite
if URLHint then // dans l'aide contextuelle ?
OpenURL(Hint) // envoi vers le navigateur par défaut
else
OpenURL(Caption); // sinon envoi du texte de l'étiquette
end;

La procédure OpenURL est contenue dans l'unité LCLIntf. Elle attend en paramètre une chaîne qui contient l'adresse visée.

Enfin, il reste à compléter la méthode Create :

Create

constructor TGVUrlLabel.Create(TheOwner: TComponent);
// *** construction du composant ***
begin
inherited Create(TheOwner); // on hérite
fURLHint := True; // URL dans l'aide contextuelle par défaut
end;

Après un héritage similaire à ceux déjà décrits, elle définit le champ fURLHint à True, conformément à la déclaration faite lors de la définition de la classe.

Encore bravo : l'écriture du code source de votre composant est terminée !

Afin de ne pas perdre ce chef d'œuvre, pensez à l'enregistrer en cliquant sur l'icône appropriée :

L'astérisque en face du nom de l'unité (en rouge) indique que le fichier n'a pas été enregistré.

Cliquez par conséquent sur l'icône représentant une disquette (en vert).

N.B. : Pour les plus jeunes : je vous assure que cet objet préhistorique a bel et bien existé !

L'installation du paquet

Votre composant serait utilisable en l'état. Il suffirait d'en créer une instance comme vous le feriez d'une TStringList, par exemple. Bien entendu, vous n'oublieriez pas de libérer cette instance à la fin de votre travail afin d'éviter les fuites de mémoire : la méthode Free serait parfaitement utilisable puisque héritée de l'ancêtre TLabel. Cette utilisation est souvent indiquée afin de tester les composants avant de les intégrer à l'EDI.

Votre propos étant cependant d'intégrer ce composant à la palette des composants déjà disponibles, il vous faut procéder à l'installation du paquet avec ses composants (en l'occurrence, le vôtre n'en contient qu'un, mais peu importe).

Cliquez sur l'option « Installer/Désinstaller des paquets… » du menu « Paquet » :

Dans la fenêtre qui s'ouvre, dans la colonne de droite, vous devriez trouver votre paquet en attente d'être installé :

Après avoir, si besoin, fait défiler la liste des paquets en attente jusqu'à sélectionner celui qui convient, cliquez sur « Installer la sélection ».

Le paquet « gvsoft » est alors déplacé vers la liste de gauche, celle des paquets installés :

Cliquez sur « Enregistrer et recréer l'EDI ».

Lazarus demande confirmation des changements que vous voulez apporter à l'EDI lui- même :

Cliquez simplement sur le bouton « Continuer » afin de valider votre choix.

L'EDI Lazarus est reconstruit devant vos yeux ébahis. Après une courte disparition, l'écran de départ réapparaît, apparemment sans changement…

Avant de vérifier que tel n'est pas le cas, il faut noter que Lazarus ne sait pas, contrairement à Delphi, intégrer les nouveaux paquets de manière dynamique. C'est par conséquent tout l'EDI qui doit être recompilé, ce qui est heureusement une affaire d'une poignée de secondes.

Un changement minime a bien eu lieu pour qui est attentif à la palette des composants :

La palette comprend à présent un onglet GVSoft.

En cliquant sur cet onglet, vous découvrez que votre composant est intégré à l'EDI :

Une ultime fois bravo : vous avez créé et installé un paquet comprenant un nouveau composant !

L'exploitation du composant créé

Pour tester ce composant, créez une nouvelle application et ajoutez à la fiche par défaut une instance de TGVUrlLabel :

Aussitôt, vous obtenez ce qui paraît être une instance de TLabel. Le type indiqué par l'inspecteur d'objets ne trompe néanmoins pas : il s'agit bien d'une instance de votre composant.

Un coup d'œil aux propriétés modifiables dans l'inspecteur d'objets montre que la propriété publiée URLHint est bien accessible :

Il ne reste qu'à s'amuser un peu pour examiner le comportement du composant suivant la valeur de cette unique propriété ajoutée. C'est ce que se propose de faire le petit programme de test fourni avec le tutoriel :

Conclusion

Vous avez appris à créer un paquet, à lui adjoindre un composant lui-même créé par vos soins, et à l'installer sur la palette des composants.

Votre apprentissage n'est évidemment pas terminé. Si ce tutoriel a intéressé certains d'entre vous, il sera complété par des réalisations plus complexes et par d'autres considérations (réglage des options essentielles, mise à jour et suppression d'un paquet…).

A vous de jouer ! Vous pouvez prolonger ce travail en améliorant le composant :

* Autoriser ou non le soulignement lorsque le texte du composant est survolé ;

* Colorer ou non le texte lors de l'activation du lien ;

* Définir la couleur à utiliser lorsque le curseur de la souris entre dans le champ du composant.

N'hésitez pas à commenter ce travail, à l'améliorer, à le développer. Et pendant que j'y suis, un grand merci à Alcatîz pour son accueil et son travail, et à ClaudeLeloup pour la relecture et les corrections !

Téléchargement

Téléchargez le paquet TGVUrlLabel.