Difference between revisions of "VirtualTreeview Example for Lazarus/es"

From Lazarus wiki
Jump to navigationJump to search
m (Fixed syntax highlighting; deleted category included in page template)
 
(20 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
{{Example for VirtualTreeview on Lazarus}}
 
{{Example for VirtualTreeview on Lazarus}}
 +
[[category:Castellano|?]][[category:Español|?]]
  
Aqui hay algunos ejemplos acerca de como how usar el control VirtualTreeview para Lazarus (probado en win32). La mayoria de estos ejemplos han sido recolectados de la web, escritos para delphi, y de los documentos o tutoriales por Philipp Frenzel y Mike Lischke. Los documentos o tutoriales pueden ser descargados desde http://www.soft-gems.net . Abajo, usted puede encontrar alguna forma rapida de como utilizar VirtualTreeview en Lazarus, no explicaciones detallas. Para mas explicaciones y otros metodos o funciones, obtenga los documentos oficiales y el tutorial.
+
   Aqui hay algunos ejemplos acerca de como usar el control VirtualTreeview para Lazarus (probado en win32). La mayoría de estos ejemplos han sido recolectados de la web, escritos para delphi, y de los documentos o tutoriales por Philipp Frenzel y Mike Lischke. Los documentos o tutoriales pueden ser descargados desde http://www.soft-gems.net . Abajo, usted puede encontrar alguna forma rapida de como utilizar VirtualTreeview en Lazarus, no explicaciones detalladas. Para más explicaciones y otros métodos o funciones, obtenga los documentos oficiales y el tutorial.
  
 
= Ejemplo Tree Listview basico con 3 columnas =
 
= Ejemplo Tree Listview basico con 3 columnas =
Line 9: Line 10:
 
2. Arrastre un componente TVirtualStringTree (bajo la pagina Controles Visuales).
 
2. Arrastre un componente TVirtualStringTree (bajo la pagina Controles Visuales).
  
3. Vaya al editor de codigo (oprima la tecla F12). Bajo la sentencia Uses agregue una unidad - escriba VirtualTrees (si no existe previamente, no confunda con la unidad VirtualStringTree). Se vera de forma igual o similar a :
+
3. Vaya al editor de código (oprima la tecla F12). Bajo la sentencia ''Uses'' agregue una unidad - escriba VirtualTrees (si no existe previamente, no confunda con la unidad VirtualStringTree). Se vera de forma igual o similar a :
<delphi>uses
+
<syntaxhighlight lang=pascal> uses
   Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
+
   Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, VirtualStringTree, VirtualTrees;</syntaxhighlight>   
  VirtualStringTree, VirtualTrees;</delphi>   
 
  
4. Vaya al Diseñador de Formas (oprima la tecla F12). Seleccione el componente Virtual Tree. En el Inspector de Objetos haga clic en Nombre, escriba VST y oprima la tecla Enter (Return). Haga clic en Encabezado (expandalo) -> Columnas, haga clic en el peque&ntilde;o boton, al lado de "0 elementos". Haga clic 3 veces en agregar boton para agregar 3 columnas. No cierre esta ventana.
+
4. Vaya al Diseñador de Formularios (oprima la tecla F12). Seleccione el componente Virtual Tree. En el Inspector de Objetos haga clic en Nombre, escriba VST y oprima la tecla Enter (Return). Haga clic en Encabezado (expandalo) -> Columnas, haga clic en el peque&ntilde;o botón, al lado de "0 elementos". Haga clic 3 veces en el botón agregar para agregar 3 columnas. No cierre esta ventana.
  
5. En la ventana para Edicion de Columna, aparecera la 3ra. columna como seleccionada. Vaya al Inspector de Objetos. Haga clic en Opciones (expandalo) -> y asigne coAllowClick como False.
+
5. En la ventana para Edición de Columna, aparecerá la 3ra. columna como seleccionada. Vaya al Inspector de Objetos. Haga clic en Opciones (expandalo) -> y asigne coAllowClick como False.
  
 
6. Haga clic en Texto. Escriba Column2.
 
6. Haga clic en Texto. Escriba Column2.
Line 22: Line 22:
 
7. Haga clic en ancho, escriba 100 y oprima la tecla Enter (Return).
 
7. Haga clic en ancho, escriba 100 y oprima la tecla Enter (Return).
  
8. Vaya a la ventana para Edicion de Columna, seleccione las columnas 1ra. y 2da., y asigne su propiedad como la de arriba (para el campo Texto, use nombres diferentes, ejemplo: Columna0, Columna1).
+
8. Vaya a la ventana para Edición de Columna, seleccione las columnas 1ra. y 2da., y asigne su propiedad como la de arriba (para el campo Texto, use nombres diferentes, ejemplo: Columna0, Columna1).
 +
 
 +
9. Cierre la ventana para Edición de Columna. Seleccione el componente ''Virtual Tree'' en el formulario. En el Inspector de Objetos vaya a Encabezado -> Opciones (expandalo). Asigne coAllowClick como True.
 +
 
 +
10. Desplacese hacia abajo hasta Style, y asignelo como hsFlatButtons.
  
9. Cierre la ventana para Edicion de Columna. Seleccione el component Virtual Tree en la forma. En el Inspector de Objetos vaya a Encabezado -> Opciones (expandalo). Asigne coAllowClick como True.
+
11. Desplacese hacia abajo hasta TreeOptions (expandalo) -> MiscOption (expandalo), y asigne toEditable como True. Asigne toGridExtensions como True.
  
10. Desplazece hacia abajo hasta Style, y asignelo como hsFlatButtons.
+
12. Desplacese hacia abajo hasta SelectionOptions (expandalo) -> y asigne toExtendedFocus como True. Asigne toMultiSelect como True. En el Diseñador de Formularios cambie el tama&ntilde;o del VST (componente Virtual) para para poder visualizar todas las columnas, en caso de que sea necesario.
  
11. Desplazece hacia abajo hasta TreeOptions (expandalo) -> MiscOption (expandalo), y asigne toEditable como True. Asigne toGridExtensions como True.
+
13. Ahora, para agregar 3 botones en el formulario. Arrastrelos desde la paleta de componentes - Pagina Estándar (Etiquetados como "OK").
  
12. Desplazece hacia abajo hasta SelectionOptions (expandalo) -> y asigne toExtendedFocus como True. Asigne toMultiSelect como True. En el Diseñador de Formas cambie el tama&ntilde;o del VST (componente Virtual) para para poder visualizar todas las columnas, en caso de que sea necesario.
+
14. Haga clic en Button1, en el Inspector de Objetos cambie Titulo a "Añadir Nodo". Haga clic en el Button2, cambie el titulo a  "Añadir Hijo". Cambie el titulo de Button3 a "Borrar".
  
13. Ahora, para agregar 3 botones en la forma. Arrastrelos desde la paleta de componentes - Pagina Estandar (Etiquetados como "OK").
+
15. Mantenga esto aquí y vaya al editor de código (oprima la tecla F12). En el Editor de Código reemplace la linea:
  
14. Haga clic en Button1, en el Inspector de Objetos cambie Titulo a "AddRoot". Haga clic en el Button2, cambie el titulo a  "AddChild". Cambie el titulo de Button3 a "Delete".
+
<syntaxhighlight lang=pascal>{$mode objfpc}{$H+}</syntaxhighlight>
  
15. Mantenga esto aqui y vaya al editor de codigo (oprima la tecla F12). En el Editor de Codigo reemplace la linea:
+
Con la linea:
  
{$mode objfpc}{$H+} with {$MODE DELPHI}
+
<syntaxhighlight lang=pascal>{$MODE DELPHI}</syntaxhighlight>
  
16. Bajo la sentencia "implementation" pegue las siguientes lineas de codigo:
+
16. Bajo la sentencia "implementation" pegue las siguientes lineas de código:
  
<delphi>type
+
<syntaxhighlight lang=pascal> type
  PTreeData = ^TTreeData;
+
PTreeData = ^TTreeData;
  TTreeData = record
+
TTreeData = record
    Column0: String;
+
  Column0: String;
    Column1: String;
+
  Column1: String;
    Column2: String;
+
  Column2: String;
  end;</delphi>
+
end;</syntaxhighlight>
  
17. Vaya al Diseñador de Formas (oprima la tecla F12). Seleccione el control VST. Vaya al Inspector de Objetos, seleccione la pagina Eventos, desplazece hasta el evento onChange. Haga doble clic en el control combobox.
+
17. Vaya al Diseñador de Formularios (oprima la tecla F12). Seleccione el control VST. Vaya al Inspector de Objetos, seleccione la pagina Eventos, desplacese hasta el evento onChange. Haga doble clic en el control combobox.
  
18. Desplazece hasta el evento onFocusChanged. Haga doble clic y pegue el codigo siguiente:
+
18. Desplacese hasta el evento onFocusChanged. Haga doble clic y pegue el código siguiente:
<delphi>procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
+
<syntaxhighlight lang=pascal> procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
 
   Column: TColumnIndex);
 
   Column: TColumnIndex);
begin
+
begin
 
   VST.Refresh;
 
   VST.Refresh;
end;</delphi>
+
end;</syntaxhighlight>
 
    
 
    
19. Desplazece hasta el evento onFreeNode. Haga doble clic y pegue el codigo siguiente:
+
19. Desplacese hasta el evento onFreeNode. Haga doble clic y pegue el código siguiente:
<delphi>procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
+
<syntaxhighlight lang=pascal> procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
+
var
 
   Data: PTreeData;
 
   Data: PTreeData;
begin
+
begin
 
   Data:=VST.GetNodeData(Node);
 
   Data:=VST.GetNodeData(Node);
 
   if Assigned(Data) then begin
 
   if Assigned(Data) then begin
Line 70: Line 74:
 
     Data^.Column2 := '';
 
     Data^.Column2 := '';
 
   end;
 
   end;
end;</delphi>
+
end;</syntaxhighlight>
  
20. Desplazece hasta el evento onGetNodeDataSize. Haga doble clic y pegue el codigo siguiente:  
+
20. Desplacese hasta el evento onGetNodeDataSize. Haga doble clic y pegue el código siguiente:  
<delphi>procedure TForm1.VSTGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
+
<syntaxhighlight lang=pascal> procedure TForm1.VSTGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
begin
+
begin
 
   NodeDataSize := SizeOf(TTreeData);
 
   NodeDataSize := SizeOf(TTreeData);
