7.4. Créer un nouvel événement
( texte extrait et composé à partirdu manuel guide du développeur Delphi, Borland Ó)



Plan du chapitre:

1. Annexe : éléments de construction proposés par Borland
 

1.1 Définition de vos propres événements
1.2 Déclenchement de l’événement
1.3 Deux sortes d’événements
1.4 Définition du type de gestionnaire
1.5 Notifications simples
1.6 Gestionnaires d’événements spécifiques
1.7 Renvoi d’informations à partir du gestionnaire
1.8 Déclaration de l’événement
1.9 Les noms d’événement débutent par “On”
1.10 Appel de l’événement
1.11 Les gestionnaires vides doivent être valides
1.12 Les utilisateurs peuvent surcharger la gestion par défaut
 
2. Exemple de création d'événements dans un TEdit
 
2.1 Evènement OnColorChange
2.2 Evènement OnResize




 

1. Annexe : éléments de construction proposés par Borland
 
 

1.1 Définition de vos propres événements

Il est relativement rare de définir des événements entièrement nouveaux. Toutefois, il peut arriver qu’un comportement complètement différent soit introduit par un composant et il faut alors lui définir un événement.

Voici les étapes qui interviennent dans la définition d’un événement :

• Déclenchement de l’événement
• Définition du type de gestionnaire
• Déclaration de l’événement
• Appel de l’événement
 
 
 

1.2 Déclenchement de l’événement

Vous avez besoin de savoir ce qui a déclenché l’événement. Pour certains événements, la réponse est évidente. Par exemple, un événement associé à l’enfoncement du bouton de souris se produit lorsque l’utilisateur clique avec le bouton gauche de la souris provoquant l’envoi par Windows d’un message WM_LBUTTONDOWN à l’application. La réception de ce message provoque l’appel de la méthode MouseDown d’un composant qui à son tour appelle le code que l’utilisateur a associé à l’événement OnMouseDown. Néanmoins, certains événements sont liés de façon moins évidente à des occurrences externes moins spécifiques. Par exemple, une barre de défilement dispose d’un événement OnChange qui peut être déclenché par plusieurs occurrences, telles des frappes de touche, des clics de souris, ou des modifications dans d’autres contrôles. Lorsque vous définissez vos événements, assurez-vous que les occurrences appellent tous les événements appropriés.
 
 
 

1.3 Deux sortes d’événements

Les deux sortes d’occurrences pour lesquelles vous pouvez être amené à définir des événements sont les interactions utilisateur et les modifications d’état. Les événements de type interaction utilisateur sont pratiquement toujours déclenchés par un message issu de Windows indiquant que l’utilisateur a agi sur votre composant d’une façon qui peut nécessiter une réponse de votre part. Les événements de modification d’état peuvent aussi être le fait de messages issus de Windows (par exemple, des changements de focalisation ou d’activation). Cependant, ils peuvent également survenir à la suite d’une modification de propriété ou de l’exécution d’une autre partie de code. Vous disposez d’un contrôle total sur le déclenchement des événements que vous avez vous-même définis. Définissez les événements avec soin de sorte que les développeurs soient capables de les comprendre et de les utiliser.
 
 

1.4 Définition du type de gestionnaire

Après avoir détecté que l’un de vos événements s’est produit, vous devez définir la façon de le gérer. Cela implique que vous devez déterminer le type du gestionnaire d’événement. Dans la plupart des cas, les gestionnaires d’événements que vous définissez vous-même seront des notifications simples ou spécifiques à des événements particuliers. Il est également possible de récupérer de l’information en provenance du gestionnaire.
 
 

1.5 Notifications simples

Un événement de type notification ne fait qu’indiquer qu’un événement particulier s’est produit sans fournir aucune information sur le moment et l’endroit où il s’est produit. Les notifications utilisent le type TNotifyEvent, qui véhiculent un paramètre unique correspondant à l’émetteur de l’événement. Les seuls éléments “connus” du gestionnaire associé à une notification sont donc le type d’événement et le composant impliqué. Par exemple, les événements clic de souris sont des notifications. Lorsque vous écrivez un gestionnaire pour un événement de ce type, vous ne récupérez que deux informations : le fait qu’un clic s’est produit et le composant impliqué. Une notification est un processus à sens unique. Il n’existe aucun mécanisme pour renvoyer une information en retour ou pour inhiber la gestion d’une notification.
 
 

1.6 Gestionnaires d’événements spécifiques

Dans certains cas, savoir qu’un événement s’est produit et connaître le composant impliqué n’est pas suffisant. Par exemple, si l’événement correspond à l’enfoncement d’une touche, le gestionnaire voudra savoir quelle est cette touche. Dans un cas comme celui-là, vous devez disposer d’un gestionnaire qui accepte des paramètres pour ces informations supplémentaires.
Si votre événement a été généré en réponse à un message, les paramètres transmis au gestionnaire d’événement seront vraisemblablement issus des paramètres du message.
 
 

1.7 Renvoi d’informations à partir du gestionnaire

