Sign in Join
Wiki copytemporary

VirtualTreeview Example for Lazarus/fr: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: VirtualTreeview Example for Lazarus/fr

OldNewLine
1+Voici quelques exemples sur la façon d'utiliser VirtualTreeview pour Lazarus (testé sur win32). Ceci sont essentiellement collectés à partir du web écrit pour delphi, et à partir des tutoriels/documents par Philipp Frenzel et Mike Lischke. Les tutoriels/documents peuvent être téléchargé à partir de l'adresse <http://www.soft-gems.net> . Ci dessous quelqu'un trouverait seulement la manière rapide d'utiliser VirtualTreeview avec Lazarus, pas une explication. Pour des explications et de nombreuses autres fonctions/méthodes obtenir les documents officiels et le didacticiel.
2+
3+# Arbre de base Listview avec trois Colonnes
4+
5+1\. Installez le composant. Exécutez lazarus.
6+
7+2\. Déposez un composant TVirtualStringTree (Sous l'onglet Virtual Controls).
8+
9+3\. Aller à l'éditeur de source (Appuyez sur F12). Sous la clause Uses ajoutez une unité - appelée VirtualTrees (si elle n'est pas déjà là et que ce n'est pas VirtualStringTree). Ainsi, il peut ressembler à:
10+
11+``` pascal
12+uses
13+ Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
14+ VirtualStringTree, VirtualTrees;
15+```
16+
17+4\. Aller à l'éditeur de fiches (Appuyez sur F12). Sélectionnez le composant Virtual Tree. Sur l'inspecteur d'objet cliquez sur Name, tapez VST et appuyez sur entrer. Cliquez sur Header (augmentez-le) -\> Columns, cliquez sur le petit bouton situé à côté de "0 items". Cliquez 3 fois sur Add button pour ajouter 3 colonnes. Ne pas fermer cette fenêtre.
18+
19+5\. Sur la fenêtre d'édition de la colonne maintenant la 3ième colonne est sélectionnée. Aller à l'inspecteur d'objet. Cliquez sur Options (augmentez-le) -\> fixez coAllowClicks à False.
20+
21+6\. Cliquez sur Text. Tapez Column2.
22+
23+7\. Cliquez sur Width, tapez 100 et appuyez sur enter.
24+
25+8\. Allez à la fenêtre d'édition de la colonne, selectionnez la 1ère et la 2ieme colonne, et fixez leur propriété comme ci-dessus (pour le champ Text, utiliser des noms différents, c'est à dire Column0, Column1).
26+
27+9\. Fermez la fenêtre d'édition de colonnes. Sélectionnez le composant Virtual Tree de la fiche. Sur l'inspecteur d'objet allez à Header -\> Options (augmentez-le). Fixez hoVisible à True.
28+
29+10\. Faites défiler la liste jusqu'à Style fixez le à hsFlatButtons.
30+
31+![](/wiki-images/7/70/ExempleVirtualtreeView1.jpg)
32+
33+11\. Faites défiler la liste jusqu'à TreeOptions(augmentez-le) -\> MiscOption(augmentez-le), fixez toEditable à True. Fixez toGridExtensions à True.
34+
35+12\. Faites défiler la liste jusqu'à SelectionOptions(augmentez-le) -\> fixez le toExtendedFocus à True. Fixez toMultiSelect à True. Sur le concepteur de fiche redimensionnez VST (composant Virtual Tree) pour obtenir le visuel de toutes les colonnes, si nécessaire.
36+
37+13\. Maintenant ajoutez 3 boutons sur la fiche. Obtenez les à partir de la palette de composants - Onglet standard (Label "OK" ).
38+
39+14\. CLiquez sur Button1, sur l'inspecteur d'object changez Caption avec AddRoot. Cliquez sur Button2, changez le caption avec AddChild. Changez le caption du Button3 avec Delete.
40+
41+![](/wiki-images/7/76/ExempleVirtualtreeView2.jpg)
42+
43+15\. Gardez ceci ici et allez à l'éditeur de source(appuyez sur F12). Dans l'éditeur de source remplacez la ligne:
44+
45+{\$mode objfpc}{\$H+} par {\$MODE DELPHI}
46+
47+16\. Sous "implementation" coller les lignes suivantes:
48+
49+``` pascal
50+type
51+ PTreeData = ^TTreeData;
52+ TTreeData = record
53+ Column0: String;
54+ Column1: String;
55+ Column2: String;
56+ end;
57+```
58+
59+17\. Allez au concepteur de fiche (Appuyez sur F12). sélectionnez VST. Allez à l'inspecteur d'objet, sélectionnez l'onglet évènements, défiler vers le bas vers l'évènement onChange. Double-cliquez sur le combobox. Coller ce qui suit:
60+
61+``` pascal
62+procedure TForm1.VSTChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
63+begin
64+ VST.Refresh;
65+end;
66+```
67+
68+18\. Faites défiler jusqu'à onFocusChanged. Double-cliquez et collez ce qui suit:
69+
70+``` pascal
71+procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
72+ Column: TColumnIndex);
73+begin
74+ VST.Refresh;
75+end;
76+```
77+
78+19\. Faites défiler jusqu'à onFreeNode. Double-cliquez et collez ce qui suit:
79+
80+``` pascal
81+procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
82+var
83+ Data: PTreeData;
84+begin
85+ Data:=VST.GetNodeData(Node);
86+ if Assigned(Data) then begin
87+ Data^.Column0 := '';
88+ Data^.Column1 := '';
89+ Data^.Column2 := '';
90+ end;
91+end;
92+```
93+
94+20\. Faites défiler jusqu'à onGetNodeDataSize. Double-cliquez et collez ce qui suit:
95+
96+``` pascal
97+procedure TForm1.VSTGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
98+begin
99+ NodeDataSize := SizeOf(TTreeData);
100+end;
101+```
102+
103+21\. Faites défiler jusqu'à onGetText. Double-cliquez et collez ce qui suit:
104+
105+``` pascal
106+procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
107+ Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
108+var
109+ Data: PTreeData;
110+begin
111+ Data := VST.GetNodeData(Node);
112+ case Column of
113+ 0: CellText := Data^.Column0;
114+ 1: CellText := Data^.Column1;
115+ 2: CellText := Data^.Column2;
116+ end;
117+end;
118+```
119+
120+22\. Pressez sur F12 pour aller à concepteur de fiche. Double-cliquez sur le bouton AddRoot. Collez ce qui suit:
121+
122+``` pascal
123+procedure TForm1.Button1Click(Sender: TObject);
124+Var
125+Data: PTreeData;
126+XNode: PVirtualNode;
127+Rand: Integer;
128+Begin
129+ Randomize;
130+ Rand := Random(99);
131+ XNode:=VST.AddChild(nil);
132+
133+ if VST.AbsoluteIndex(XNode) > -1 then
134+ Begin
135+ Data := VST.GetNodeData(Xnode);
136+ Data^.Column0:= 'One ' + IntToStr(Rand);
137+ Data^.Column1:= 'Two ' + IntToStr(Rand + 10);
138+ Data^.Column2:= 'Three ' + IntToStr(Rand - 10);
139+ End;
140+End;
141+```
142+
143+23\. Appuyez sur F9 pour exécuter le projet à vérifier. Cliquez sur AddRoot pour ajouter un nœud. Si c'est ok, le nœud sera ajouté sur VST.
144+
145+![](/wiki-images/8/86/ExempleVirtualtreeView3.jpg)
146+
147+24\. Arrêtez l'exécution. Sur le concepteur de fiche double-cliquez sur le bouton intitulé addChild. Collez ce qui suit:
148+
149+``` pascal
150+procedure TForm1.Button2Click(Sender: TObject);
151+var
152+ XNode: PVirtualNode;
153+ Data: PTreeData;
154+begin
155+ if not Assigned(VST.FocusedNode) then
156+ Exit;
157+
158+ XNode := VST.AddChild(VST.FocusedNode);
159+ Data := VST.GetNodeData(Xnode);
160+
161+ Data^.Column0:= 'Ch 1';
162+ Data^.Column1:= 'Ch 2';
163+ Data^.Column2:= 'Ch 3';
164+
165+ VST.Expanded[VST.FocusedNode]:=True;
166+end;
167+```
168+
169+25\. Sur le concepteur de fiche double-cliquez sur le bouton intitulé Delete. Copiez ce qui suit:
170+
171+``` pascal
172+procedure TForm1.Button3Click(Sender: TObject);
173+begin
174+ VST.DeleteSelectedNodes;
175+end;
176+```
177+
178+26\. Exécutez le projet en appuyant sur la touche F9 pour vérifier. Ajoutez quelques nœuds, nœuds fils et effacez les.
179+
180+![](/wiki-images/3/3d/ExempleVirtualtreeView4.jpg)
181+
182+27\. Essayez d'éditer un nœud. Sélectionnez un nœud et pressez sur F2, écrivez une nouvelle valeur. Si vous pouvez voir ce que vous tapez alors c'est OK. Sinon, lisez-dessous "Si l'édition d'une cellule ne peut être vue".
183+
184+28\. Pour obtenir que VST montre la nouvelle valeur après l'édition, allez au concepteur de fiche, sélectionnez VST. Double-cliquez sur le combobox de l'inspecteur d'objet -\> Evenements -\> OnNewText. Copiez ce qui suit:
185+
186+``` pascal
187+procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
188+ Column: TColumnIndex; NewText: WideString);
189+Var
190+ Data: PTreeData;
191+begin
192+ Data := VST.GetNodeData(Node);
193+ Case Column of
194+ 0: Data^.Column0:= NewText;
195+ 1: Data^.Column1:= NewText;
196+ 2: Data^.Column2:= NewText;
197+ End;
198+end;
199+```
200+
201+Jusqu'à présent, l'exemple de l'utilisation de base se termine ici. Vous pouvez mettre quelques boutons de plus sur la fiche afin de tester quelques commandes indiquées ci-dessous. La suite serait de montrer les cases à cocher, les images, la couleur des caractères et l'ajout de combobox sur un noeud.
202+
203+- Une autre manière d'ajouter le nœud racine
204+
205+``` pascal
206+procedure TForm1.Button8Click(Sender: TObject);
207+begin
208+ with VST do
209+ RootNodeCount:=RootNodeCount+1;
210+end;
211+```
212+
213+- Une autre façon d'ajouter un nœud enfant
214+
215+``` pascal
216+procedure TForm1.Button9Click(Sender: TObject);
217+begin
218+ if Assigned(VST.FocusedNode) Then
219+ VST.ChildCount[VST.FocusedNode]:=VST.ChildCount[VST.FocusedNode]+1;
220+end;
221+```
222+
223+- Déterminer et effacer un enfant d'un nœud donné
224+
225+``` pascal
226+procedure TForm1.Button4Click(Sender: TObject);
227+Var
228+ c: Integer;
229+begin
230+ if not Assigned(VST.FocusedNode) then
231+ Exit;
232+ If VST.HasChildren[VST.FocusedNode] then
233+ Begin
234+ c := VST.ChildCount[VST.FocusedNode];
235+ VST.DeleteChildren(VST.FocusedNode);
236+ ShowMessage('Number of deleted child:' + #13#10 + IntToStr(c));
237+ End;
238+end;
239+```
240+
241+- Effacer un nœud
242+
243+``` pascal
244+procedure TForm1.Button5Click(Sender: TObject);
245+begin
246+{VST.Clear; //Delete All Nodes}
247+ if not Assigned(VST.FocusedNode) then
248+ Exit;
249+ VST.DeleteNode(VST.FocusedNode);
250+end;
251+```
252+
253+- Rechercher et sélectionner un nœud
254+
255+``` pascal
256+procedure TForm1.Button6Click(Sender: TObject);
257+Var
258+ XNode: PVirtualNode;
259+ Data: PTreeData;
260+begin
261+ XNode:= VST.GetFirst;
262+
263+ while XNode <> nil do
264+ begin
265+ Data:=VST.GetNodeData(XNode);
266+ if Data^.Column0 = '1' then
267+ Begin
268+ VST.ClearSelection;
269+ VST.Selected[XNode]:=True;
270+ VST.SetFocus;
271+ break;
272+ End
273+ Else
274+ XNode:= VST.GetNextSibling(XNode);
275+ End;
276+End;
277+```
278+
279+- Determine Parent
280+
281+``` pascal
282+procedure TForm1.Button13Click(Sender: TObject);
283+var
284+ XNode: PVirtualNode;
285+begin
286+ if not Assigned(VST.FocusedNode) then
287+ Exit;
288+ XNode:=VST.FocusedNode;
289+ while VST.GetNodeLevel(XNode) > 0 do
290+ Begin
291+ XNode := XNode.Parent;
292+ VST.Selected[XNode]:= True;
293+ End;
294+ VST.Refresh;
295+ VST.SetFocus;
296+end;
297+```
298+
299+- Tout rechercher
300+
301+``` pascal
302+procedure TForm1.Button7Click(Sender: TObject);
303+Var
304+ XNode: PVirtualNode;
305+ Data: PTreeData;
306+begin
307+ If VST.GetFirst = nil then Exit;
308+ XNode:=nil;
309+ Repeat
310+ if XNode = nil then XNode:=VST.GetFirst Else XNode:=VST.GetNext(XNode);
311+ Data:=VST.GetNodeData(XNode);
312+ If (Data^.Column0 = '1') OR (Data^.Column1 = '1') OR (Data^.Column2 = '1') then
313+ Begin
314+ ShowMessage('Found at Node Level : ' + IntToStr(VST.GetNodeLevel(XNode)) );
315+ break;
316+ End;
317+ Until XNode = VST.GetLast();
318+end;
319+```
320+
321+- Insérer un nœud
322+
323+``` pascal
324+procedure TForm1.Button12Click(Sender: TObject);
325+var
326+XNode: PVirtualNode;
327+begin
328+ If Assigned(VST.FocusedNode) then
329+ begin
330+ XNode := VST.InsertNode(VST.FocusedNode,amInsertBefore);
331+ // To Insert After Selected Node.
332+ {XNode := VST.InsertNode(VST.FocusedNode,amInsertAfter);}
333+ VST.Refresh;
334+ end;
335+end;
336+```
337+
338+- Fixer la hauteur d'un nœud
339+
340+``` pascal
341+procedure TForm1.Button14Click(Sender: TObject);
342+begin
343+ If Assigned(VST.FocusedNode) then
344+ VST.NodeHeight[VST.FocusedNode] := 32;
345+end;
346+```
347+
348+- Sauvegarde et chargement
349+
350+Un arbre simple (sans colonne) peut être sauvegardé et chargé ainsi:
351+
352+``` pascal
353+VST.SaveToFile('filename.dat');
354+VST.LoadFromFile('filename.dat');
355+```
356+
357+Pour enregistrer et charger l'exemple mentionné ci-dessus, placez 2 boutons sur la fiche, renommez le caption avec "Save" pour le 1er et "Load" pour le second. Sélectionnez VST, sur l'inspecteur d'objet -\> TreeOptions -\> StringOptions assurez-vous que toSaveCaptions est fixé à True. Allez à l'onglet évènements de l'inspecteur d'objet. Faites défiler la liste jusqu'à OnLoadNode, double-cliquez, puis collez:
358+
359+``` pascal
360+procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
361+ Stream: TStream);
362+Var
363+ Data: PTreeData;
364+ Len: Integer;
365+begin
366+ Data := VST.GetNodeData(Node);
367+ Stream.read(Len, SizeOf(Len));
368+ SetLength(Data^.Column0, Len);
369+ Stream.read(PChar(Data^.Column0)^, Len);
370+
371+ Stream.read(Len, SizeOf(Len));
372+ SetLength(Data^.Column1, Len);
373+ Stream.read(PChar(Data^.Column1)^, Len);
374+
375+ Stream.read(Len, SizeOf(Len));
376+ SetLength(Data^.Column2, Len);
377+ Stream.read(PChar(Data^.Column2)^, Len);
378+end;
379+```
380+
381+A nouveau sur l'onglet évènements de l'inspecteur d'objet - défiler vers le bas vers OnSaveNode, double-cliquez, puis collez:
382+
383+``` pascal
384+procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
385+ Stream: TStream);
386+Var
387+ Data: PTreeData;
388+ Len: Integer;
389+begin
390+ Data := VST.GetNodeData(Node);
391+ Len := Length(Data^.Column0);
392+ Stream.write(Len, SizeOf(Len));
393+ Stream.write(PChar(Data^.Column0)^, Len);
394+
395+ Len := Length(Data^.Column1);
396+ Stream.write(Len, SizeOf(Len));
397+ Stream.write(PChar(Data^.Column1)^, Len);
398+
399+ Len := Length(Data^.Column2);
400+ Stream.write(Len, SizeOf(Len));
401+ Stream.write(PChar(Data^.Column2)^, Len);
402+end;
403+```
404+
405+Sur le concepteur de fiche double-cliquez sur le bouton intitulé Save, collez:
406+
407+``` pascal
408+procedure TForm1.Button10Click(Sender: TObject);
409+begin
410+ VST.SaveToFile('C:\vst.dat');
411+end;
412+```
413+
414+Sur le concepteur de fiche double-cliquez sur le bouton intitulé Load, collez:
415+
416+``` pascal
417+procedure TForm1.Button11Click(Sender: TObject);
418+begin
419+ VST.LoadFromFile('C:\vst.dat');
420+end;
421+```
422+
423+Testez maintenant l'enregistrement et le chargement de l'arbre.
424+
425+- Problème de défilement
426+
427+L'en-tête du treeview disparaît totalement ou partiellement lors du défilement. Je n'ai pas pu trouver une bonne solution pour cela. Une façon de surmonter ceci est de fixer la hauteur de l'en-tête à 0, puis d'utiliser un label général pour les colonnes. C'est bon tant qu'il y a peu de colonnes, et quelles sont toutes visibles sans défilement horizontal. Ou bien, la hauteur de l'en-tête peut être réglée à une valeur plus élevée de 25 ou 30. VST.Refresh peut être ajouté à l'évènement OnScroll.
428+
429+- Redimensionnement des colonnes
430+
431+Il n'est pas possible de redimensionner une colonne en faisant glisser la souris sur l'en-tête de VST. Peut être c'est à cause d'un bug de l'en-tête ou j'ai oublié quelque chose. Si c'est à cause de l'en-tête, ça sera probablement fixé avec la prochaine version de Lazarus. Voir ce lien: <http://bugs.freepascal.org/view.php?id=11209>\
432+Quoi qu'il en soit, il est possible de redimensionner la colonne à partir du code. Lorsque vous appuyez sur le bouton droit de la souris et déplacez la roulette vers le haut, la largeur de la colonne sélectionnée augmente et appuyez sur le bouton droit de la souris et déplacez la roulette vers le bas, pour diminuer la largeur de la colonne sélectionnée. Pour faire ceci:\
433+1\. Ajouter une variable dans l'éditeur de source nommé CurCol: Integer; Ainsi, le code ressemble à:
434+
435+``` pascal
436+var
437+ Form1: TForm1;
438+ CurCol: Integer; // <- Add this line only.
439+
440+implementation
441+
442+{ TForm1 }
443+```
444+
445+2\. Sur le concepteur de fiche double-cliquez sur le fiche pour générer l'évènement OnCreate. Dans la procédure OnCreate tapez Form1.OnMouseWheelUp:= et appuyez sur Ctrl+Shift+C, ceci va compléter le code et faire le squelette de l'évènement MouseWheelUp. Maintenant revenir à la procédure TForm1.FormCreate(Sender: TObject); et ajoutez un nouvel évènement pour MouseWheelDown. Tapez Form1.OnMouseWheelDown:= et appuyez sur Ctrl+Shift+C, pour générer l'évènement MouseWheelDown. La procédure FormCreate ressemble maintenant à :
446+
447+``` pascal
448+procedure TForm1.FormCreate(Sender: TObject);
449+begin
450+ Form1.OnMouseWheelUp:=@Form1MouseWheelUp;
451+ Form1.OnMouseWheelDown:=@Form1MouseWheelDown;
452+end;
453+```
454+
455+3\. Remplissez la procédure TForm1.Form1MouseWheelUp ainsi:
456+
457+``` pascal
458+procedure TForm1.Form1MouseWheelUp(Sender: TObject; Shift: TShiftState;
459+ MousePos: TPoint; var Handled: Boolean);
460+begin
461+ If VST.Focused then
462+ if ssRight in Shift then
463+ VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width + 10;
464+end;
465+```
466+
467+4\. Remplissez la procédure TForm1.Form1MouseWheelDown ainsi:
468+
469+``` pascal
470+procedure TForm1.Form1MouseWheelDown(Sender: TObject; Shift: TShiftState;
471+ MousePos: TPoint; var Handled: Boolean);
472+begin
473+ If VST.Focused then
474+ if ssRight in Shift then
475+ VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width - 10;
476+end;
477+```
478+
479+5\. Allez au concepteur de fiche (appuyez sur F12), sélectionnez VST, sur l'onglet des évènement de l'inspecteur d'objet faites défiler jusqu'à OnFocusChanged, double-cliquez et collez:
480+
481+``` pascal
482+procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree;
483+ Node: PVirtualNode; Column: TColumnIndex);
484+begin
485+ CurCol:=Column;
486+end;
487+```
488+
489+Lorsque vous exécutez le programme, cliquez sur une colonne puis maintenez enfoncé le bouton droit de la souris et faire bouger la roulette vers le haut pour augmenter la largeur de la colonne, et le roulette vers le bas pour la diminuer. Vous devriez mettre au point les procédures ci-dessus si nécessaire. Ou bien, ajoutez un évènement au clavier avec quelque chose du genre "if (key=187) and (ssShift in Shift) then" pour surveiller le Shift + "+".
490+
491+------------------------------------------------------------------------
492+
493+------------------------------------------------------------------------
494+
495+# Checkbox
496+
497+------------------------------------------------------------------------
498+
499+Sur le concepteur de fiche sélectionnez VST. Allez à:\
500+\#Inspecteur d'objets -\> Propriétés -\> CheckImageKind et sélectionnez ckDarkCheck.
501+
502+1. Inspecteur d'objets -\> Propriétés -\> TreeOptions -\> MiscOptions -\> toCheckSupport et la mettre à True.\
503+
504+Maintenant passer à l'onglet évènements.\
505+*Faites défiler jusqu'à OnInitNode. Double-cliquez et collez ce qui suit:
506+
507+``` pascal
508+procedure TForm1.VSTInitNode(Sender: TBaseVirtualTree; ParentNode,
509+ Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
510+Var
511+ Level: Integer;
512+begin
513+ Level := VST.GetNodeLevel(Node);
514+ if Level = 0 then
515+ Node.CheckType:=ctCheckBox;
516+
517+ if Level = 2 then
518+ Node.CheckType:=ctRadioButton;
519+
520+ if Level = 1 then
521+ begin
522+ Node.CheckType:=ctTriStateCheckBox;
523+ Node.CheckState := csCheckedNormal;
524+ end;
525+
526+ if Level = 3 then
527+ Node.CheckType:=ctButton;
528+end;
529+```
530+
531+Lancez le programme, ajoutez le nœud racine et un nœud enfant puis l'enfant d'un enfant, et vérifiez si vous pouvez cocher et décocher correctement. Si non, fermez le programme. Allez à l'onglet évènements de l'inspecteur d'objets.
532+
533+- Faites défiler jusqu'à OnChecked, double-cliquez et collez:
534+
535+``` pascal
536+procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
537+begin
538+ vst.Refresh;
539+end;
540+```
541+
542+- Faites défiler jusqu'à OnChecking, double-cliquez et collez:
543+
544+``` pascal
545+procedure TForm1.VSTChecking(Sender: TBaseVirtualTree; Node: PVirtualNode;
546+ var NewState: TCheckState; var Allowed: Boolean);
547+begin
548+ VST.Refresh;
549+end;
550+```
551+
552+J'espère maintenant que c'est ok. Pour déterminer l'état du checkbox utilisez quelque chose comme:\
553+If XNode.CheckState = csCheckedNormal then\
554+ShowMessage('Checked.');\
555+Les autres états sont:\
556+
557+``` pascal
558+csUncheckedNormal = unchecked and not pressed
559+csUncheckedPressed = unchecked and pressed
560+csCheckedNormal = checked and not pressed
561+csCheckedPressed = checked and pressed
562+csMixedNormal = 3-state check box and not pressed
563+csMixedPressed = 3-state check box and pressed
564+```
565+
566+Les autres types sont:\
567+
568+``` pascal
569+ctNone
570+ctTriStateCheckBox
571+ctCheckBox
572+ctRadioButton
573+ctButton
574+```
575+
576+- Pour capturer le clic du bouton Checkbox (ctButton)
577+
578+Allez à l'onglet évènements de l'inspecteur d'objets. Faites défiler jusqu'à OnChecked, double-cliquez et collez:
579+
580+``` pascal
581+procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
582+begin
583+ if Node.CheckType = ctButton then
584+ ShowMessage('Ok.');
585+ VST.Refresh;
586+end;
587+```
588+
589+Fin de checkbox.\
590+
591+------------------------------------------------------------------------
592+
593+------------------------------------------------------------------------
594+
595+# Image & Font Colour
596+
597+------------------------------------------------------------------------
598+
599+To show image on VST nodes, a list of image should be created.
600+
601+- Go to the Component Palette -\> Common Controls. Select and drop a TImageList component on the form. Right click on the component icon and select ImageList Editor. Click on Add button and and select some images (at least 3 for now), then click on tick button to accept and close the ImageList Editor. By the way, there are some nice images you can download from <http://www.famfamfam.com/lab/icons/silk/>
602+- Now on the Form Designer select VST, and on Object Inspector's Properties tab, scroll to Images and select ImageList1
603+- On Object Inspector's Events tab scroll to OnGetImageIndex, double click and paste:
604+
605+``` pascal
606+procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
607+ Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
608+ var ImageIndex: Integer);
609+begin
610+if Kind in [ikNormal , ikSelected] then // Either Selected or not
611+ begin
612+ if Column = 0 then // if 1st Column
613+ ImageIndex:=0; // 1st Image of the ImageList1
614+
615+ if Column = 1 then // if 2nd Column
616+ ImageIndex:=1; // 2nd Image of the ImageList1
617+
618+ if Sender.FocusedNode = Node then // Only show if Focused
619+ if Column =2 then // if 3rd Column
620+ ImageIndex:=2; // 3rd Image of the ImageList1
621+ end;
622+ {Sender.NodeHeight[node]:=40; //If Image is big}
623+end;
624+```
625+
626+##### Font Colour
627+
628+On the Form Designer select VST, and on Object Inspector's Events tab, scroll to OnPaintText, double click and paste:
629+
630+``` pascal
631+procedure TForm1.VSTPaintText(Sender: TBaseVirtualTree;
632+ const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
633+ TextType: TVSTTextType);
634+Var
635+ Data: PTreeData;
636+begin
637+ Data := VST.GetNodeData(Node);
638+
639+ if Data^.Column0 = 'sky' then
640+ TargetCanvas.Font.Color:=clBlue;
641+
642+ if Column = 1 then
643+ begin
644+ TargetCanvas.Font.Color:=clRed;
645+ TargetCanvas.Font.Style:= Font.Style + [fsItalic];
646+ end;
647+
648+ if Column = 2 then
649+ begin
650+// ImageList1.Draw(Form1.Canvas,-1,-1,2); {draw top left of form, 3rd image of ImageList1??}
651+ TargetCanvas.Font.Size:= 9;
652+ TargetCanvas.Font.Color:=clHighlightText;
653+ end;
654+end;
655+```
656+
657+Image & Font Colour ends here.
658+
659+# Adding A Combobox
660+
661+- I guess you have an open project on Lazarus IDE having VST on it and can edit the nodes. If not see the "Basic Tree Listview With 3 Columns" above, and atleast complete steps 1 to 21.
662+
663+- Bellow there is an unit file named combo. Copy that unit and save as combo.pas inside the project directory. Under your program's uses clause add combo. So it may look like:
664+
665+``` pascal
666+uses
667+ Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
668+ VirtualStringTree, VirtualTrees, combo;
669+```
670+
671+- The combo.pas unit
672+
673+``` pascal
674+unit combo;
675+
676+{$mode delphi}
677+
678+interface
679+
680+uses
681+ Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
682+ VirtualStringTree, VirtualTrees, messages, windows, StdCtrls;
683+
684+type
685+ TStringEditLink = class(TInterfacedObject, IVTEditLink)
686+ private
687+ FEdit: TWinControl;
688+ FTree: TVirtualStringTree;
689+ FNode: PVirtualNode;
690+ FColumn: Integer;
691+ protected
692+ procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
693+ public
694+ destructor Destroy; override;
695+ function BeginEdit: Boolean; stdcall;
696+ function CancelEdit: Boolean; stdcall;
697+ function EndEdit: Boolean; stdcall;
698+ function GetBounds: TRect; stdcall;
699+ function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
700+ procedure ProcessMessage(var Message: TMessage); stdcall;
701+ procedure SetBounds(R: TRect); stdcall;
702+ end;
703+
704+implementation
705+
706+destructor TStringEditLink.Destroy;
707+begin
708+ FEdit.Free;
709+ inherited;
710+end;
711+
712+procedure TStringEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
713+begin
714+ case Key of
715+ VK_ESCAPE:
716+ begin
717+ FTree.CancelEditNode;
718+ Key := 0;
719+ FTree.setfocus;
720+ end;
721+ VK_RETURN:
722+ begin
723+ PostMessage(FTree.Handle, WM_KEYDOWN, VK_DOWN, 0);
724+ Key := 0;
725+ FTree.EndEditNode;
726+ FTree.setfocus;
727+ end;
728+ End; //case
729+end;
730+
731+function TStringEditLink.BeginEdit: Boolean;
732+begin
733+ Result := True;
734+ //FEdit.Height:=(FTree.DefaultNodeHeight - 1); //Needed for editbox. Not combo
735+ FEdit.Show;
736+ TComboBox(FEdit).DroppedDown:=True;
737+ FEdit.SetFocus;
738+end;
739+
740+function TStringEditLink.CancelEdit: Boolean;
741+begin
742+ Result := True;
743+ FEdit.Hide;
744+end;
745+
746+function TStringEditLink.EndEdit: Boolean;
747+var
748+ S: WideString;
749+begin
750+ Result := True;
751+ S:= TComboBox(FEdit).Text;
752+ FTree.Text[FNode, FColumn] := S;
753+
754+ FTree.InvalidateNode(FNode);
755+ FEdit.Hide;
756+ FTree.SetFocus;
757+end;
758+
759+function TStringEditLink.GetBounds: TRect;
760+begin
761+ Result := FEdit.BoundsRect;
762+end;
763+
764+function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean;
765+begin
766+ Result := True;
767+ FTree := Tree as TVirtualStringTree;
768+ FNode := Node;
769+ FColumn := Column;
770+
771+ FEdit.Free;
772+ FEdit := nil;
773+
774+ FEdit := TComboBox.Create(nil);
775+ with FEdit as TComboBox do
776+ begin
777+ Visible := False;
778+ Parent := Tree;
779+ Items.Add('Google');
780+ Items.Add('Yahoo');
781+ Items.Add('Altavista');
782+ OnKeyDown := EditKeyDown;
783+ end;
784+end;
785+
786+procedure TStringEditLink.ProcessMessage(var Message: TMessage);
787+begin
788+ FEdit.WindowProc(Message);
789+end;
790+
791+procedure TStringEditLink.SetBounds(R: TRect);
792+var
793+ Dummy: Integer;
794+
795+begin
796+ FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right);
797+ FEdit.BoundsRect := R;
798+end;
799+
800+End.
801+```
802+
803+- After saving the file, on the Form Designer select VST and on Object Inspector's Properties, scroll to TreeOptions -\> MiscOptions, set toEditable to True. Then get to TreeOptions -\> SelectionOptions, set toExtendedFocus to True.
804+
805+- Switch to Object Inspector's Events tab. Scroll to OnCreateEditor, double click and paste:
806+
807+``` pascal
808+procedure TForm1.VSTCreateEditor(Sender: TBaseVirtualTree;
809+ Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink);
810+begin
811+ EditLink:=TStringEditLink.Create;
812+end;
813+```
814+
815+- On Object Inspector's Events tab. Scroll to OnNewText, double click and paste:
816+
817+``` pascal
818+procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
819+ Column: TColumnIndex; NewText: WideString);
820+Var
821+Data: PTreeData;
822+begin
823+Data := VST.GetNodeData(Node);
824+Case Column of
825+ 0: Data^.Column0:= NewText;
826+ 1: Data^.Column1:= NewText;
827+ 2: Data^.Column2:= NewText;
828+End;
829+end;
830+```
831+
832+Run program, select a node and press F2 to get combobox. On pressing Enter new value should appear on the node.
833+
834+# If Cell Editing Can't Be Seen
835+
836+------------------------------------------------------------------------
837+
838+Open VirtualStringTree.pas unit file (if you are still on the above example project, right click on VirtualStringTree under Uses clause and select Find Declaration. This opens the file on next tab. Go to that file's tab.). Get to the "function TStringEditLink.BeginEdit: Boolean; stdcall;". It looks like:
839+
840+``` pascal
841+
842+function TStringEditLink.BeginEdit: Boolean; stdcall;
843+
844+// Notifies the edit link that editing can start now. Descentants may cancel node edit
845+// by returning False.
846+
847+begin
848+ Result := not FStopping;
849+ if Result then
850+ begin
851+ FEdit.Show;
852+ FEdit.SelectAll;
853+ FEdit.SetFocus;
854+ end;
855+end;
856+```
857+
858+Now add "FEdit.Height:=18;". It should look like:
859+
860+``` pascal
861+function TStringEditLink.BeginEdit: Boolean; stdcall;
862+
863+// Notifies the edit link that editing can start now. Descentants may cancel node edit
864+// by returning False.
865+
866+begin
867+ Result := not FStopping;
868+ if Result then
869+ begin
870+ FEdit.Show;
871+ FEdit.SelectAll;
872+ FEdit.SetFocus;
873+ FEdit.Height:=18; // <--- Added this line.
874+ end;
875+end;
876+```
877+
878+Save the file (press Ctrl + S). If you are on the example project, close this (Project -\> Close Project). Click on Tools -\> Configure "Build Lazarus" ... Select Clean Up + Build All and then click on the Build button. After compile Lazarus should be restarted. Now open the example project and try to edit node on VST. This time it should be ok.\
879+Thank you.\
880+--Rabiul 21:37, 20 October 2008 (CEST)\
881+Alhamdulillah.
882+
883+------------------------------------------------------------------------
884+
885+[Programando en Pascal](http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_Pascal) - Spanish tutorial focused on FPC/Lazarus, hosted in Wikibooks.
886+
887+---
888+*From the Free Pascal wiki, page "VirtualTreeview Example for Lazarus/fr", as it stood on 2020-11-12 after a change by Iaurkano, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history