end;</delphi>
+
end;</syntaxhighlight>
  
21. Desplazece hasta el evento onGetText. Haga doble clic y pegue el codigo siguiente:  
+
21. Desplacese hasta el evento onGetText. Haga doble clic y pegue el código siguiente:  
<delphi>procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
+
<syntaxhighlight lang=pascal> procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
 
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
 
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
 
var
 
var
Line 90: Line 94:
 
     2: CellText := Data^.Column2;
 
     2: CellText := Data^.Column2;
 
   end;
 
   end;
end;</delphi>
+
end;</syntaxhighlight>
  
22. Oprima la tecla F12 para ir al Diseñador de Formas. Haga doble clic en el boton "AddRoot". Haga doble clic y pegue el codigo siguiente:
+
22. Oprima la tecla F12 para ir al Diseñador de Formularios. Haga doble clic en el botón "Añadir Nodo". Haga doble clic y pegue el código siguiente:
  
<delphi>procedure TForm1.Button1Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button1Click(Sender: TObject);
Var
+
Var
 
   Data: PTreeData;
 
   Data: PTreeData;
 
   XNode: PVirtualNode;
 
   XNode: PVirtualNode;
 
   Rand: Integer;
 
   Rand: Integer;
Begin
+
Begin
 
   Randomize;
 
   Randomize;
 
   Rand := Random(99);
 
   Rand := Random(99);
Line 107: Line 111:
 
   Begin
 
   Begin
 
   Data := VST.GetNodeData(Xnode);
 
   Data := VST.GetNodeData(Xnode);
   Data^.Column0:= 'One ' + IntToStr(Rand);
+
   Data^.Column0:= 'Uno ' + IntToStr(Rand);
   Data^.Column1:= 'Two ' + IntToStr(Rand + 10);
+
   Data^.Column1:= 'Dos ' + IntToStr(Rand + 10);
   Data^.Column2:= 'Three ' + IntToStr(Rand - 10);
+
   Data^.Column2:= 'Tres ' + IntToStr(Rand - 10);
 
   End;  
 
   End;  
End;</delphi>
+
End;</syntaxhighlight>
  
23. Oprima la tecla F9 para Ejecutar el proyecto y revisarlo. Haga clic en el boton "AddRoot" para agregar un nodo. SI no hay problema alguno, el nodo sera agregado al control VST.
+
23. Oprima la tecla F9 para Ejecutar el proyecto y revisarlo. Haga clic en el botón "Añadir Nodo" para agregar un nodo. Si no hay problema alguno, el nodo sera agregado al control V.S.T.
  
24. Detenga la ejecucion del programa. En el Diseñador de Formas haga doble clic en el boton titulado "AddChild". Haga doble clic y pegue el codigo siguiente:
+
24. Detenga la ejecución del programa. En el Diseñador de Formularios haga doble clic en el botón titulado "Añadir Hijo". Haga doble clic y pegue el código siguiente:
  
<delphi>procedure TForm1.Button2Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button2Click(Sender: TObject);
var
+
var
 
   XNode: PVirtualNode;
 
   XNode: PVirtualNode;
 
   Data: PTreeData;
 
   Data: PTreeData;
begin
+
begin
 
   if not Assigned(VST.FocusedNode) then
 
   if not Assigned(VST.FocusedNode) then
 
     Exit;
 
     Exit;
Line 133: Line 137:
  
 
   VST.Expanded[VST.FocusedNode]:=True;
 
   VST.Expanded[VST.FocusedNode]:=True;
end;</delphi>
+
end;</syntaxhighlight>
  
25. En el Diseñador de Formas haga doble clic en el boton titulado "Delete". Haga doble clic y pegue el codigo siguiente:
+
25. En el Diseñador de Formularios haga doble clic en el botón titulado "Borrar". Haga doble clic y pegue el código siguiente:
  
<delphi>procedure TForm1.Button3Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button3Click(Sender: TObject);
begin
+
begin
 
   VST.DeleteSelectedNodes;
 
   VST.DeleteSelectedNodes;
end;</delphi>
+
end;</syntaxhighlight>
  
 
26. Ejecute el proyecto, oprimiendo la tecla F9 para revisarlo. Haga varias pruebas, agregando algunos nodos principales, nodos hijos y eliminelos.
 
26. Ejecute el proyecto, oprimiendo la tecla F9 para revisarlo. Haga varias pruebas, agregando algunos nodos principales, nodos hijos y eliminelos.
  
27. Intente editar un node. Seleccione un nodo y oprima la tecla F2, y escriba un nuevo valor. Si puede ver lo que esta escribiendo, entonces, el paso esta bien. De lo contrario, lea la seccion siguiente titulada "Cuando la edicion de celda no puede verse".
+
27. Intente editar un nodo. Seleccione un nodo y oprima la tecla F2, y escriba un nuevo valor. Si puede ver lo que esta escribiendo, entonces, el paso esta bien. De lo contrario, lea la sección siguiente titulada "Cuando la edición de celda no puede verse".
  
28. Para obtener que el V.S.T. muestre el nuevo valor capturado despues de la edicion, vaya al Diseñador de Formas, y seleccione V.S.T. Haga doble clic, en la cajacombo de el Inspector de Objetos -> Events -> OnNewText.
+
28. Para obtener que el V.S.T. muestre el nuevo valor capturado después de la edición, vaya al Diseñador de Formularios, y seleccione V.S.T. Haga doble clic, en el ''combo'' del Inspector de Objetos -> Events -> OnNewText.
Haga doble clic y pegue el codigo siguiente:
 
  
<delphi>procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
+
&nbsp;&nbsp;&nbsp;Haga doble clic y pegue el código siguiente:
 +
 
 +
<syntaxhighlight lang=pascal> procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
 
   Column: TColumnIndex; NewText: WideString);
 
   Column: TColumnIndex; NewText: WideString);
Var
+
Var
 
   Data: PTreeData;
 
   Data: PTreeData;
begin
+
begin
 
   Data := VST.GetNodeData(Node);
 
   Data := VST.GetNodeData(Node);
 
   Case Column of
 
   Case Column of
Line 160: Line 165:
 
     2: Data^.Column2:= NewText;
 
     2: Data^.Column2:= NewText;
 
   End;
 
   End;
end;</delphi>
+
end;</syntaxhighlight>
  
Hasta ahora, el ejemplo para uso basico, termina aqui. Usted podria arrastrar algunos botones adicionales  en la forma para probar algunos de los comandos mencionados, mas adelante. El paso siguiente, podria ser, desplegar una casill para marcar o "checkbox", imagen, color para tipo de fuente de texto, o agregar una cajacombo al nodo.  
+
&nbsp;&nbsp;&nbsp;Hasta ahora, el ejemplo para uso básico, termina aquí. Usted podría arrastrar algunos botones adicionales  en el formulario para probar algunos de los comandos mencionados, mas adelante. El paso siguiente, podría ser, desplegar una casilla para marcar o ''checkbox'', imagen, color para tipo de fuente de texto, o agregar un ''combo'' al nodo.  
  
*Otra forma para agregar el nodo raiz:
+
*Otra forma para agregar el nodo raíz:
  
<delphi>procedure TForm1.Button8Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button8Click(Sender: TObject);
begin
+
begin
 
   with VST do
 
   with VST do
 
   RootNodeCount:=RootNodeCount+1;
 
   RootNodeCount:=RootNodeCount+1;
end;</delphi>
+
end;</syntaxhighlight>
  
 
* Otra forma para agregar un nodo hijo:
 
* Otra forma para agregar un nodo hijo:
  
<delphi>procedure TForm1.Button9Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button9Click(Sender: TObject);
begin
+
begin
 
   if Assigned(VST.FocusedNode) Then
 
   if Assigned(VST.FocusedNode) Then
 
   VST.ChildCount[VST.FocusedNode]:=VST.ChildCount[VST.FocusedNode]+1;
 
   VST.ChildCount[VST.FocusedNode]:=VST.ChildCount[VST.FocusedNode]+1;
end;</delphi>
+
end;</syntaxhighlight>
  
 
*Determinar y eliminar los nodos hijos de un nodo:
 
*Determinar y eliminar los nodos hijos de un nodo:
  
<delphi>procedure TForm1.Button4Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button4Click(Sender: TObject);
Var
+
Var
 
   c: Integer;
 
   c: Integer;
begin
+
begin
 
   if not Assigned(VST.FocusedNode) then
 
   if not Assigned(VST.FocusedNode) then
 
     Exit;
 
     Exit;
