Support des propriétés et des méthodes dans les variants personnalisés

De RAD Studio
Aller à : navigation, rechercher

Remonter à Définition de variants personnalisés - Index


Certains variants ont des propriétés et des méthodes. Par exemple, quand la valeur d'un variant est une interface, vous pouvez utiliser le variant pour lire ou écrire les valeurs des propriétés de cette interface et appeler ses méthodes. Même si votre type variant personnalisé ne représente pas une interface, vous pouvez lui donner des propriétés et des méthodes qu'une application pourra utiliser.

Utilisation de TInvokeableVariantType

Pour fournir le support des propriétés et méthodes, la classe que vous créez pour activer le nouveau type variant personnalisé doit descendre de System.Variants.TInvokeableVariantType et non directement de TCustomVariantType.

TInvokeableVariantType définit quatre méthodes :

que vous pouvez implémenter pour supporter les propriétés et les méthodes dans votre type variant personnalisé.

Par exemple, l'unité System.VarConv utilise TInvokeableVariantType comme classe de base pour TConvertVariantType de sorte que les variants personnalisés résultant puissent supporter les propriétés. L'exemple suivant présente l'accès en lecture pour ces propriétés :

Delphi :

 function TConvertVariantType.GetProperty(var Dest: TVarData;
 const V: TVarData; const Name: String): Boolean;
 var
 LType: TConvType;
 begin
 // supports...
 //   'Value'
 //   'Type'
 //   'TypeName'
 //   'Family'
 //   'FamilyName'
 //   'As[Type]'
 Result := True;
 if Name = 'VALUE' then
   Variant(Dest) := TConvertVarData(V).VValue
 else if Name = 'TYPE' then
   Variant(Dest) := TConvertVarData(V).VConvType
 else if Name = 'TYPENAME' then
   Variant(Dest) := ConvTypeToDescription(TConvertVarData(V).VConvType)
 else if Name = 'FAMILY' then
   Variant(Dest) := ConvTypeToFamily(TConvertVarData(V).VConvType)
 else if Name = 'FAMILYNAME' then
   Variant(Dest) := ConvFamilyToDescription(ConvTypeToFamily(TConvertVarData(V).VConvType))
 else if System.Copy(Name, 1, 2) = 'AS' then
 begin
   if DescriptionToConvType(ConvTypeToFamily(TConvertVarData(V).VConvType), System.Copy(Name, 3, MaxInt), LType) then
     VarConvertCreateInto(Variant(Dest), Convert(TConvertVarData(V).VValue, TConvertVarData(V).VConvType, LType), LType)
   else
     Result := False;
 end
 else
     Result := False;
 end;

La méthode GetProperty vérifie le paramètre Name pour déterminer quelle propriété est demandée. Elle récupère ensuite l'information de l'enregistrement TVarData du Variant (V), et la renvoie sous forme du Variant (Dest). Remarquez que cette méthode supporte les propriétés dont les noms sont générés de façon dynamique à l'exécution (As[Type]), en se basant sur la valeur en cours du variant personnalisé.

De même, les méthodes SetProperty, DoFunction et DoProcedure sont suffisamment génériques pour que vous puissiez générer de façon dynamique les noms des méthodes ou répondre aux divers nombres et types de paramètres.

Utilisation de TPublishableVariantType

Si le type variant personnalisé stocke ses données en utilisant l'instance d'un objet, alors il existe un moyen plus simple d'implémenter des propriétés, si ce sont aussi les propriétés de l'objet qui représente les données du variant. Si vous utilisez System.TypInfo.TPublishableVariantType comme classe de base pour votre type variant personnalisé, alors il vous suffit d'implémenter la méthode GetInstance et toutes les propriétés publiées de l'objet qui représente les données du variant seront implémentées automatiquement pour les variants personnalisés.

Par exemple, comme on l'a vu dans Stockage des données d'un type Variant personnalisé, TComplexVariantType stocke les données d'un variant à valeur complexe en utilisant une instance de TComplexData. TComplexData possède un certain nombre de propriétés publiées (Real, Imaginary, Radius, Theta et FixedTheta), qui fournissent des informations sur la valeur complexe. TComplexVariantType descend de TPublishableVariantType et implémente la méthode GetInstance pour renvoyer l'objet TComplexData (de TypInfo.pas) qui est stocké dans l'enregistrement TVarData du variant à valeur complexe.

Delphi :

 function TComplexVariantType.GetInstance(const V: TVarData): TObject;
 begin
 Result := TComplexVarData(V).VComplex;
 end;

TPublishableVariantType fait le reste. Il redéfinit les méthodes GetProperty et SetProperty pour qu'elles utilisent les informations de type à l'exécution (RTTI) de l'objet TComplexData pour lire et écrire les valeurs de propriétés.

Remarque :  Pour que TPublishableVariantType fonctionne, l'objet qui contient les données du variant personnalisé doit être compilé avec RTTI. Cela signifie qu'il doit être compilé en utilisant la directive {$M+} ou descendre de TPersistent.

Voir aussi