Conserver les noms de définition d'un type énuméré

Soyez le premier à donner votre avis sur cette source.

Vue 6 086 fois - Téléchargée 200 fois

Description

C'est un truc tout simple pour afficher les nom de constante utilisés dans un type énuméré. Il permet aussi de déterminer l'indice dans le type en ne connaissant que le nom.

Par exemple si on définit un type enuméré du style TMonTypeEnum=(mtUN,mtDEUX,mtTROIS), Delphi traite les variables de ce type comme des variables de type ordinal. Il n'est pas directement possible d'en afficher le nom comme on affiche un entier avec IntToStr. Le plus souvent on utilise un Case Of pour donner les noms :
Var t:TmonTypeEnum;
...
Case t Of
mtUn:LeNom:='mtUN';
mtDeux:LeNom:='mtDEUX';
mtTrois:LeNom:='mtTROIS';
End;

Or il est possible de demander à Delphi de conserver les noms dans le .EXE et de les obtenir. Je ne savais pas du tout que c'était possible, c'est donc pour cela que je poste ce truc. Je n'était peut-être pas le seul à ne pas le savoir.

Dans l'exemple ci dessus il suffit de faire
LeNom:=GetEnumName(TypeInfo(TMonTypeEnum),Integer(t));

GetEnumName n'est pas documentée dans l'aide de Delphi 6. Il est vrai que son utilisation est plutôt rare...

Source / Exemple :


Uses TypInfo;

type
// Défintion d'un type personnalisé tout simple
Type TChiffre=(Zero,Un,Deux,Trois,Quatre,Cinq,Six,Sept,Huit,Neuf);

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Affichage du nom de la constante définie dans le type énuméré
  ShowMessage(GetEnumName(TypeInfo(TChiffre),SpinEdit1.Value));
end;

procedure TForm1.Button2Click(Sender: TObject);
Var i:Integer;
begin
  // Obtention de l'indice de la constante
  i := GetEnumValue(TypeInfo(TChiffre),Edit1.Text);
  if i<0 Then Label2.Caption:='<inconnu>'
         Else Label2.Caption:=IntToStr(i);
end;

Conclusion :


La directive $M à été supprimée du source, après le commentaire de Delphiprog.

Cette source et quelques autres sur : http://nono40.developpez.com

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

cs_Delphiprog
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
23 -
Si GetEnumName renvoie une valeur littérale, il y a aussi la réciproque : GetEnumValue. Ci-après une démonstration :

uses
TypInfo;
type
TTestEnum =(Un, Deux, Trois, Quatre, Cinq, Six, Sept, Huit, Neuf);
const
TabTestEnum : array[TTestEnum] of String=
('Un','Deux','Trois','Quatre','Cinq','Six','Sept','Huit','Neuf');

procedure TForm1.Button1Click(Sender: TObject);
begin
TrackBar1.Position := GetEnumValue(TypeInfo(TTestEnum), Edit1.Text);
Edit1.SelectAll;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
TrackBar1.Max := Ord(High(TTestEnum));
TrackBar1.Min := Ord(Low(TTestEnum));
end;

GetEnumValue admet deux paramètres :
1- un pointeur sur une type énuméré
2- l'équivalent en chaîne de la valeur recherchée
et renvoie un integer indiquant la valeur ordinale dans le type énuméré ou zéro s'il n'a rien trouvé.

L'utilisation de la directive $M n'est pas indispensable ici. Je ne l'ai jamais utilisée et Borland me rassure en écrivant "Une application utilise directement l'indicateur $M de compilation très rarement, si ce n'est jamais".
cs_Nono40
Messages postés
1000
Date d'inscription
mercredi 3 avril 2002
Statut
Membre
Dernière intervention
12 septembre 2006
1 -
Très bonne remarque, je vais de ce pas modifier le source.

Juste un détail, GetEnumValeu retourne -1 si le nom n'est pas trouvé.

Je suis d'accord que ce n'est pas très utile, mais il y a un cas qui va me servir. J'utilise régulièrement les type énumérés et pour des besoin d'affichage j'avais recours à un Case ou un tableau de chaine constant. Mais dans les deux cas il fallait maintenir le case ou le tableau quand le type énuméré était modifié. Avec cette astuce ce n'est plus nécessaire.

Il est vrai que cela fonctionne aussi sans la directive $M, cela me semblait nécessaire dans ce cas... Je décourve le sujet...
cs_Delphiprog
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
23 -
GetEnumValue ne retourne pas toujours -1. Celà dépend du type de données examinées.

D'autre part, j'ai oublié de préciser que GetEnumValue n'est pas sensible à la casse en ce qui concerne le deuxième paramètre.

Pour info : ces routines existent depuis Delphi 2. Seulement, Borland ne semble pas avoir jugé utile de documenter l'unité TypInfo.Pas.
Et pourtant, ils font souvent allusion aux RTTI (RunTime Type Information) dans leur manuels.
cs_Nono40
Messages postés
1000
Date d'inscription
mercredi 3 avril 2002
Statut
Membre
Dernière intervention
12 septembre 2006
1 -
Ben quand on regarde le source de GetEnumValue il semble que si. GetEnumValue appelle la fonction GetEnumNameValue qui retourne -1 si la chaine n'est pas trouvée :
...
{ we haven't found the thing - return -1 }
@notFound:
OR EAX,-1

@exit:
POP EDI
POP ESI
POP EBX
end;

Par contre -1 peut aussi être retourné pour la valeur True des type LongBool WordBool ou ByteBool.
cbonus2000
Messages postés
33
Date d'inscription
vendredi 14 février 2003
Statut
Membre
Dernière intervention
2 décembre 2009
-
Question:
Est-ce qu'il y a moyen d'aller chercher toutes les propriétés de type string d'une classe?
Par exemple, la classe TFORM, aller chercher au RunTime ces propriétés de type string tel que: Caption, Hint, Name, etc...

Je ne crois pas que ma question est directement lié à cette source mais....peut-être que quelqu'un avec votre bagage d'expérience....

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.