Line 194: Line 199:
 
     ShowMessage('Number of deleted child:' + #13#10 + IntToStr(c));
 
     ShowMessage('Number of deleted child:' + #13#10 + IntToStr(c));
 
   End;
 
   End;
end;</delphi>
+
end;</syntaxhighlight>
  
 
* Eliminar un nodo:
 
* Eliminar un nodo:
  
<delphi>procedure TForm1.Button5Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button5Click(Sender: TObject);
begin
+
begin
{VST.Clear;  //Delete All Nodes}
+
{VST.Clear;  //Delete All Nodes}
 
   if not Assigned(VST.FocusedNode) then
 
   if not Assigned(VST.FocusedNode) then
 
     Exit;
 
     Exit;
 
   VST.DeleteNode(VST.FocusedNode);
 
   VST.DeleteNode(VST.FocusedNode);
end;</delphi>
+
end;</syntaxhighlight>
  
 
* Buscar y seleccionar un nodo:
 
* Buscar y seleccionar un nodo:
  
<delphi>procedure TForm1.Button6Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button6Click(Sender: TObject);
bar
+
var
 
   XNode: PVirtualNode;
 
   XNode: PVirtualNode;
 
   Data: PTreeData;
 
   Data: PTreeData;
begin
+
begin
 
   XNode:= VST.GetFirst;
 
   XNode:= VST.GetFirst;
  
Line 227: Line 232:
 
     XNode:= VST.GetNextSibling(XNode);
 
     XNode:= VST.GetNextSibling(XNode);
 
   end;
 
   end;
end;</delphi>
+
end;</syntaxhighlight>
  
 
* Determinar el nodo padre de un nodo:
 
* Determinar el nodo padre de un nodo:
  
<delphi>procedure TForm1.Button13Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button13Click(Sender: TObject);
var
+
var
 
   XNode: PVirtualNode;
 
   XNode: PVirtualNode;
begin
+
begin
 
   if not Assigned(VST.FocusedNode) then
 
   if not Assigned(VST.FocusedNode) then
 
     Exit;
 
     Exit;
Line 245: Line 250:
 
   VST.Refresh;
 
   VST.Refresh;
 
   VST.SetFocus;
 
   VST.SetFocus;
end;</delphi>
+
end;</syntaxhighlight>
  
 
* Buscar todos los nodos:
 
* Buscar todos los nodos:
  
<delphi>procedure TForm1.Button7Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button7Click(Sender: TObject);
Var
+
Var
 
   XNode: PVirtualNode;
 
   XNode: PVirtualNode;
 
   Data: PTreeData;
 
   Data: PTreeData;
begin
+
begin
 
   If VST.GetFirst = nil then Exit;
 
   If VST.GetFirst = nil then Exit;
 
   XNode:=nil;
 
   XNode:=nil;
Line 265: Line 270:
 
     End;
 
     End;
 
   Until XNode = VST.GetLast();
 
   Until XNode = VST.GetLast();
end;</delphi>
+
end;</syntaxhighlight>
  
 
* Buscar el nodo siguiente:
 
* Buscar el nodo siguiente:
  
<delphi>procedure TForm1.Button8Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button8Click(Sender: TObject);
var
+
var
 
   XNode: PVirtualNode;
 
   XNode: PVirtualNode;
 
   Data: PTreeData;
 
   Data: PTreeData;
begin
+
begin
 
   if not Assigned(VST.GetFirst) then
 
   if not Assigned(VST.GetFirst) then
 
     Exit
 
     Exit
Line 294: Line 299:
 
     end;
 
     end;
 
   until XNode = VST.GetLast;
 
   until XNode = VST.GetLast;
end;</delphi>
+
end;</syntaxhighlight>
  
 
* Insertar Nodo:
 
* Insertar Nodo:
  
<delphi>procedure TForm1.Button12Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button12Click(Sender: TObject);
var
+
var
 
   XNode: PVirtualNode;
 
   XNode: PVirtualNode;
begin
+
begin
 
   If Assigned(VST.FocusedNode) then
 
   If Assigned(VST.FocusedNode) then
 
   begin
 
   begin
Line 309: Line 314:
 
     VST.Refresh;
 
     VST.Refresh;
 
   end;
 
   end;
end;</delphi>
+
end;</syntaxhighlight>
  
 
* Asignar la altura de un nodo:
 
* Asignar la altura de un nodo:
  
<delphi>procedure TForm1.Button14Click(Sender: TObject);
+
<syntaxhighlight lang=pascal> procedure TForm1.Button14Click(Sender: TObject);
begin
+
begin
 
   If Assigned(VST.FocusedNode) then
 
   If Assigned(VST.FocusedNode) then
 
   VST.NodeHeight[VST.FocusedNode] := 32;
 
   VST.NodeHeight[VST.FocusedNode] := 32;
end;</delphi>
+
end;</syntaxhighlight>
  
 
* Guardar y Cargar:
 
* Guardar y Cargar:
  
Simple tree (without column) can be saved and loaded as:
+
&nbsp;&nbsp;&nbsp;El arbol simple (sin columnas), puede ser guardado y recargado con:
  
<delphi>
+
<syntaxhighlight lang=pascal> VST.SaveToFile('filename.dat');
VST.SaveToFile('filename.dat');
+
VST.LoadFromFile('filename.dat');</syntaxhighlight>
VST.LoadFromFile('filename.dat');
 
</delphi>
 
  
Para guardar y cargar el ejemplo mencionado arriba, coloque 2 botones en la forma, cambie el titulo de un boton a "Guardar", y el titulo del otro boton a "Cargar". Seleccione el V.S.T., En el Inspector de Objetos -> TreeOptions -> StringOptions. Asegurese, que el valor de la propiedad toSaveCaptions este asignada como True. Vaya a la pagina del Inspector de Eventos Events. Desplazece hasta OnLoadNode,, haga doble cilc y pegue el codigo siguiente:
+
&nbsp;&nbsp;&nbsp;Para guardar y cargar el ejemplo mencionado arriba, coloque 2 botones en el formulario, cambie el título de un botón a "Guardar", y el titulo del otro botón a "Cargar". Seleccione el V.S.T., En el Inspector de Objetos -> TreeOptions -> StringOptions. Asegurese, que el valor de la propiedad toSaveCaptions este asignada como True. Vaya a la pagina del Inspector de Eventos Events. Desplazece hasta OnLoadNode, haga doble cilc y pegue el codigo siguiente:
  
<delphi>procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
+
<syntaxhighlight lang=pascal> procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
 
   Stream: TStream);
 
   Stream: TStream);
Var
+
Var
 
   Data: PTreeData;
 
   Data: PTreeData;
 
   Len: Integer;
 
   Len: Integer;
begin
+
begin
 
   Data := VST.GetNodeData(Node);
 
   Data := VST.GetNodeData(Node);
 
   Stream.read(Len, SizeOf(Len));
 
   Stream.read(Len, SizeOf(Len));
Line 348: Line 351:
 
   SetLength(Data^.Column2, Len);
 
   SetLength(Data^.Column2, Len);
 
   Stream.read(PChar(Data^.Column2)^, Len);
 
   Stream.read(PChar(Data^.Column2)^, Len);
end;</delphi>
+
end;</syntaxhighlight>
 +
 
 +
&nbsp;Otra vez, en la pagina Events del Inspector de Objetos, desplazece hasta OnSaveNode, haga doble cilc y pegue el codigo siguiente:
  
Again on Object Inspector's Events tab - scroll down to OnSaveNode, double click and then paste:
+
<syntaxhighlight lang=pascal> procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
<delphi>procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
 
 
   Stream: TStream);
 
   Stream: TStream);
Var
+
Var
 
   Data: PTreeData;
 
   Data: PTreeData;
 
   Len: Integer;
 
   Len: Integer;
begin
+
begin
 
   Data := VST.GetNodeData(Node);
 
   Data := VST.GetNodeData(Node);
 
   Len := Length(Data^.Column0);
 
   Len := Length(Data^.Column0);
Line 369: Line 373:
 
   Stream.write(Len, SizeOf(Len));
 
   Stream.write(Len, SizeOf(Len));
 
   Stream.write(PChar(Data^.Column2)^, Len);
 
   Stream.write(PChar(Data^.Column2)^, Len);
end;</delphi>
+
end;</syntaxhighlight>
  
On Form Designer double click Save captioned button, paste:
+
&nbsp;&nbsp;&nbsp;En el Diseñador de Formularios, haga doble clic en el botón titulado "Save" o "Guargar", y pegue el codigo siguiente:
<delphi>procedure TForm1.Button10Click(Sender: TObject);
+
 
begin
+
<syntaxhighlight lang=pascal> procedure TForm1.Button10Click(Sender: TObject);
 +
begin
 
  VST.SaveToFile('C:\vst.dat');
 
  VST.SaveToFile('C:\vst.dat');
end;</delphi>
+
end;</syntaxhighlight>
  
On Form Designer double click Load captioned button, paste:
+
&nbsp;&nbsp;En el Diseñador de Formularios, haga doble clic en el botón titulado "Load" o "Cargar", y pegue el codigo siguiente:
<delphi>procedure TForm1.Button11Click(Sender: TObject);
+
 
 +
<syntaxhighlight lang=pascal>
 +
procedure TForm1.Button11Click(Sender: TObject);
 
begin
 
begin
 
   VST.LoadFromFile('C:\vst.dat');
 
   VST.LoadFromFile('C:\vst.dat');
end;</delphi>
+
end;
Now test to save and load tree.
+
</syntaxhighlight>
 +
 
 +
&nbsp;&nbsp;&nbsp;Ahora, haga pruebas, para guardar y volver a cargar el arbol.
  
*Scroll Problem
+
*Problema de desplazamiento
The header of the treeview disappears fully or partially when scrolling. I could not find a good solution for this. One way to overcome this is to set the header height to 0, then using general label for columns. This is good while there are few columns, and all are visible without horizontal scrolling. Or, the header height can be set to a higher value like 25 or 30. VST.Refresh can be added to the OnScroll event.
 
  
*Column Resize
+
&nbsp;&nbsp;&nbsp;El encabezado de control vistaarbol desaparece parcialmente o completamente al desplazarse. No pude encontrar una buena solucion a esto. Una forma de sobrepasar esto, es asignar la altura del encabezado a 0, y utilizar una etiqueta generica para las columnas, y todas las columnas estan visibles sin desplazamiento horizontal. O, la altura del encabezado puede ser asignada un valor mas alto, entre 25 o 30. El metodo VST.Refresh puede ser asignado al evento OnScroll.
It was not possible to resize column by dragging mouse on VST header. May be it is for the header bug or I have missed something. If it is for the header, probably will be fixed on next version of Lazarus. See this link: http://bugs.freepascal.org/view.php?id=11209<br>
 
Anyway, it is possible to resize column from code. When you press down right mouse button and move mouse-wheel up, the width of the selected column increases and press down the right mouse button and move mouse-wheel down, to decrease the width of the selected column. To do this:<br>
 
  
1. Add a variable in the source editor named as CurCol: Integer; So it looks like:
+
*Cambiar el tama&ntilde;o de las columnas
<delphi>var
+
 
 +
&nbsp;&nbsp;&nbsp;No fue posible cambiar el tama&ntilde;o de las columnas, arrastrando el ratón en el encabezado del V.S.T. Tal vez, sea debido al "bug" del encabezado, o tal vez, omiti algo. En caso de que la causa haya sido el encabezado, tal vez sea corregido en la siguiente version de  Lazarus. Puede ver este enlace: http://bugs.freepascal.org/view.php?id=11209<br>
 +
 
 +
