![]() |
|
Marco CantùL'essentiel sur PascalTraduit de l'anglais par Iannis Papageorgiadis [email protected] |
Chapitre 10
|
Pour fournir un support OLE complet, la version 32 bits de Delphi comporte le type de données Variant. Nous traiterons ici ce type de données d'un point de vue général. Le type Variant est, en fait, diffus dans tout le langage et la bibliothèque des composants Delphi l'utilise dans des situations qui n'ont rien à voir avec la programmation OLE.
Après cette mise en garde quant à l'utilisation du type Variant, examinons ce que ce type peut faire. Fondamentalement, une fois que l'on a déclaré une variable de type Variant comme la suivante :
var V: Variant;on peut lui affecter des valeurs de types différents :
V := 10; V := 'Hello, World'; V := 45.55;Une fois que l'on dispose de la valeur variant, on peut la copier dans n'importe quel autre type de données compatible ou non. Si on assigne une valeur à un type de données incompatible, Delphi effectue une conversion si cela est possible. Sinon il déclenche une erreur d'exécution. En fait, les variants stockent le type d'information avec la donnée et permettent un certain nombre d'opérations à l'exécution; ces opérations peuvent être pratiques mais sont lentes et peu sûres.
Considérons l'exemple suivant (appelé VariTest), qui est une extension du code précédent. Sur une nouvelle fiche, nous avons placé trois boîtes de saisie (Edit) et deux boutons, et nous avons écrit le code suivant pour l'événement OnClick du premier bouton :
procedure TForm1.Button1Click(Sender: TObject); var V: Variant; begin V := 10; Edit1.Text := V; V := 'Hello, World'; Edit2.Text := V; V := 45.55; Edit3.Text := V; end;Bizarre, n'est-ce pas? En plus d'assigner un variant contenant une chaîne à la propriété Text d'un composant TEdit, on peut lui assigner un variant contenant un nombre entier ou un nombre à virgule flottante. Tout cela fonctionne, comme on le voit à la figure 10.1.
Pire encore, on peut utiliser les variants pour calculer des valeurs, comme on peut le voir dans le code relatif au second bouton:
procedure TForm1.Button2Click(Sender: TObject); var V: Variant; N: Integer; begin V := Edit1.Text; N := Integer(V) * 2; V := N; Edit1.Text := V; end;Écrire ce genre de code est risqué, c'est le moins qu'on puisse dire. Si la première boîte d'édition (TEdit) contient un nombre, tout fonctionne. Sinon, une exception est levée. De nouveau, on peut écrire un code semblable mais, sans raison valable pour le faire, on ne devrait pas utiliser le type Variant; mieux vaut rester fidèle aux types de données Pascal traditionnels et à l'approche de vérification de type. Dans Delphi et dans la VCL (Bibliothèque des composants visuels), les variants sont fondamentalement utilisés pour le support d'OLE et pour l'accès aux champs des bases de données.
Les valeurs possibles du champ VType correspondent aux types de données qu'on peut utiliser dans OLE Automation, souvent appelés types OLE ou types Variant. Voici une liste alphabétique complète des types variants disponibles :
Il existe aussi de nombreuses fonctions qui travaillent sur des variants; on les utilise pour effectuer des conversions spécifiques ou pour obtenir des informations à propos du type d'un variant (p.ex. la fonction VarType). La plupart de ces fonctions de conversion de type et d'assignation sont en fait appelées automatiquement lorsqu'on écrit des expressions utilisant des variants. D'autres routines de support de variants (voir la rubrique Routines de support de variants de l'aide Delphi) travaillent en fait sur des tableaux de variants.
Ce programme fait tourner une boucle, il mesure sa vitesse et en affiche l'état dans une barre de progression. Voici la première de deux boucles très semblables, basées sur des Integer et sur des variants :
procedure TForm1.Button1Click(Sender: TObject); var time1, time2: TDateTime; n1, n2: Variant; begin time1 := Now; n1 := 0; n2 := 0; ProgressBar1.Position := 0; while n1 < 5000000 do begin n2 := n2 + n1; Inc (n1); if (n1 mod 50000) = 0 then begin ProgressBar1.Position := n1 div 50000; Application.ProcessMessages; end; end; // nous devons utiliser le résultat Total := n2; time2 := Now; Label1.Caption := FormatDateTime ( 'n:ss', Time2-Time1) + ' secondes'; end;Le code de chronométrage vaut la peine d'être examiné, parce qu'il est facilement adaptable à tout type de test de performances. Comme on le voit, le programme utilise la fonction Now pour obtenir l'heure courante, et la fonction FormatDateTime pour afficher la différence de temps, en indiquant uniquement les minutes ("n") et les secondes ("ss") dans la chaîne de format. On peut également utiliser la fonction API Windows GetTickCount, qui retourne une indication très précise des milli-secondes écoulées depuis le démarrage du système d'exploitation.
Dans cet exemple, la différence de vitesse est tellement grande
qu'on la remarquera même sans un chronométrage précis.
Voici, en tout cas, à la figure 10.2, les résultats de notre
ordinateur. Les valeurs réelles dépendent de l'ordinateur
utilisé pour faire tourner ce programme, mais la proportion ne devrait
pas être fort différente.
Après avoir traité de la plupart des fonctionnalités du langage, voyons la structure générale d'un programme et la modularisation offerte par les unités.