5 - Propriété de type enum :
Nous allons maintenant aborder les propriétés de type enum (énumérations),
propriétés couramment utilisées dans les composants C++ Builder.
L'avantage des propriétés de type enum est qu'elles ont des noms explicites
pour leurs valeurs, qui de plus sont limitées à une liste de constantes
symboliques. Autre avantage dans le cas d'une propriété, c'est que cette liste
s'affiche dans l'inspecteur d'objet pour la propriété en question.
Pour aborder ce type de propriété, nous allons prendre un exemple simple :
Nous allons construire un TAlignEdit composant descendant de TEdit qui aura
comme nouvelle propriété d'aligner son contenu à gauche, à droite ou centré.
Cette propriété ayant trois possibilités, le type enum lui convient donc
parfaitement. Pour parfaire notre exercice, nous ajouterons une deuxième
propriété de type enum qui aura comme caractéristique de pouvoir limiter la saisie
à des chiffres, à des chiffres plus le séparateur décimal plus le signe moins
ou pas de limitation.
Fichier "alignedit.h" :
#ifndef AlignEditH
#define AlignEditH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
//---------------------------------------------------------------------------
enum TAlignement {alGauche, alCentre, alDroite};
enum TNumerique {chNone, chInt, chFloat};
class PACKAGE TAlignEdit : public TEdit
{
private:
TAlignement FAlign;
TNumerique FNum;
protected:
DYNAMIC void __fastcall KeyPress(char &Key);
DYNAMIC void __fastcall DoEnter();
virtual void __fastcall SetAlign(TAlignement Value);
virtual void __fastcall SetNum(TNumerique Value);
void __fastcall CreateParams(TCreateParams &Params);
public:
__fastcall TAlignEdit(TComponent* Owner);
__published:
__property TAlignement Alignement = {read=FAlign, write=SetAlign, nodefault};
__property TNumerique Chiffres = {read=FNum, write=SetNum, nodefault};
};
//---------------------------------------------------------------------------
#endif
Dans le fichier entête "alignedit.h" nous déclarons nos deux
types enum : TAlignement et TNumerique. Pour TNumerique la valeur chNone correspond
à pas de restriction, chInt à chaîne de type int et chFloat chaîne de type float.
Pour TAlignement c'est suffisamment explicite. Ensuite dans la section private
de la classe TAlignEdit nous déclarons nos deux
données membres FAlign de type TAlignement et FNum de type TNumerique.
Dans la section protected nous déclarons les méthodes SetAlign SetNum qui serviront
à modifier leur propriété respective. Déclaration des méthodes à redéfinir KeyPress,
DoEnter, CreateParams.
Dans la section __published les 2 propriétés de type enum toujours selon le même principe.
Notre composant descendant de TEdit où toutes ses propriétés sont déjà visibles, il n'y a
donc pas besoin de les redéclarer.
Fichier "alignedit.cpp"
#include <vcl.h>
#pragma hdrstop
#include "AlignEdit.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck est utilisé pour vérifier que les composants créés n'ont
// aucune fonction virtuelle pure.
static inline void ValidCtrCheck(TAlignEdit *)
{
new TAlignEdit(NULL);
}
//---------------------------------------------------------------------------
__fastcall TAlignEdit::TAlignEdit(TComponent* Owner)
: TEdit(Owner)
{
FAlign = alGauche;
FNum = chNone;
}
//---------------------------------------------------------------------------
void __fastcall TAlignEdit::DoEnter()
{
TEdit::DoEnter();
if(AutoSelect) SelectAll();
}
//---------------------------------------------------------------------------
void __fastcall TAlignEdit::SetAlign(TAlignement Value)
{
FAlign = Value;
RecreateWnd();
}
//---------------------------------------------------------------------------
void __fastcall TAlignEdit::SetNum(TNumerique Value)
{
FNum = Value;
RecreateWnd();
}
//---------------------------------------------------------------------------
void __fastcall TAlignEdit::CreateParams(TCreateParams& Params)
{
int ValAlign;
int ValNum;
switch (Alignement)
{
case alGauche :
ValAlign = ES_LEFT;
break;
case alCentre :
ValAlign = ES_CENTER;
break;
case alDroite :
ValAlign = ES_RIGHT;
break;
}
if ( Chiffres == chInt ) ValNum = ES_NUMBER;
else ValNum = 0;
TEdit::CreateParams(Params);
Params.Style = Params.Style | ValAlign | ValNum
| ES_MULTILINE ;
}
//---------------------------------------------------------------------------
void __fastcall TAlignEdit::KeyPress(char &Key)
{
TEdit::KeyPress(Key);
if (Key == 13) Key = NULL;
if (Chiffres == chFloat && (Key < '0' || Key >'9') && Key != 8 &&
(Key != '-' || Text.Length() > 0 && SelLength != Text.Length()) &&
(Key != DecimalSeparator || Text.Pos(DecimalSeparator)!=0))
Key = NULL;
}
//---------------------------------------------------------------------------
namespace Alignedit
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TAlignEdit)};
RegisterComponents("MesCompo", classes, 0);
}
}
Passons maintenant à la définition de nos méthodes :
Dans le constructeur initialisation de nos deux données membres FAlign et FNum.
Dans la méthode DoEnter on sélectionne le texte quand le contrôle prend le focus.
Les méthodes SetAlign et SetNum Comme à l'habitude assignent leur donnée membre respective,
puis appelle la méthode RecreateWnd qui force le contrôle à se reconstruire.
(Certaine propriétés de contrôles Windows ne peuvent être modifiées que de cette façon).
La méthode redéfinie CreateParams est appelée automatiquement avant la reconstruction
du contrôle, c'est donc ici que nous initialiserons les paramètres de notre contrôle.
On y retrouve d'ailleurs les énumérations Alignement et Chiffres que l'on teste pour
l'initialisation de ces paramètres.
Dans la méthode KeyPress nous invalidons la touche entrée car c'est un contrôle multiligne
et cela aurait pour effet de créer une seconde ligne ce qui n'est pas notre but.
(Le contrôle EDIT de Windows ne peut avoir un alignement à droite ou centrée que s'il
est multiligne). Dans cette méthode nous faisons aussi la sélection des caractères
pour la saisie numérique de type float.
Pour que notre composant puisse traiter les événements correspondant aux méthodes DoEnter et KeyPress, il faut
appeller la méthode correspondante de la classe ancêtre. par exemple pour DoEnter() il faut
appeller Edit::DoEnter().
Vous avez pu constater que le type enum est très facile à mettre en oeuvre dans un composant.
Vous avez aussi dû remarquer que de nombreux composants utilisent ce type de donnée pour
leurs propriétés. Il rend l'utilisation des composants beaucoup plus intuitive.
Des propriétés avec des valeurs explicites sont beaucoup plus simples d'utilisation,
donc à utiliser sans modération dans vos composants.
CGi
Avec la contribution d'Alacazam pour la relecture.
Télécharger les sources.
|