&nbsp;&nbsp;&nbsp;De cualquier forma, es posible cambiar el tama&ntilde;o de las columnas por medio de codigo. Cuando presione mantenga presionado el botón derecho del ratón, y gire la rueda arriba, el ancho de la columna seleccionada se incrementa, y manteniendo presionado abajo, el botón derecho del ratón y girando hacia abjo la rueda del ratón, podra decrementar el ancho de la columna seleccionada. Para hacer esto:<br>
 +
 
 +
1. Agregue una variable en el editor de codigo llamada como CurCol: Integer; Se vera como esto:
 +
 
 +
<syntaxhighlight lang=pascal> var
 
   Form1: TForm1;  
 
   Form1: TForm1;  
   CurCol: Integer; // <- Add this line only.
+
   CurCol: Integer; // <- Agregue solo esta linea.
  
implementation
+
implementation
  
{ TForm1 } </delphi>
+
{ TForm1 }</syntaxhighlight>
  
2. On the Form Designer double click the form to generate an event OnCreate. Inside the OnCreate procedure type Form1.OnMouseWheelUp:= and press Ctrl+Shift+C, this will complete the code and make skeleton of the MouseWheelUp event. Now get back to procedure TForm1.FormCreate(Sender: TObject); And add another event for MouseWheelDown. Type Form1.OnMouseWheelDown:= and press Ctrl+Shift+C, to generate the MouseWheelDown event. FormCreate procedure now looks like:
+
2. En el Diseñador de Formularios, haga doble clic en el formulario para generar un procedimiento para el evento OnCreate. En el procedimiento OnCreate, escriba Form1.OnMouseWheelUp:= y presione Ctrl+Shift+C, esto completara el codigoy hara el esqueleto del procedimiento para el evento MouseWheelUp. ahora, regrese al procedimiento TForm1.FormCreate(Sender: TObject); Y agregue otro procedimiento, esta vez para el evento MouseWheelDown. Escriba Form1.OnMouseWheelDown:= y oprima la combinacion de teclas Ctrl+Shift+C, para generar el procedimiento para el evento MouseWheelDown. El procedimiento FormCreate quedará asi:
<delphi>procedure TForm1.FormCreate(Sender: TObject);
+
 
begin
+
<syntaxhighlight lang=pascal> procedure TForm1.FormCreate(Sender: TObject);
 +
begin
 
   Form1.OnMouseWheelUp:=@Form1MouseWheelUp;
 
   Form1.OnMouseWheelUp:=@Form1MouseWheelUp;
 
   Form1.OnMouseWheelDown:=@Form1MouseWheelDown;
 
   Form1.OnMouseWheelDown:=@Form1MouseWheelDown;
end;</delphi>
+
end;</syntaxhighlight>
  
3. Fill the TForm1.Form1MouseWheelUp procedure as:
+
3. Capture el procedimiento para el evento TForm1.Form1MouseWheelUp procedure como:
<delphi>procedure TForm1.Form1MouseWheelUp(Sender: TObject; Shift: TShiftState;
+
 
 +
<syntaxhighlight lang=pascal> procedure TForm1.Form1MouseWheelUp(Sender: TObject; Shift: TShiftState;
 
   MousePos: TPoint; var Handled: Boolean);
 
   MousePos: TPoint; var Handled: Boolean);
begin
+
begin
 
  If VST.Focused then
 
  If VST.Focused then
 
   if ssRight in Shift then
 
   if ssRight in Shift then
 
  VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width + 10;
 
  VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width + 10;
end;</delphi>
+
end;</syntaxhighlight>
  
4. Fill the TForm1.Form1MouseWheelDown procedure as:
+
4. Capture el procedimiento para el evento TForm1.Form1MouseWheelDown procedure como:
<delphi>procedure TForm1.Form1MouseWheelDown(Sender: TObject; Shift: TShiftState;
+
 
 +
<syntaxhighlight lang=pascal> procedure TForm1.Form1MouseWheelDown(Sender: TObject; Shift: TShiftState;
 
   MousePos: TPoint; var Handled: Boolean);
 
   MousePos: TPoint; var Handled: Boolean);
begin
+
begin
 
   If VST.Focused then
 
   If VST.Focused then
 
   if ssRight in Shift then
 
   if ssRight in Shift then
 
  VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width - 10;
 
  VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width - 10;
end;</delphi>
+
end;</syntaxhighlight>
 +
 
 +
5. Vaya al Diseñador de Formularios (puede oprimir F12), seleccione el V.S.T., En la pagina Events, del Inspector de Objetos, desplazece hasta OnFocusChanged, haga doble clic y pegue el codigo siguiente:
  
5. Go to the Form Designer (press F12), select VST, on Object Inspector's Events tab scroll to OnFocusChanged, double click & paste:
+
<syntaxhighlight lang=pascal> procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree;
<delphi>procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree;
 
 
   Node: PVirtualNode; Column: TColumnIndex);
 
   Node: PVirtualNode; Column: TColumnIndex);
begin
+
begin
 
   CurCol:=Column;
 
   CurCol:=Column;
end;</delphi>
+
end;</syntaxhighlight>
 +
 
 +
&nbsp;&nbsp;&nbsp;Cuando ejecute el programa, haga clic en una columna, después mantenga presionado abajo, el botón derecho del ratón, y gire la rueda arriba, para incrementar el ancho. Gire la rueda abajo decrementar los valores mencionados.
 +
 
 +
&nbsp;&nbsp;Podria modificar los procedimientos anteriores, para ajustar un poco el resultado, si es necesario. O, agregar algun evento para el teclado, con algo como ''if (key=187) and (ssShift in Shift) then'' para utilizar la combinacion de teclas "Shift" y "+".
  
When you run, click on a column then hold down right mouse button and move wheel up to increase width, wheel down to decrease. You may tune-up the above procedures if needed. Or, add keyboard event with something like "if (key=187) and (ssShift in Shift) then" to watch for Shift + "+".
+
=Casillas de verificación ( "Checkboxes" )=
 +
 
 +
&nbsp;&nbsp;&nbsp;En el Diseñador de Formularios selecciona el control V.S.T. y desplazate hasta:
 +
 +
#Inspector de Objetos -> Propiedades -> CheckImageKind y seleccione ckDarkCheck.
 +
#Inspector de Objetos -> Propiedade -> TreeOptions -> MiscOptions -> toCheckSupport y asignelo como True.
  
=Checkbox=
+
&nbsp;&nbsp;&nbsp;Ahora, cambia a la página de '''Eventos'''.
  
On Form Designer select VST. Go to:<br>
+
*Desplazate hasta el evento '''''OnInitNode'''''. Haz doble clic y pega el código siguiente:
#Object Inspector -> Properties -> CheckImageKind and select ckDarkCheck.
+
<syntaxhighlight lang=pascal> procedure TForm1.VSTInitNode(Sender: TBaseVirtualTree; ParentNode,
#Object Inspector -> Properties -> TreeOptions -> MiscOptions -> toCheckSupport and set it to True.<br>
 
Now switch to Events tab.<br>
 
*Scroll to OnInitNode. Double click and paste the followings:
 
<delphi>procedure TForm1.VSTInitNode(Sender: TBaseVirtualTree; ParentNode,
 
 
   Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
 
   Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
Var
+
Var
 
   Level: Integer;
 
   Level: Integer;
begin
+
begin
 
   Level := VST.GetNodeLevel(Node);
 
   Level := VST.GetNodeLevel(Node);
 
   if Level = 0 then
 
   if Level = 0 then
Line 461: Line 483:
 
   if Level = 3 then
 
   if Level = 3 then
 
     Node.CheckType:=ctButton;
 
     Node.CheckType:=ctButton;
end;</delphi>
+
end;</syntaxhighlight>
Run the program, add rootnode and child then child of the child, and check if you can check and uncheck properly. If not, close the program. Go to the Object Inspector's Events tab.
 
  
*Scroll to OnChecked, double click and paste:
+
&nbsp;&nbsp;&nbsp;Ejecuta el programa, y agrega el nodo raiz y nodos hijos, y posteriormente, nodos hijos a los nodos hijos, y revisa marcar y desmarcar las casillas correctamente. Cuando no sea el caso, cierra el programa. Ve a la pestaña '''Eventos''' del Inspector de Eventos.
<delphi>procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
+
 
begin
+
*Deslizate al evento '''''OnChecked''''', haz doble clic y pega el texto siguiente:
 +
<syntaxhighlight lang=pascal> procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
 +
begin
 
   vst.Refresh;
 
   vst.Refresh;
end;</delphi>
+
end;</syntaxhighlight>
 +
 
 +
*Va hasta el evento '''''OnChecking''''', haz doble clic y pege el texto siguiente:
 +
<syntaxhighlight lang=pascal> procedure TForm1.VSTChecking(Sender: TBaseVirtualTree; Node: PVirtualNode;
 +
var NewState: TCheckState; var Allowed: Boolean);
 +
begin
 +
  VST.Refresh;
 +
end;</syntaxhighlight>
  
*Scroll to OnChecking, double click and paste:
+
&nbsp;&nbsp;&nbsp;Esperemos que ahora funcione. Para determinar el estado actual de la casilla escribe algo como:<BR>
<delphi>procedure TForm1.VSTChecking(Sender: TBaseVirtualTree; Node: PVirtualNode;
 
  var NewState: TCheckState; var Allowed: Boolean);
 
begin
 
VST.Refresh;
 
end;</delphi>
 
Hope now it is ok. To determine checkbox state use like:<BR>
 
  
If XNode.CheckState = csCheckedNormal then<br>
+
<syntaxhighlight lang=pascal> If XNode.CheckState = csCheckedNormal then ShowMessage('Marcado.');</syntaxhighlight>
ShowMessage('Checked.');<br>
 
  
Other states are:<br>
+
*Otros estados son:
<delphi>csUncheckedNormal = unchecked and not pressed
+
**'''''csUncheckedNormal''''' : Sin marcar y sin presionar
csUncheckedPressed = unchecked and pressed
+
**'''''csUncheckedPressed''''' : Sin marcar y presionado
csCheckedNormal = checked and not pressed
+
**'''''csCheckedNormal''''' : Marcado y sin presionar
csCheckedPressed = checked and pressed
+
**'''''csCheckedPressed''''' : Marcado y presionado
csMixedNormal = 3-state check box and not pressed
+
**'''''csMixedNormal''''' : Casilla de 3 estados y sin presionar
csMixedPressed = 3-state check box and pressed</delphi>
+
**'''''csMixedPressed''''' : Casilla de 3 estados y presionados</syntaxhighlight>
  
Other types are:<br>
+
*Otros tipos son:
<delphi>ctNone
+
**'''''ctNone''''' : Sin asignar
ctTriStateCheckBox
+
**'''''ctTriStateCheckBox''''' : casilla de 3 estados
ctCheckBox
+
**'''''ctCheckBox''''' : casilla estándar de 2 estados
ctRadioButton
+
**'''''ctRadioButton''''' : Botón tipo Radio, en vez de casilla
ctButton</delphi>
+
**'''''ctButton''''' : botón estándar</syntaxhighlight>
*To Catch Checkbox's Button (ctButton) Click
 
Go to Object Inspector's Events tab. Scroll to OnChecked, double click and paste:
 
<delphi>procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
 
begin
 
if Node.CheckType = ctButton then
 
ShowMessage('Ok.');
 
VST.Refresh;
 
end;</delphi>
 
End of checkbox.<br>
 
  
 +
*Para capturar el evento '''''Clic''''' del boton o casilla (ctButton)
 +
&nbsp;&nbsp;Ve a la pestaña Eventos del Inspector de Objetos. Desplazace al evento '''''OnChecked''''', haz doble clic y pega el texto siguiente:
 +
<syntaxhighlight lang=pascal>procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
 +
begin
 +
  if Node.CheckType = ctButton then
 +
  ShowMessage('Correcto');
 +
  VST.Refresh;
 +
end;</syntaxhighlight>
 +
Fin de Casillas.
  
=Images=
+
=Imagenes=
  
 
To show image on VST nodes, a list of image should be created.
 
To show image on VST nodes, a list of image should be created.
Line 512: Line 535:
 
*Now on the Form Designer select VST, and on Object Inspector's Properties tab, scroll to Images and select ImageList1
 
*Now on the Form Designer select VST, and on Object Inspector's Properties tab, scroll to Images and select ImageList1
 
*On Object Inspector's Events tab scroll to OnGetImageIndex, double click and paste:
 
*On Object Inspector's Events tab scroll to OnGetImageIndex, double click and paste:
<delphi>procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
+
<syntaxhighlight lang=pascal>procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
 
   Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
 
   Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
 
   var ImageIndex: Integer);
 
   var ImageIndex: Integer);