Comme tous les gestionnaires d’événements sont des procédures, la seule façon de renvoyer des informations à partir d’un gestionnaire consiste à faire appel à un paramètre var. Vos composants peuvent utiliser les informations ainsi récupérées pour déterminer le traitement éventuel d’un événement après l’exécution du gestionnaire de l’utilisateur. Par exemple, tous les événements liés aux touches (OnKeyDown, OnKeyUp et OnKeyPress) transmettent par référence la valeur de la touche enfoncée dans un paramètre intitulé Key. Le gestionnaire d’événement peut changer Key de façon à donner l’impression à l’application qu’une touche différente est impliquée dans l’événement. Cela permet par exemple de forcer en majuscules les caractères tapés.
 
 

1.8 Déclaration de l’événement

Une fois déterminé le type de votre gestionnaire d’événement, vous pouvez déclarer le pointeur de méthode et la propriété pour l’événement. N’oubliez pas d’attribuer un nom à l’événement qui soit à la fois significatif et descriptif pour que l’utilisateur puisse comprendre son rôle. Dans la mesure du possible, choisissez des noms de propriétés qui ressemblent à ceux de composants déjà définis.
 
 

1.9 Les noms d’événement débutent par “On”

Dans Delphi, les noms de la plupart des événements commencent par “On”. Il s’agit d’une simple convention ; le compilateur n’impose pas cette restriction. L’inspecteur d’objets détermine qu’une propriété est un événement en examinant le type de la propriété : toutes les propriétés de type pointeur de méthode sont interprétées comme des événements et apparaissent donc dans la page Evénements. Les développeurs s’attendent à trouver les événements dans la liste alphabétique à l’endroit des noms commençant par “On.” Vous risquez d’introduire une certaine confusion en utilisant une autre convention.
 
 

1.10 Appel de l’événement

Il est préférable de centraliser tous les appels à un événement. Autrement dit, créez une méthode virtuelle dans votre composant qui appelle le gestionnaire d’événement de l’application (s’il a été défini) et qui fournit une gestion par défaut.
Le fait de rassembler tous les appels à un événement en un seul endroit vous permet d’être sûr qu’un programmeur, qui dérive un nouveau composant à partir du vôtre, pourra personnaliser la gestion de l’événement en surchargeant cette méthode sans avoir à parcourir votre code pour repérer les endroits où l’événement est appelé.

Deux autres considérations sont à prendre en compte concernant l’appel de l’événement :
• Les gestionnaires vides doivent être valides.
• Les utilisateurs peuvent surcharger la gestion par défaut.
 
 

1.11 Les gestionnaires vides doivent être valides

Vous ne devez jamais créer une situation dans laquelle un gestionnaire d’événement vide provoque une erreur, ou dans laquelle le bon fonctionnement d’un composant dépend d’une réponse spécifique provenant du code de gestion d’un événement dans l’application. Un gestionnaire vide doit produire le même effet qu’un gestionnaire absent. Aussi, le code pour appeler le gestionnaire d’événement dans une application doit ressembler à ceci :
 
 
if Assigned(OnClick) then OnClick(Self);
... { exécute la gestion par défaut}

Il ne doit en aucun cas ressembler à ceci :
 
if Assigned(OnClick) then OnClick(Self)
else{ exécute la gestion par défaut};

En effet dans la partie associée au else, il se pourrait que la gestion par défaut s'exécute avec une référence OnClick = nil, ce qui engendrerait des possibilités d'erreurs.

 

1.12 Les utilisateurs peuvent surcharger la gestion par défaut

Pour certains types d’événements, les développeurs peuvent vouloir remplacer la gestion par défaut ou même supprimer l’ensemble des réponses. Pour permettre cela, vous devez transmettre au gestionnaire un argument par référence et vérifier si le gestionnaire renvoie une certaine valeur. Cela reste dans la lignée de l’affirmation qu’un gestionnaire vide doit produire le même effet qu’un gestionnaire absent : puisqu’un gestionnaire vide ne modifie en rien la valeur des arguments passés par référence, la gestion par défaut se déroule toujours après l’appel du gestionnaire vide.

Par exemple, lors de la gestion des événements frappe de touches, le développeur d’applications peut omettre la gestion par défaut de la frappe de touches du composant en attribuant le caractère null (#0) au paramètre var Key.

La logique de programmation sous-jacente est la suivante :
 
if Assigned(OnKeyPress) then OnKeyPress(Self, Key);
if Key <> #0 then ... { exécute la gestion par défaut}

Le code réel est légèrement différent car il prend également en compte les messages Windows mais la logique reste la même. Par défaut, le composant appelle le gestionnaire défini par l’utilisateur avant d’exécuter la gestion standard. Si le gestionnaire défini par l’utilisateur attribue le caractère null à Key, le composant omet l’exécution de la gestion par défaut.
 
 

2. Exemple de création de deux nouveaux événements dans un TEdit

Mise en oeuvre sur l'adjonction de 2 évènements nouveaux à un composant déjà existant.

Enoncé