obones.com  

Login







Mot de passe oublié ?  
Vous voulez vous inscrire ?  

Recherche

VirtualTreeview

Cette page présente quelques conseils et astuces relatifs à l'utilisation du VirtualTreeview sous Delphi

Les records doivent être initialisés

Note: Ceci n'est plus nécessaire depuis la révision c62ba8c6ece69078f472054bac770158388c0c19, 01/07/2009 21:24:17

Pour le virtual treeview, les données qu'il manipulent ne sont jamais qu'un tableau d'octets, sans signification particulière pour lui. Les exemples fournis avec lui montrent l'utilisation de records comme une des pistes de développement et c'est donc ce qui a est généralement utilisé. Cependant, une particularité des records est fréquement oubliée : l'initialisation.
Avec une classe, l'initialisation est faite automatiquement lors de sa construction avec l'appel à Create. Pour un record, il n'y a pas de constructeur, mais les champs présents dans le record doivent être initialisés, en particulier les chaînes et les tableaux. Dans un cadre classique, cette initialisation est faite automatiquement par le compilateur dès le début de la procédure où une variable de type record a été déclarée.
Dans le cadre du virtual treeview, seuls des pointeurs vers record sont manipulés, jamais des variables de type record puisque c'est le virtual treeview qui alloue les octets nécessaires au stockage du record demandé. La mémoire est donc bien allouée mais aucune initialisation n'est faite si ce n'est la mise à zéro des octets (selon les options de compilation).
Ainsi quand le pointeur est déréférencé pour accéder aux membres du record, on accède bien à une zone mémoire valide mais les routines de gestion implicite de la mémoire pour les strings et les tableaux risquent de ne pas fonctionner.
C'est pourquoi il est indispensable de fournir un gestionnaire pour OnInitNode dans lequel on fera un appel spécifique pour initialiser le record :

NodeData := Sender.GetNodeData(Node);
Initialize(NodeData^);

Avec NodeData qui est une variable de type pointeur sur le record. L'utilisation de l'indirection (le chapeau ^) est obligatoire pour passer le record à Initialize et pas un pointeur sur le record. Ainsi, on est sûr que ce dernier est initialisé correctement. On pourra placer ce code dans le gestionnaire pour OnInitNode ou, plus judicieusement, dans OnStructureChange comme on le voit à la section suivante.