Line 529: Line 552:
 
   end;
 
   end;
 
   {Sender.NodeHeight[node]:=40; //If Image is big}
 
   {Sender.NodeHeight[node]:=40; //If Image is big}
end;</delphi>
+
end;</syntaxhighlight>
  
 
=Font Colour=
 
=Font Colour=
  
 
On the Form Designer select VST, and on Object Inspector's Events tab, scroll to OnPaintText, double click and paste:
 
On the Form Designer select VST, and on Object Inspector's Events tab, scroll to OnPaintText, double click and paste:
<delphi>procedure TForm1.VSTPaintText(Sender: TBaseVirtualTree;
+
<syntaxhighlight lang=pascal>procedure TForm1.VSTPaintText(Sender: TBaseVirtualTree;
 
   const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
 
   const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
 
   TextType: TVSTTextType);
 
   TextType: TVSTTextType);
Line 557: Line 580:
 
     TargetCanvas.Font.Color:=clHighlightText;
 
     TargetCanvas.Font.Color:=clHighlightText;
 
   end;
 
   end;
end;</delphi>
+
end;</syntaxhighlight>
  
 
=Adding A Combobox=
 
=Adding A Combobox=
Line 564: Line 587:
  
 
*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:
 
*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:
<delphi>uses
+
<syntaxhighlight lang=pascal> uses
 
   Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
 
   Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
   VirtualStringTree, VirtualTrees, combo;</delphi>
+
   VirtualStringTree, VirtualTrees, combo;</syntaxhighlight>
  
 
*The combo.pas unit
 
*The combo.pas unit
<delphi>unit combo;
+
<syntaxhighlight lang=pascal> unit combo;
  
{$mode delphi}
+
{$mode delphi}
  
interface
+
interface
  
uses
+
uses
 
   Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
 
   Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
 
   VirtualStringTree, VirtualTrees, messages, windows, StdCtrls;
 
   VirtualStringTree, VirtualTrees, messages, windows, StdCtrls;
  
type
+
type
 
   TStringEditLink = class(TInterfacedObject, IVTEditLink)
 
   TStringEditLink = class(TInterfacedObject, IVTEditLink)
 
   private
 
   private
Line 599: Line 622:
 
   end;
 
   end;
  
implementation
+
implementation
  
destructor TStringEditLink.Destroy;
+
destructor TStringEditLink.Destroy;
begin
+
begin
 
   FEdit.Free;
 
   FEdit.Free;
 
   inherited;
 
   inherited;
end;
+
end;
  
procedure TStringEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
+
procedure TStringEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
+
begin
 
   case Key of
 
   case Key of
 
     VK_ESCAPE:
 
     VK_ESCAPE:
Line 624: Line 647:
 
       end;
 
       end;
 
   End; //case
 
   End; //case
end;
+
end;
  
function TStringEditLink.BeginEdit: Boolean;
+
function TStringEditLink.BeginEdit: Boolean;
begin
+
begin
 
   Result := True;
 
   Result := True;
 
   //FEdit.Height:=(FTree.DefaultNodeHeight - 1); //Needed for editbox. Not combo
 
   //FEdit.Height:=(FTree.DefaultNodeHeight - 1); //Needed for editbox. Not combo
Line 633: Line 656:
 
   TComboBox(FEdit).DroppedDown:=True;
 
   TComboBox(FEdit).DroppedDown:=True;
 
   FEdit.SetFocus;
 
   FEdit.SetFocus;
end;
+
end;
  
function TStringEditLink.CancelEdit: Boolean;
+
function TStringEditLink.CancelEdit: Boolean;
begin
+
begin
 
   Result := True;
 
   Result := True;
 
   FEdit.Hide;
 
   FEdit.Hide;
end;
+
end;
  
function TStringEditLink.EndEdit: Boolean;
+
function TStringEditLink.EndEdit: Boolean;
var
+
var
 
   S: WideString;
 
   S: WideString;
begin
+
begin
 
   Result := True;
 
   Result := True;
 
   S:= TComboBox(FEdit).Text;
 
   S:= TComboBox(FEdit).Text;
Line 652: Line 675:
 
   FEdit.Hide;
 
   FEdit.Hide;
 
   FTree.SetFocus;
 
   FTree.SetFocus;
end;
+
end;
  
function TStringEditLink.GetBounds: TRect;
+
function TStringEditLink.GetBounds: TRect;
begin
+
begin
 
   Result := FEdit.BoundsRect;
 
   Result := FEdit.BoundsRect;
end;
+
end;
  
function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean;
+
function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean;
begin
+
begin
 
   Result := True;
 
   Result := True;
 
   FTree := Tree as TVirtualStringTree;
 
   FTree := Tree as TVirtualStringTree;
Line 679: Line 702:
 
           OnKeyDown := EditKeyDown;
 
           OnKeyDown := EditKeyDown;
 
       end;
 
       end;
end;
+
end;
  
procedure TStringEditLink.ProcessMessage(var Message: TMessage);
+
procedure TStringEditLink.ProcessMessage(var Message: TMessage);
begin
+
begin
 
   FEdit.WindowProc(Message);
 
   FEdit.WindowProc(Message);
end;
+
end;
  
procedure TStringEditLink.SetBounds(R: TRect);
+
procedure TStringEditLink.SetBounds(R: TRect);
var
+
var
 
   Dummy: Integer;
 
   Dummy: Integer;
begin
+
begin
 
   FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right);
 
   FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right);
 
   FEdit.BoundsRect := R;
 
   FEdit.BoundsRect := R;
end;
+
end;
  
End.</delphi>
+
End.</syntaxhighlight>
  
 
*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.
 
*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.
  
 
*Switch to Object Inspector's Events tab. Scroll to OnCreateEditor, double click and paste:
 
*Switch to Object Inspector's Events tab. Scroll to OnCreateEditor, double click and paste:
<delphi>procedure TForm1.VSTCreateEditor(Sender: TBaseVirtualTree;
+
<syntaxhighlight lang=pascal> procedure TForm1.VSTCreateEditor(Sender: TBaseVirtualTree;
 
   Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink);
 
   Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink);
begin
+
begin
 
   EditLink:=TStringEditLink.Create;
 
   EditLink:=TStringEditLink.Create;
end;</delphi>
+
end;</syntaxhighlight>
  
 
*On Object Inspector's Events tab. Scroll to OnNewText, double click and paste:
 
*On Object Inspector's Events tab. Scroll to OnNewText, double click and paste:
<delphi>procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
+
<syntaxhighlight lang=pascal> procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
 
   Column: TColumnIndex; NewText: WideString);
 
   Column: TColumnIndex; NewText: WideString);
Var
+
Var
 
   Data: PTreeData;
 
   Data: PTreeData;
begin
+
begin
 
   Data := VST.GetNodeData(Node);
 
   Data := VST.GetNodeData(Node);
 
   Case Column of
 
   Case Column of
Line 717: Line 740:
 
     2: Data^.Column2:= NewText;
 
     2: Data^.Column2:= NewText;
 
   End;
 
   End;
end;</delphi>
+
end;</syntaxhighlight>
 
Run program, select a node and press F2 to get combobox. On pressing Enter new value should appear on the node.
 
Run program, select a node and press F2 to get combobox. On pressing Enter new value should appear on the node.
  
Line 725: Line 748:
 
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;".
 
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:
 
It looks like:
<delphi>function TStringEditLink.BeginEdit: Boolean; stdcall;
+
<syntaxhighlight lang=pascal> function TStringEditLink.BeginEdit: Boolean; stdcall;
  
// Notifies the edit link that editing can start now. Descentants may cancel node edit
+
// Notifies the edit link that editing can start now. Descentants may cancel node edit
// by returning False.
+
// by returning False.
  
begin
+
begin
 
   Result := not FStopping;
 
   Result := not FStopping;
 
   if Result then
 
   if Result then
Line 738: Line 761:
 
     FEdit.SetFocus;
 
     FEdit.SetFocus;
 
   end;
 
   end;
end;</delphi>     
+
end;</syntaxhighlight>     
  
 
Now add "FEdit.Height:=18;". It should look like:
 
Now add "FEdit.Height:=18;". It should look like:
  
<delphi>function TStringEditLink.BeginEdit: Boolean; stdcall;
+
<syntaxhighlight lang=pascal> function TStringEditLink.BeginEdit: Boolean; stdcall;
  
// Notifies the edit link that editing can start now. Descentants may cancel node edit
+
// Notifies the edit link that editing can start now. Descentants may cancel node edit
// by returning False.
+
// by returning False.
  
begin
+
begin
 
   Result := not FStopping;
 
   Result := not FStopping;
 
   if Result then
 
   if Result then
Line 756: Line 779:
 
     FEdit.Height:=18; // <--- Added this line.
 
     FEdit.Height:=18; // <--- Added this line.
 
   end;
 
   end;
end;</delphi>
+
  end;</syntaxhighlight>
  
 
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.
 
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.
Line 764: Line 787:
  
 
* [http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_Pascal Programando en Pascal] - Spanish tutorial focused on FPC/Lazarus, hosted in Wikibooks.
 
* [http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_Pascal Programando en Pascal] - Spanish tutorial focused on FPC/Lazarus, hosted in Wikibooks.
 
[[Category:Tutorials]]
 
 
  
 
(In progress)
 
(In progress)
  
 
[En desarrollo]
 
[En desarrollo]

Latest revision as of 08:25, 3 March 2020

English (en) español (es) français (fr) polski (pl) русский (ru)

   Aqui hay algunos ejemplos acerca de como usar el control VirtualTreeview para Lazarus (probado en win32). La mayoría de estos ejemplos han sido recolectados de la web, escritos para delphi, y de los documentos o tutoriales por Philipp Frenzel y Mike Lischke. Los documentos o tutoriales pueden ser descargados desde http://www.soft-gems.net . Abajo, usted puede encontrar alguna forma rapida de como utilizar VirtualTreeview en Lazarus, no explicaciones detalladas. Para más explicaciones y otros métodos o funciones, obtenga los documentos oficiales y el tutorial.

Ejemplo Tree Listview basico con 3 columnas

1. Instalar el componente. Ejecutar Lazarus.

2. Arrastre un componente TVirtualStringTree (bajo la pagina Controles Visuales).

3. Vaya al editor de código (oprima la tecla F12). Bajo la sentencia Uses agregue una unidad - escriba VirtualTrees (si no existe previamente, no confunda con la unidad VirtualStringTree). Se vera de forma igual o similar a :

 uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, VirtualStringTree, VirtualTrees;

4. Vaya al Diseñador de Formularios (oprima la tecla F12). Seleccione el componente Virtual Tree. En el Inspector de Objetos haga clic en Nombre, escriba VST y oprima la tecla Enter (Return). Haga clic en Encabezado (expandalo) -> Columnas, haga clic en el pequeño botón, al lado de "0 elementos". Haga clic 3 veces en el botón agregar para agregar 3 columnas. No cierre esta ventana.

5. En la ventana para Edición de Columna, aparecerá la 3ra. columna como seleccionada. Vaya al Inspector de Objetos. Haga clic en Opciones (expandalo) -> y asigne coAllowClick como False.

6. Haga clic en Texto. Escriba Column2.

7. Haga clic en ancho, escriba 100 y oprima la tecla Enter (Return).

8. Vaya a la ventana para Edición de Columna, seleccione las columnas 1ra. y 2da., y asigne su propiedad como la de arriba (para el campo Texto, use nombres diferentes, ejemplo: Columna0, Columna1).

9. Cierre la ventana para Edición de Columna. Seleccione el componente Virtual Tree en el formulario. En el Inspector de Objetos vaya a Encabezado -> Opciones (expandalo). Asigne coAllowClick como True.

10. Desplacese hacia abajo hasta Style, y asignelo como hsFlatButtons.

11. Desplacese hacia abajo hasta TreeOptions (expandalo) -> MiscOption (expandalo), y asigne toEditable como True. Asigne toGridExtensions como True.

12. Desplacese hacia abajo hasta SelectionOptions (expandalo) -> y asigne toExtendedFocus como True. Asigne toMultiSelect como True. En el Diseñador de Formularios cambie el tamaño del VST (componente Virtual) para para poder visualizar todas las columnas, en caso de que sea necesario.

13. Ahora, para agregar 3 botones en el formulario. Arrastrelos desde la paleta de componentes - Pagina Estándar (Etiquetados como "OK").

14. Haga clic en Button1, en el Inspector de Objetos cambie Titulo a "Añadir Nodo". Haga clic en el Button2, cambie el titulo a "Añadir Hijo". Cambie el titulo de Button3 a "Borrar".

15. Mantenga esto aquí y vaya al editor de código (oprima la tecla F12). En el Editor de Código reemplace la linea:

{$mode objfpc}{$H+}

Con la linea:

{$MODE DELPHI}

16. Bajo la sentencia "implementation" pegue las siguientes lineas de código:

 type
 PTreeData = ^TTreeData;
 TTreeData = record
   Column0: String;
   Column1: String;
   Column2: String;
 end;

17. Vaya al Diseñador de Formularios (oprima la tecla F12). Seleccione el control VST. Vaya al Inspector de Objetos, seleccione la pagina Eventos, desplacese hasta el evento onChange. Haga doble clic en el control combobox.

18. Desplacese hasta el evento onFocusChanged. Haga doble clic y pegue el código siguiente:

 procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex);
 begin
  VST.Refresh;
 end;

19. Desplacese hasta el evento onFreeNode. Haga doble clic y pegue el código siguiente:

 procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
 var
  Data: PTreeData;
 begin
  Data:=VST.GetNodeData(Node);
  if Assigned(Data) then begin
    Data^.Column0 := '';
    Data^.Column1 := '';
    Data^.Column2 := '';
  end;
 end;

20. Desplacese hasta el evento onGetNodeDataSize. Haga doble clic y pegue el código siguiente:

 procedure TForm1.VSTGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
 begin
  NodeDataSize := SizeOf(TTreeData);
 end;

21. Desplacese hasta el evento onGetText. Haga doble clic y pegue el código siguiente:

 procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
 Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  Data: PTreeData;
begin
  Data := VST.GetNodeData(Node);
  case Column of
    0: CellText := Data^.Column0;
    1: CellText := Data^.Column1;
    2: CellText := Data^.Column2;
  end;
end;

22. Oprima la tecla F12 para ir al Diseñador de Formularios. Haga doble clic en el botón "Añadir Nodo". Haga doble clic y pegue el código siguiente:

 procedure TForm1.Button1Click(Sender: TObject);
 Var
  Data: PTreeData;
  XNode: PVirtualNode;
  Rand: Integer;
 Begin
  Randomize;
  Rand := Random(99);
  XNode:=VST.AddChild(nil);
  
  if VST.AbsoluteIndex(XNode) > -1 then
  Begin
   Data := VST.GetNodeData(Xnode);
   Data^.Column0:= 'Uno ' + IntToStr(Rand);
   Data^.Column1:= 'Dos ' + IntToStr(Rand + 10);
   Data^.Column2:= 'Tres ' + IntToStr(Rand - 10);
  End; 
 End;

23. Oprima la tecla F9 para Ejecutar el proyecto y revisarlo. Haga clic en el botón "Añadir Nodo" para agregar un nodo. Si no hay problema alguno, el nodo sera agregado al control V.S.T.

24. Detenga la ejecución del programa. En el Diseñador de Formularios haga doble clic en el botón titulado "Añadir Hijo". Haga doble clic y pegue el código siguiente:

 procedure TForm1.Button2Click(Sender: TObject);
 var
  XNode: PVirtualNode;
  Data: PTreeData;
 begin
  if not Assigned(VST.FocusedNode) then
    Exit;
    
    XNode := VST.AddChild(VST.FocusedNode);
    Data := VST.GetNodeData(Xnode);
    
    Data^.Column0:= 'Ch 1';
    Data^.Column1:= 'Ch 2';
    Data^.Column2:= 'Ch 3';

   VST.Expanded[VST.FocusedNode]:=True;
 end;

25. En el Diseñador de Formularios haga doble clic en el botón titulado "Borrar". Haga doble clic y pegue el código siguiente:

 procedure TForm1.Button3Click(Sender: TObject);
 begin
  VST.DeleteSelectedNodes;
 end;

26. Ejecute el proyecto, oprimiendo la tecla F9 para revisarlo. Haga varias pruebas, agregando algunos nodos principales, nodos hijos y eliminelos.

27. Intente editar un nodo. Seleccione un nodo y oprima la tecla F2, y escriba un nuevo valor. Si puede ver lo que esta escribiendo, entonces, el paso esta bien. De lo contrario, lea la sección siguiente titulada "Cuando la edición de celda no puede verse".

28. Para obtener que el V.S.T. muestre el nuevo valor capturado después de la edición, vaya al Diseñador de Formularios, y seleccione V.S.T. Haga doble clic, en el combo del Inspector de Objetos -> Events -> OnNewText.

   Haga doble clic y pegue el código siguiente:

 procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; NewText: WideString);
 Var
  Data: PTreeData;
 begin
  Data := VST.GetNodeData(Node);
  Case Column of
    0: Data^.Column0:= NewText;
    1: Data^.Column1:= NewText;
    2: Data^.Column2:= NewText;
  End;
 end;

   Hasta ahora, el ejemplo para uso básico, termina aquí. Usted podría arrastrar algunos botones adicionales en el formulario para probar algunos de los comandos mencionados, mas adelante. El paso siguiente, podría ser, desplegar una casilla para marcar o checkbox, imagen, color para tipo de fuente de texto, o agregar un combo al nodo.

  • Otra forma para agregar el nodo raíz:
 procedure TForm1.Button8Click(Sender: TObject);
 begin
  with VST do
  RootNodeCount:=RootNodeCount+1;
 end;
  • Otra forma para agregar un nodo hijo:
 procedure TForm1.Button9Click(Sender: TObject);
 begin
  if Assigned(VST.FocusedNode) Then
  VST.ChildCount[VST.FocusedNode]:=VST.ChildCount[VST.FocusedNode]+1;
 end;
  • Determinar y eliminar los nodos hijos de un nodo:
 procedure TForm1.Button4Click(Sender: TObject);
 Var
  c: Integer;
 begin
  if not Assigned(VST.FocusedNode) then
    Exit;
  If VST.HasChildren[VST.FocusedNode] then
  Begin
    c := VST.ChildCount[VST.FocusedNode];
    VST.DeleteChildren(VST.FocusedNode);
    ShowMessage('Number of deleted child:' + #13#10 + IntToStr(c));
  End;
 end;
  • Eliminar un nodo:
 procedure TForm1.Button5Click(Sender: TObject);
 begin
 {VST.Clear;  //Delete All Nodes}
  if not Assigned(VST.FocusedNode) then
    Exit;
  VST.DeleteNode(VST.FocusedNode);
 end;
  • Buscar y seleccionar un nodo:
 procedure TForm1.Button6Click(Sender: TObject);
 var
  XNode: PVirtualNode;
  Data: PTreeData;
 begin
  XNode:= VST.GetFirst;

  while XNode <> nil do
  begin
    Data:=VST.GetNodeData(XNode);
    if Data^.Column0  = '1' then
    begin
      VST.ClearSelection;
      VST.Selected[XNode]:=True;
      VST.SetFocus;
      break;
    end else
    XNode:= VST.GetNextSibling(XNode);
  end;
 end;
  • Determinar el nodo padre de un nodo:
 procedure TForm1.Button13Click(Sender: TObject);
 var
  XNode: PVirtualNode;
 begin
  if not Assigned(VST.FocusedNode) then
    Exit;
  XNode:=VST.FocusedNode;
  while VST.GetNodeLevel(XNode) > 0 do
    Begin
    XNode := XNode.Parent;
    VST.Selected[XNode]:= True;
    End;
   VST.Refresh;
   VST.SetFocus;
 end;
  • Buscar todos los nodos:
 procedure TForm1.Button7Click(Sender: TObject);
 Var
  XNode: PVirtualNode;
  Data: PTreeData;
 begin
  If VST.GetFirst = nil then Exit;
  XNode:=nil;
  Repeat
    if XNode = nil then XNode:=VST.GetFirst Else XNode:=VST.GetNext(XNode);
    Data:=VST.GetNodeData(XNode);
    If (Data^.Column0 = '1') OR (Data^.Column1 = '1') OR (Data^.Column2 = '1') then
    Begin
      ShowMessage('Found at Node Level : ' + IntToStr(VST.GetNodeLevel(XNode)) );
      break;
    End;
  Until XNode = VST.GetLast();
 end;
  • Buscar el nodo siguiente:
 procedure TForm1.Button8Click(Sender: TObject);
 var
  XNode: PVirtualNode;
  Data: PTreeData;
 begin
  if not Assigned(VST.GetFirst) then
    Exit
  else
    XNode := VST.GetFirst;
  repeat
    XNode := VST.GetNext(XNode);
    Data := VST.GetNodeData(XNode);
    if Pos(LowerCase(SearchEdit.Text), LowerCase(Data^.Column0)) > 0 then
    begin
      VST.FocusedNode := XNode;
      VST.Selected[XNode] := True;
      if MessageDlg('Item found?', mtConfirmation, mbYesNo, 0) = mrYes then
      begin
        VST.Expanded[XNode] := True;
        VST.Refresh;
        VST.SetFocus;
        Break;
      end;
    end;
  until XNode = VST.GetLast;
 end;
  • Insertar Nodo:
 procedure TForm1.Button12Click(Sender: TObject);
 var
  XNode: PVirtualNode;
 begin
  If Assigned(VST.FocusedNode) then
  begin
     XNode := VST.InsertNode(VST.FocusedNode,amInsertBefore);
     // To Insert After Selected Node.
     {XNode := VST.InsertNode(VST.FocusedNode,amInsertAfter);}
     VST.Refresh;
  end;
 end;
  • Asignar la altura de un nodo:
 procedure TForm1.Button14Click(Sender: TObject);
 begin
   If Assigned(VST.FocusedNode) then
   VST.NodeHeight[VST.FocusedNode] := 32;
 end;
  • Guardar y Cargar:

   El arbol simple (sin columnas), puede ser guardado y recargado con:

 VST.SaveToFile('filename.dat');
 VST.LoadFromFile('filename.dat');

   Para guardar y cargar el ejemplo mencionado arriba, coloque 2 botones en el formulario, cambie el título de un botón a "Guardar", y el titulo del otro botón a "Cargar". Seleccione el V.S.T., En el Inspector de Objetos -> TreeOptions -> StringOptions. Asegurese, que el valor de la propiedad toSaveCaptions este asignada como True. Vaya a la pagina del Inspector de Eventos Events. Desplazece hasta OnLoadNode, haga doble cilc y pegue el codigo siguiente:

 procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Stream: TStream);
 Var
  Data: PTreeData;
  Len: Integer;
 begin
  Data := VST.GetNodeData(Node);
  Stream.read(Len, SizeOf(Len));
  SetLength(Data^.Column0, Len);
  Stream.read(PChar(Data^.Column0)^, Len);

  Stream.read(Len, SizeOf(Len));
  SetLength(Data^.Column1, Len);
  Stream.read(PChar(Data^.Column1)^, Len);

  Stream.read(Len, SizeOf(Len));
  SetLength(Data^.Column2, Len);
  Stream.read(PChar(Data^.Column2)^, Len);
 end;

 Otra vez, en la pagina Events del Inspector de Objetos, desplazece hasta OnSaveNode, haga doble cilc y pegue el codigo siguiente:

 procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Stream: TStream);
 Var
  Data: PTreeData;
  Len: Integer;
 begin
  Data := VST.GetNodeData(Node);
  Len := Length(Data^.Column0);
  Stream.write(Len, SizeOf(Len));
  Stream.write(PChar(Data^.Column0)^, Len);

  Len := Length(Data^.Column1);
  Stream.write(Len, SizeOf(Len));
  Stream.write(PChar(Data^.Column1)^, Len);

  Len := Length(Data^.Column2);
  Stream.write(Len, SizeOf(Len));
  Stream.write(PChar(Data^.Column2)^, Len);
 end;

   En el Diseñador de Formularios, haga doble clic en el botón titulado "Save" o "Guargar", y pegue el codigo siguiente:

  procedure TForm1.Button10Click(Sender: TObject);
 begin
 VST.SaveToFile('C:\vst.dat');
 end;

  En el Diseñador de Formularios, haga doble clic en el botón titulado "Load" o "Cargar", y pegue el codigo siguiente:

procedure TForm1.Button11Click(Sender: TObject);
begin
  VST.LoadFromFile('C:\vst.dat');
end;

   Ahora, haga pruebas, para guardar y volver a cargar el arbol.

  • Problema de desplazamiento

   El encabezado de control vistaarbol desaparece parcialmente o completamente al desplazarse. No pude encontrar una buena solucion a esto. Una forma de sobrepasar esto, es asignar la altura del encabezado a 0, y utilizar una etiqueta generica para las columnas, y todas las columnas estan visibles sin desplazamiento horizontal. O, la altura del encabezado puede ser asignada un valor mas alto, entre 25 o 30. El metodo VST.Refresh puede ser asignado al evento OnScroll.

  • Cambiar el tamaño de las columnas

   No fue posible cambiar el tamaño de las columnas, arrastrando el ratón en el encabezado del V.S.T. Tal vez, sea debido al "bug" del encabezado, o tal vez, omiti algo. En caso de que la causa haya sido el encabezado, tal vez sea corregido en la siguiente version de Lazarus. Puede ver este enlace: http://bugs.freepascal.org/view.php?id=11209

   De cualquier forma, es posible cambiar el tamaño de las columnas por medio de codigo. Cuando presione mantenga presionado el botón derecho del ratón, y gire la rueda arriba, el ancho de la columna seleccionada se incrementa, y manteniendo presionado abajo, el botón derecho del ratón y girando hacia abjo la rueda del ratón, podra decrementar el ancho de la columna seleccionada. Para hacer esto:

1. Agregue una variable en el editor de codigo llamada como CurCol: Integer; Se vera como esto:

 var
  Form1: TForm1; 
  CurCol: Integer; // <- Agregue solo esta linea.

 implementation

 { TForm1 }

2. En el Diseñador de Formularios, haga doble clic en el formulario para generar un procedimiento para el evento OnCreate. En el procedimiento OnCreate, escriba Form1.OnMouseWheelUp:= y presione Ctrl+Shift+C, esto completara el codigoy hara el esqueleto del procedimiento para el evento MouseWheelUp. ahora, regrese al procedimiento TForm1.FormCreate(Sender: TObject); Y agregue otro procedimiento, esta vez para el evento MouseWheelDown. Escriba Form1.OnMouseWheelDown:= y oprima la combinacion de teclas Ctrl+Shift+C, para generar el procedimiento para el evento MouseWheelDown. El procedimiento FormCreate quedará asi:

 procedure TForm1.FormCreate(Sender: TObject);
 begin
  Form1.OnMouseWheelUp:=@Form1MouseWheelUp;
  Form1.OnMouseWheelDown:=@Form1MouseWheelDown;
 end;

3. Capture el procedimiento para el evento TForm1.Form1MouseWheelUp procedure como:

 procedure TForm1.Form1MouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
 begin
 If VST.Focused then
   if ssRight in Shift then
 VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width + 10;
 end;

4. Capture el procedimiento para el evento TForm1.Form1MouseWheelDown procedure como:

 procedure TForm1.Form1MouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
 begin
  If VST.Focused then
   if ssRight in Shift then
 VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width - 10;
 end;

5. Vaya al Diseñador de Formularios (puede oprimir F12), seleccione el V.S.T., En la pagina Events, del Inspector de Objetos, desplazece hasta OnFocusChanged, haga doble clic y pegue el codigo siguiente:

 procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex);
 begin
  CurCol:=Column;
 end;

   Cuando ejecute el programa, haga clic en una columna, después mantenga presionado abajo, el botón derecho del ratón, y gire la rueda arriba, para incrementar el ancho. Gire la rueda abajo decrementar los valores mencionados.

  Podria modificar los procedimientos anteriores, para ajustar un poco el resultado, si es necesario. O, agregar algun evento para el teclado, con algo como if (key=187) and (ssShift in Shift) then para utilizar la combinacion de teclas "Shift" y "+".

Casillas de verificación ( "Checkboxes" )

   En el Diseñador de Formularios selecciona el control V.S.T. y desplazate hasta:

  1. Inspector de Objetos -> Propiedades -> CheckImageKind y seleccione ckDarkCheck.
  2. Inspector de Objetos -> Propiedade -> TreeOptions -> MiscOptions -> toCheckSupport y asignelo como True.

   Ahora, cambia a la página de Eventos.

  • Desplazate hasta el evento OnInitNode. Haz doble clic y pega el código siguiente:
 procedure TForm1.VSTInitNode(Sender: TBaseVirtualTree; ParentNode,
  Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
 Var
  Level: Integer;
 begin
  Level := VST.GetNodeLevel(Node);
  if Level = 0 then
    Node.CheckType:=ctCheckBox;

  if Level = 2 then
    Node.CheckType:=ctRadioButton;

  if Level = 1 then
  begin
    Node.CheckType:=ctTriStateCheckBox;
    Node.CheckState := csCheckedNormal;
  end;

  if Level = 3 then
    Node.CheckType:=ctButton;
 end;

   Ejecuta el programa, y agrega el nodo raiz y nodos hijos, y posteriormente, nodos hijos a los nodos hijos, y revisa marcar y desmarcar las casillas correctamente. Cuando no sea el caso, cierra el programa. Ve a la pestaña Eventos del Inspector de Eventos.

  • Deslizate al evento OnChecked, haz doble clic y pega el texto siguiente:
 procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
 begin
   vst.Refresh;
 end;
  • Va hasta el evento OnChecking, haz doble clic y pege el texto siguiente:
 procedure TForm1.VSTChecking(Sender: TBaseVirtualTree; Node: PVirtualNode;
 var NewState: TCheckState; var Allowed: Boolean);
 begin
  VST.Refresh;
 end;

   Esperemos que ahora funcione. Para determinar el estado actual de la casilla escribe algo como:

 If XNode.CheckState = csCheckedNormal then ShowMessage('Marcado.');
  • Otros estados son:
    • csUncheckedNormal : Sin marcar y sin presionar
    • csUncheckedPressed : Sin marcar y presionado
    • csCheckedNormal : Marcado y sin presionar
    • csCheckedPressed : Marcado y presionado
    • csMixedNormal : Casilla de 3 estados y sin presionar
    • csMixedPressed : Casilla de 3 estados y presionados</syntaxhighlight>
  • Otros tipos son:
    • ctNone : Sin asignar
    • ctTriStateCheckBox : casilla de 3 estados
    • ctCheckBox : casilla estándar de 2 estados
    • ctRadioButton : Botón tipo Radio, en vez de casilla
    • ctButton : botón estándar</syntaxhighlight>
  • Para capturar el evento Clic del boton o casilla (ctButton)

  Ve a la pestaña Eventos del Inspector de Objetos. Desplazace al evento OnChecked, haz doble clic y pega el texto siguiente:

procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
 begin
  if Node.CheckType = ctButton then
  ShowMessage('Correcto');
  VST.Refresh;
 end;

Fin de Casillas.

Imagenes

To show image on VST nodes, a list of image should be created.

  • 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/
  • Now on the Form Designer select VST, and on Object Inspector's Properties tab, scroll to Images and select ImageList1
  • On Object Inspector's Events tab scroll to OnGetImageIndex, double click and paste:
procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
  var ImageIndex: Integer);
begin
  if Kind in [ikNormal , ikSelected] then // Either Selected or not
  begin
    if Column = 0 then                    // if 1st Column
      ImageIndex:=0;                      // 1st Image of the ImageList1

    if Column = 1 then                    // if 2nd Column
      ImageIndex:=1;                      // 2nd Image of the ImageList1

    if Sender.FocusedNode = Node then     // Only show if Focused
      if Column =2 then                    // if 3rd Column
        ImageIndex:=2;                      // 3rd Image of the ImageList1
  end;
  {Sender.NodeHeight[node]:=40; //If Image is big}
end;

Font Colour

On the Form Designer select VST, and on Object Inspector's Events tab, scroll to OnPaintText, double click and paste:

procedure TForm1.VSTPaintText(Sender: TBaseVirtualTree;
  const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  TextType: TVSTTextType);
Var
  Data: PTreeData;
begin
  Data := VST.GetNodeData(Node);
 
  if Data^.Column0 = 'sky' then
    TargetCanvas.Font.Color:=clBlue;
  
  if Column = 1 then
  begin
    TargetCanvas.Font.Color:=clRed;
    TargetCanvas.Font.Style:= Font.Style + [fsItalic];
  end;
 
  if Column = 2 then
  begin
//  ImageList1.Draw(Form1.Canvas,-1,-1,2); {draw top left of form, 3rd image of ImageList1??}
    TargetCanvas.Font.Size:= 9;
    TargetCanvas.Font.Color:=clHighlightText;
  end;
end;

Adding A Combobox

  • 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.
  • 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:
 uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
  VirtualStringTree, VirtualTrees, combo;
  • The combo.pas unit
 unit combo;

 {$mode delphi}

 interface

 uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
  VirtualStringTree, VirtualTrees, messages, windows, StdCtrls;

 type
  TStringEditLink = class(TInterfacedObject, IVTEditLink)
  private
    FEdit: TWinControl;
    FTree: TVirtualStringTree;
    FNode: PVirtualNode;
    FColumn: Integer;
  protected
    procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  public
    destructor Destroy; override;
    function BeginEdit: Boolean; stdcall;
    function CancelEdit: Boolean; stdcall;
    function EndEdit: Boolean; stdcall;
    function GetBounds: TRect; stdcall;
    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
    procedure ProcessMessage(var Message: TMessage); stdcall;
    procedure SetBounds(R: TRect); stdcall;
  end;

 implementation

 destructor TStringEditLink.Destroy;
 begin
  FEdit.Free;
  inherited;
 end;

 procedure TStringEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
 begin
  case Key of
    VK_ESCAPE:
      begin
        FTree.CancelEditNode;
        Key := 0;
        FTree.setfocus;
      end;
    VK_RETURN:
      begin
       PostMessage(FTree.Handle, WM_KEYDOWN, VK_DOWN, 0);
       Key := 0;
       FTree.EndEditNode;
       FTree.setfocus;
      end;
  End; //case
 end;

 function TStringEditLink.BeginEdit: Boolean;
 begin
  Result := True;
  //FEdit.Height:=(FTree.DefaultNodeHeight - 1); //Needed for editbox. Not combo
  FEdit.Show;
  TComboBox(FEdit).DroppedDown:=True;
  FEdit.SetFocus;
 end;

 function TStringEditLink.CancelEdit: Boolean;
 begin
  Result := True;
  FEdit.Hide;
 end;

 function TStringEditLink.EndEdit: Boolean;
 var
  S: WideString;
 begin
  Result := True;
  S:= TComboBox(FEdit).Text;
  FTree.Text[FNode, FColumn] := S;

  FTree.InvalidateNode(FNode);
  FEdit.Hide;
  FTree.SetFocus;
 end;

 function TStringEditLink.GetBounds: TRect;
 begin
  Result := FEdit.BoundsRect;
 end;

 function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean;
 begin
  Result := True;
  FTree := Tree as TVirtualStringTree;
  FNode := Node;
  FColumn := Column;

  FEdit.Free;
  FEdit := nil;

  FEdit := TComboBox.Create(nil);
   with FEdit as TComboBox do
     begin
          Visible := False;
          Parent := Tree;
          Items.Add('Google');
          Items.Add('Yahoo');
          Items.Add('Altavista');
          OnKeyDown := EditKeyDown;
      end;
 end;

 procedure TStringEditLink.ProcessMessage(var Message: TMessage);
 begin
  FEdit.WindowProc(Message);
 end;

 procedure TStringEditLink.SetBounds(R: TRect);
 var
  Dummy: Integer;
 begin
  FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right);
  FEdit.BoundsRect := R;
 end;

 End.
  • 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.
  • Switch to Object Inspector's Events tab. Scroll to OnCreateEditor, double click and paste:
 procedure TForm1.VSTCreateEditor(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink);
 begin
  EditLink:=TStringEditLink.Create;
 end;
  • On Object Inspector's Events tab. Scroll to OnNewText, double click and paste:
 procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; NewText: WideString);
 Var
  Data: PTreeData;
 begin
  Data := VST.GetNodeData(Node);
  Case Column of
    0: Data^.Column0:= NewText;
    1: Data^.Column1:= NewText;
    2: Data^.Column2:= NewText;
  End;
 end;

Run program, select a node and press F2 to get combobox. On pressing Enter new value should appear on the node.

If Cell Editing Can't Be Seen

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:

 function TStringEditLink.BeginEdit: Boolean; stdcall;

 // Notifies the edit link that editing can start now. Descentants may cancel node edit
 // by returning False.

 begin
  Result := not FStopping;
  if Result then
  begin
    FEdit.Show;
    FEdit.SelectAll;
    FEdit.SetFocus;
  end;
 end;

Now add "FEdit.Height:=18;". It should look like:

 function TStringEditLink.BeginEdit: Boolean; stdcall;

 // Notifies the edit link that editing can start now. Descentants may cancel node edit
 // by returning False.

 begin
  Result := not FStopping;
  if Result then
  begin
    FEdit.Show;
    FEdit.SelectAll;
    FEdit.SetFocus;
    FEdit.Height:=18; // <--- Added this line.
  end;
  end;

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.


External links

(In progress)

[En desarrollo]