Ir al contenido


Foto

Guardar y abrir datos en VirtualTreeview


  • Por favor identifícate para responder
10 respuestas en este tema

#1 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 19 febrero 2017 - 10:33

buenas amigos, tiempo que no les saludos :)

tengo un pequeño problema si me pueden dar la mano.

 

Lo que pasa es que estoy empezando a usar el componente VirtualTreeview como reemplazo al clásico Listview, he comenzado aprendiendo a como agregar datos e íconos, pero quisiera saber como puedo grabar todo lo que tenga en el VirtualTreeview para luego poder abrirlo y seguir trabajando.

 

Le adjunto un proyecto que estoy haciendo.

 

http://www.mediafire...st lazarus 1.7z


  • 0

#2 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 109 mensajes

Escrito 20 febrero 2017 - 08:31

Hola, al parecer VirtualTreeView tiene un par de eventos para cargar y guardar según la wiki de Free Pascal fijate que tiene un código de ejemplo para guardar en disco y cargar. El ejemplo es largo, busca "Save And Load" en la página, para mi está bien explicado, aunque en inglés.

 

Saludos.


  • 0

#3 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 21 febrero 2017 - 02:22

Gracias amigo por su respuesta, he revisado su link, acabo de hacer unas pruebas pero no se que estoy haciendo mal, pues si logro grabar los datos, pero cuando los quiero abrir me sale el mensaje "El proyecto prueba ha lanzado una excepción de la clase 'External:SIGSEGV", les adjunto el code que uso:


php
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, VirtualTrees, Forms, Controls, Graphics, Dialogs,
  9.   StdCtrls;
  10.  
  11. type
  12.   PData = ^TData;
  13.   TData = record
  14.     Fnombre: String;
  15.     Fapellido: String;
  16.     Fedad: String;
  17.     Ftrabajando: String;
  18.     FImageIndex: Integer;
  19.   end;
  20.  
  21.   { TForm1 }
  22.  
  23.   TForm1 = class(TForm)
  24.     Button1: TButton;
  25.     Button2: TButton;
  26.     Button3: TButton;
  27.     Button4: TButton;
  28.     ImageList1: TImageList;
  29.     VST: TVirtualStringTree;
  30.     procedure Button1Click(Sender: TObject);
  31.     procedure Button2Click(Sender: TObject);
  32.     procedure Button3Click(Sender: TObject);
  33.     procedure Button4Click(Sender: TObject);
  34.     procedure FormCreate(Sender: TObject);
  35.     procedure VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
  36.       Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
  37.       var ImageIndex: Integer);
  38.     procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  39.       Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
  40.     procedure VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  41.       Stream: TStream);
  42.     procedure VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  43.       Stream: TStream);
  44.   private
  45.     { private declarations }
  46.   public
  47.     { public declarations }
  48.   end;
  49.  
  50. var
  51.   Form1: TForm1;
  52.  
  53. implementation
  54.  
  55. {$R *.lfm}
  56.  
  57. { TForm1 }
  58.  
  59. procedure TForm1.FormCreate(Sender: TObject);
  60. begin
  61.  
  62.  
  63. procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
  64.   Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
  65.   var ImageIndex: Integer);
  66.   var
  67.     Data: PData;
  68.   begin
  69.     if Column = 1 then
  70.     begin
  71.       Data := VST.GetNodeData(Node);
  72.       ImageIndex := Data^.FImageIndex;
  73.     end;
  74.   end;
  75.  
  76. procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  77.   Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
  78.   var
  79.     Data: PData;
  80.   begin
  81.     // si no existen estos codes, el resultado sera el texto    "NODE"
  82.     Data := VST.GetNodeData(Node);
  83.     case Column of
  84.       0: CellText := '';
  85.       1: CellText := Data^.Fnombre;
  86.       2: CellText := Data^.Fapellido;
  87.       3: CellText := Data^.Fedad;
  88.       4: CellText := Data^.Ftrabajando;
  89.       //4: CellText := Data^.FImageIndex;
  90.     end;
  91.   end;
  92.  
  93. procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  94.   Stream: TStream);
  95.   var
  96.     Data: Pdata;
  97.     Len: Integer;
  98.   begin
  99.     Data := VST.GetNodeData(Node);
  100.     Stream.read(Len, SizeOf(Len));
  101.     SetLength(Data^.Fnombre, Len);
  102.     Stream.read(PChar(Data^.Fnombre)^, Len);
  103.  
  104.     Stream.read(Len, SizeOf(Len));
  105.     SetLength(Data^.Fapellido, Len);
  106.     Stream.read(PChar(Data^.Fapellido)^, Len);
  107.  
  108.     Stream.read(Len, SizeOf(Len));
  109.     SetLength(Data^.Fedad, Len);
  110.     Stream.read(PChar(Data^.Fedad)^, Len);
  111.  
  112.     Stream.read(Len, SizeOf(Len));
  113.     SetLength(Data^.Ftrabajando, Len);
  114.     Stream.read(PChar(Data^.Ftrabajando)^, Len);
  115.   end;
  116.  
  117. procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  118.   Stream: TStream);
  119.   var
  120.      data: Pdata;
  121.      len: Integer;
  122.   begin
  123.   Data := VST.GetNodeData(Node);
  124.   Len := Length(Data^.Fnombre);
  125.   Stream.write(Len, SizeOf(Len));
  126.   Stream.write(PChar(Data^.Fnombre)^, Len);
  127.  
  128.   Len := Length(Data^.Fapellido);
  129.   Stream.write(Len, SizeOf(Len));
  130.   Stream.write(PChar(Data^.Fapellido)^, Len);
  131.  
  132.   Len := Length(Data^.Fedad);
  133.   Stream.write(Len, SizeOf(Len));
  134.   Stream.write(PChar(Data^.Fedad)^, Len);
  135.  
  136.   Len := Length(Data^.Ftrabajando);
  137.   Stream.write(Len, SizeOf(Len));
  138.   Stream.write(PChar(Data^.Ftrabajando)^, Len);
  139.  
  140.   end;
  141.  
  142. procedure TForm1.Button1Click(Sender: TObject); // botón para agregar datos
  143.   var
  144.   Data: PData;
  145.   Node: PVirtualNode;
  146. begin
  147.   VST.Clear;
  148.   VST.NodeDataSize := SizeOf(TData);
  149.  
  150.   Node := VST.AddChild(nil);
  151.   Data := VST.GetNodeData(Node);
  152.   Data^.Fnombre := 'erick';
  153.   Data^.Fapellido := 'student';
  154.   Data^.Fedad := '18';
  155.   Data^.Ftrabajando := 'si';
  156.   Data^.FImageIndex := 0;
  157.  
  158.   Node := VST.AddChild(nil);
  159.   Data := VST.GetNodeData(Node);
  160.   Data^.Fnombre := 'magui';
  161.   Data^.Fapellido := 'enfermera';
  162.   Data^.Fedad := '25';
  163.   Data^.Ftrabajando := 'no';
  164.   Data^.FImageIndex := 1;
  165.  
  166.   Node := VST.AddChild(nil);
  167.   Data := VST.GetNodeData(Node);
  168.   Data^.Fnombre := 'leo';
  169.   Data^.Fapellido := 'ingenier';
  170.   Data^.Fedad := '30';
  171.   Data^.Ftrabajando := 'si';
  172.   Data^.FImageIndex := 2;
  173.  
  174.  
  175. procedure TForm1.Button2Click(Sender: TObject); // botón para guardar
  176. begin
  177.   VST.SaveToFile('filename.dat');
  178.  
  179.  
  180. procedure TForm1.Button3Click(Sender: TObject); // botón para abrir
  181. begin
  182.   VST.LoadFromFile('filename.dat');
  183.  
  184. procedure TForm1.Button4Click(Sender: TObject);
  185. begin
  186.   VST.Clear;
  187.  

Porfavor si me pueden ayudar. :(
 


  • 0

#4 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 109 mensajes

Escrito 21 febrero 2017 - 03:33

Me parece que el problema pasa por la primer columna (0) que no estás guardando ni cargando, por eso el error te lo tira al intentar cargar los datos.

 

Saludos.


  • 0

#5 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 21 febrero 2017 - 09:40

acabo de hacer unos ajustes al proyecto y he empezado a usar la column 0, pero me sigue saliendo el error amigo, que podrá ser....

Otra cosa que me di cuenta es que cuando el programa esta activo si guardo y abro sin cerrar el programa entonces si carga la data, pero si guardo luego cierro la app, al momento de volverlo a abrir el programa y de cargar los datos ahí si me sale el error.

 

Les adjunto los codes que acabo de modificar, al igual que con otros code que trate de implementar pero el mismo error.


php
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, VirtualTrees, Forms, Controls, Graphics, Dialogs,
  9.   StdCtrls;
  10.  
  11. type
  12.   PData = ^TData;
  13.   TData = record
  14.     Fnombre: String;
  15.     Fapellido: String;
  16.     Fedad: String;
  17.     Ftrabajando: String;
  18.     FImageIndex: Integer;
  19.   end;
  20.  
  21.   { TForm1 }
  22.  
  23.   TForm1 = class(TForm)
  24.     Button1: TButton;
  25.     Button2: TButton;
  26.     Button3: TButton;
  27.     Button4: TButton;
  28.     ImageList1: TImageList;
  29.     VST: TVirtualStringTree;
  30.     procedure Button1Click(Sender: TObject);
  31.     procedure Button2Click(Sender: TObject);
  32.     procedure Button3Click(Sender: TObject);
  33.     procedure Button4Click(Sender: TObject);
  34.     procedure FormCreate(Sender: TObject);
  35.     procedure VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
  36.       Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
  37.       var ImageIndex: Integer);
  38.     procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  39.       Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
  40.     procedure VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  41.       Stream: TStream);
  42.     procedure VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  43.       Stream: TStream);
  44.   private
  45.     { private declarations }
  46.   public
  47.     { public declarations }
  48.   end;
  49.  
  50. var
  51.   Form1: TForm1;
  52.  
  53. implementation
  54.  
  55. {$R *.lfm}
  56.  
  57. { TForm1 }
  58.  
  59. procedure TForm1.FormCreate(Sender: TObject);
  60. begin
  61.  
  62.  
  63. procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
  64.   Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
  65.   var ImageIndex: Integer);
  66.   var
  67.     Data: PData;
  68.   begin
  69.     if Column = 0 then
  70.     begin
  71.       Data := VST.GetNodeData(Node);
  72.       ImageIndex := Data^.FImageIndex;
  73.     end;
  74.   end;
  75.  
  76. procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  77.   Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
  78.   var
  79.     Data: PData;
  80.   begin
  81.  
  82.     // si no existen estos codes, el resultado sera el texto    "NODE"
  83.     Data := VST.GetNodeData(Node);
  84.     case Column of
  85.       //0: CellText := '';
  86.       0: CellText := Data^.Fnombre;
  87.       1: CellText := Data^.Fapellido;
  88.       2: CellText := Data^.Fedad;
  89.       3: CellText := Data^.Ftrabajando;
  90.       //4: CellText := Data^.FImageIndex;
  91.     end;
  92.  
  93.   end;
  94.  
  95. procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  96.   Stream: TStream);
  97.   var
  98.     Data: Pdata;
  99.     Len: Integer;
  100.   begin
  101.     Data := VST.GetNodeData(Node);
  102.  
  103.         Stream.Read(Len, SizeOf(Len));
  104.   SetLength(Data^.Fnombre, Len);
  105.   Stream.Read(PChar(Data^.Fnombre)^, Len * SizeOf(Data^.Fnombre[1]));
  106.  
  107.       Stream.Read(Len, SizeOf(Len));
  108.   SetLength(Data^.Fapellido, Len);
  109.   Stream.Read(PChar(Data^.Fapellido)^, Len * SizeOf(Data^.Fapellido[1]));
  110.  
  111.       Stream.Read(Len, SizeOf(Len));
  112.   SetLength(Data^.Fedad, Len);
  113.   Stream.Read(PChar(Data^.Fedad)^, Len * SizeOf(Data^.Fedad[1]));
  114.  
  115.       Stream.Read(Len, SizeOf(Len));
  116.   SetLength(Data^.Ftrabajando, Len);
  117.   Stream.Read(PChar(Data^.Ftrabajando)^, Len * SizeOf(Data^.Ftrabajando[1]));
  118.  
  119.  
  120.   // SEGUNDO INTENTO, Obtenido de buscar en la web
  121.   {Stream.Read(Len, SizeOf(Len));
  122.   SetLength(Data^.Fnombre, Len);
  123.   Stream.Read(PChar(Data^.Fnombre)^, Len * SizeOf(Char));
  124.  
  125.   Stream.Read(Len, SizeOf(Len));
  126.   SetLength(Data^.Fapellido, Len);
  127.   Stream.Read(PChar(Data^.Fapellido)^, Len * SizeOf(Char));
  128.  
  129.   Stream.Read(Len, SizeOf(Len));
  130.   SetLength(Data^.Fedad, Len);
  131.   Stream.Read(PChar(Data^.Fedad)^, Len * SizeOf(Char));
  132.  
  133.   Stream.Read(Len, SizeOf(Len));
  134.   SetLength(Data^.Ftrabajando, Len);
  135.   Stream.Read(PChar(Data^.Ftrabajando)^, Len * SizeOf(Char));}
  136.  
  137.  
  138.  
  139.  
  140.     // PRIMER INTENTO, SACADO DE http://wiki.freepascal.org/VirtualTreeview_Example_for_Lazarus
  141.     {Stream.read(Len, SizeOf(Len));
  142.     SetLength(Data^.Fnombre, Len);
  143.     Stream.read(PChar(Data^.Fnombre)^, Len);
  144.  
  145.     Stream.read(Len, SizeOf(Len));
  146.     SetLength(Data^.Fapellido, Len);
  147.     Stream.read(PChar(Data^.Fapellido)^, Len);
  148.  
  149.     Stream.read(Len, SizeOf(Len));
  150.     SetLength(Data^.Fedad, Len);
  151.     Stream.read(PChar(Data^.Fedad)^, Len);
  152.  
  153.     Stream.read(Len, SizeOf(Len));
  154.     SetLength(Data^.Ftrabajando, Len);
  155.     Stream.read(PChar(Data^.Ftrabajando)^, Len);}
  156.   end;
  157.  
  158. procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  159.   Stream: TStream);
  160.   var
  161.      data: Pdata;
  162.      len: Integer;
  163.   begin
  164.   Data := VST.GetNodeData(Node);
  165.  
  166. Len := Length(Data^.Fnombre);
  167. Stream.Write(Len, SizeOf(Len));
  168. Stream.Write(PChar(Data^.Fnombre)^, Length(Data^.Fnombre) * SizeOf(Data^.Fnombre[1]));
  169.  
  170. Len := Length(Data^.Fapellido);
  171. Stream.Write(Len, SizeOf(Len));
  172. Stream.Write(PChar(Data^.Fapellido)^, Length(Data^.Fapellido) * SizeOf(Data^.Fapellido[1]));
  173.  
  174. Len := Length(Data^.Fedad);
  175. Stream.Write(Len, SizeOf(Len));
  176. Stream.Write(PChar(Data^.Fedad)^, Length(Data^.Fedad) * SizeOf(Data^.Fedad[1]));
  177.  
  178. Len := Length(Data^.Ftrabajando);
  179. Stream.Write(Len, SizeOf(Len));
  180. Stream.Write(PChar(Data^.Ftrabajando)^, Length(Data^.Ftrabajando) * SizeOf(Data^.Ftrabajando[1]));
  181.  
  182.  
  183.   // SEGUNDO INTENTO, Obtenido de buscar en la web
  184.   {Len := Length(Data^.Fnombre);
  185.   Stream.Write(Len, SizeOf(Len));
  186.   Stream.Write(PChar(Data^.Fnombre)^, Length(Data^.Fnombre) * SizeOf(Char));
  187.  
  188.   Len := Length(Data^.Fapellido);
  189.   Stream.Write(Len, SizeOf(Len));
  190.   Stream.Write(PChar(Data^.Fapellido)^, Length(Data^.Fapellido) * SizeOf(Char));
  191.  
  192.   Len := Length(Data^.Fedad);
  193.   Stream.Write(Len, SizeOf(Len));
  194.   Stream.Write(PChar(Data^.Fedad)^, Length(Data^.Fedad) * SizeOf(Char));
  195.  
  196.   Len := Length(Data^.Ftrabajando);
  197.   Stream.Write(Len, SizeOf(Len));
  198.   Stream.Write(PChar(Data^.Ftrabajando)^, Length(Data^.Ftrabajando) * SizeOf(Char));}
  199.  
  200.  
  201.  
  202.   // PRIMER INTENTO, SACADO DE http://wiki.freepascal.org/VirtualTreeview_Example_for_Lazarus
  203.   {Len := Length(Data^.Fnombre);
  204.   Stream.write(Len, SizeOf(Len));
  205.   Stream.write(PChar(Data^.Fnombre)^, Len);
  206.  
  207.   Len := Length(Data^.Fapellido);
  208.   Stream.write(Len, SizeOf(Len));
  209.   Stream.write(PChar(Data^.Fapellido)^, Len);
  210.  
  211.   Len := Length(Data^.Fedad);
  212.   Stream.write(Len, SizeOf(Len));
  213.   Stream.write(PChar(Data^.Fedad)^, Len);
  214.  
  215.   Len := Length(Data^.Ftrabajando);
  216.   Stream.write(Len, SizeOf(Len));
  217.   Stream.write(PChar(Data^.Ftrabajando)^, Len); }
  218.  
  219.   end;
  220.  
  221. procedure TForm1.Button1Click(Sender: TObject);  // botón para agregar datos
  222.   var
  223.   Data: PData;
  224.   Node: PVirtualNode;
  225. begin
  226.   VST.Clear;
  227.   VST.NodeDataSize := SizeOf(TData);
  228.  
  229.   Node := VST.AddChild(nil);
  230.   Data := VST.GetNodeData(Node);
  231.   Data^.Fnombre := 'erick';
  232.   Data^.Fapellido := 'student';
  233.   Data^.Fedad := '18';
  234.   Data^.Ftrabajando := 'si';
  235.   Data^.FImageIndex := 0;
  236.  
  237.   Node := VST.AddChild(nil);
  238.   Data := VST.GetNodeData(Node);
  239.   Data^.Fnombre := 'magui';
  240.   Data^.Fapellido := 'enfermera';
  241.   Data^.Fedad := '25';
  242.   Data^.Ftrabajando := 'no';
  243.   Data^.FImageIndex := 1;
  244.  
  245.   Node := VST.AddChild(nil);
  246.   Data := VST.GetNodeData(Node);
  247.   Data^.Fnombre := 'leo';
  248.   Data^.Fapellido := 'ingenier';
  249.   Data^.Fedad := '30';
  250.   Data^.Ftrabajando := 'si';
  251.   Data^.FImageIndex := 2;
  252.  
  253.  
  254. procedure TForm1.Button2Click(Sender: TObject);  // botón para guardar
  255. begin
  256.   VST.SaveToFile('filename.dat');
  257.  
  258.  
  259. procedure TForm1.Button3Click(Sender: TObject);  // botón para abrir
  260. begin
  261.   VST.LoadFromFile('filename.dat');
  262.  
  263. procedure TForm1.Button4Click(Sender: TObject);
  264. begin
  265.   VST.Clear;
  266.  

Que podrá ser amigos .... ?
 


  • 0

#6 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 109 mensajes

Escrito 22 febrero 2017 - 12:42

  • Save And Load

Simple tree (without column) can be saved and loaded as:

 

Presté atención a esto que dice el ejemplo de la wiki, árbol simple (sin columna), como desconozco el componente no sé si se aplica a tu proyecto.

 

En el segundo intento:


delphi
  1. Stream.Write(PChar(Data^.Fnombre)^, Length(Data^.Fnombre) * SizeOf(Char));

eso de SizeOf(Char) no va, el parámetro debe ser una variable no un tipo.

 

 

Otra cosa que me di cuenta es que cuando el programa esta activo si guardo y abro sin cerrar el programa entonces si carga la data, pero si guardo luego cierro la app, al momento de volverlo a abrir el programa y de cargar los datos ahí si me sale el error.

 

Y será que realmente los carga del archivo? no puede tener una memoria caché? Si bien el código es más que claro, pero bueno, por ahí es una burrada lo que digo, pero hay que encontrarle la vuelta por algún lado. Podrías agregar otro botón que cargue otros datos, para ver si realmente lee y carga del archivo, es decir, probar con dos conjuntos de datos, A y B, iniciar el programa, cargar A, guardar A, cargar B, leer A. Si eso lo hace correctamente, entonces el método funciona y hay que buscar el error por otro lado.

 

O también puede ser algo mucho más sencillo:


delphi
  1. procedure TForm1.Button11Click(Sender: TObject);
  2. begin
  3. VST.LoadFromFile('C:\vst.dat');
  4. end;

En el ejemplo de la wiki pone el path completo, en tu app no.

 

Saludos.


  • 0

#7 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 22 febrero 2017 - 01:17

Ante todo muchas gracias por su valioso tiempo amigo en ayudarme, le comento que después de tanto buscar y buscarr y luego de haber leido un poco la documentación del componente "VirtualTreeview" he conseguido que el proyecto funcione, le comparto los códigos que use:


php
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, VirtualTrees, Forms, Controls, Graphics, Dialogs,
  9.   StdCtrls;
  10.  
  11. type
  12.   PData = ^TData;
  13.   TData = record
  14.     Fnombre: String;
  15.     Fapellido: String;
  16.     Fedad: String;
  17.     Ftrabajando: String;
  18.     FImageIndex: Integer;
  19.   end;
  20.  
  21.   { TForm1 }
  22.  
  23.   TForm1 = class(TForm)
  24.     Button1: TButton;
  25.     Button2: TButton;
  26.     Button3: TButton;
  27.     Button4: TButton;
  28.     ImageList1: TImageList;
  29.     VST: TVirtualStringTree;
  30.     procedure Button1Click(Sender: TObject);
  31.     procedure Button2Click(Sender: TObject);
  32.     procedure Button3Click(Sender: TObject);
  33.     procedure Button4Click(Sender: TObject);
  34.     procedure Button5Click(Sender: TObject);
  35.     procedure FormCreate(Sender: TObject);
  36.     procedure VSTChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
  37.     procedure VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
  38.       Column: TColumnIndex);
  39.     procedure VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
  40.     procedure VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
  41.       Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
  42.       var ImageIndex: Integer);
  43.     procedure VSTGetNodeDataSize(Sender: TBaseVirtualTree;
  44.       var NodeDataSize: Integer);
  45.     procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  46.       Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
  47.     procedure VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  48.       Stream: TStream);
  49.     procedure VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  50.       Stream: TStream);
  51.   private
  52.     { private declarations }
  53.   public
  54.     { public declarations }
  55.   end;
  56.  
  57. var
  58.   Form1: TForm1;
  59.  
  60. implementation
  61.  
  62. {$R *.lfm}
  63.  
  64. { TForm1 }
  65.  
  66. procedure TForm1.FormCreate(Sender: TObject);
  67. begin
  68.  
  69.  
  70. procedure TForm1.VSTChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
  71. begin
  72.   VST.Refresh;
  73.  
  74. procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
  75.   Column: TColumnIndex);
  76. begin
  77.   VST.Refresh;
  78.  
  79. procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
  80.   var
  81.     Data: PData;
  82.   begin
  83.     Data := VST.GetNodeData(Node);
  84.     if Assigned(Data) then begin
  85.       Data^.Fnombre := '';
  86.       Data^.Fapellido := '';
  87.       Data^.Fedad := '';
  88.       Data^.Ftrabajando := '';
  89.  
  90.     end;
  91.   end;
  92.  
  93. procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
  94.   Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
  95.   var ImageIndex: Integer);
  96.   var
  97.     Data: PData;
  98.   begin
  99.     if Column = 0 then
  100.     begin
  101.       Data := VST.GetNodeData(Node);
  102.       ImageIndex := Data^.FimageIndex;
  103.     end;
  104.   end;
  105.  
  106. procedure TForm1.VSTGetNodeDataSize(Sender: TBaseVirtualTree;
  107.   var NodeDataSize: Integer);
  108. begin
  109.   NodeDataSize := SizeOf(TData);    // este es importantisimo sino sale error exception cuando cargamos un archivos grabado antes
  110.  
  111. procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  112.   Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
  113.   var
  114.     Data: PData;
  115.   begin
  116.  
  117.     // si no existen estos codes, el resultado sera el texto    "NODE"
  118.     Data := VST.GetNodeData(Node);
  119.     case Column of
  120.       //0: CellText := '';
  121.       0: CellText := Data^.Fnombre;
  122.       1: CellText := Data^.Fapellido;
  123.       2: CellText := Data^.Fedad;
  124.       3: CellText := Data^.Ftrabajando;
  125.       //4: CellText := Data^.FImageIndex;
  126.     end;
  127.  
  128.   end;
  129.  
  130. procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  131.   Stream: TStream);
  132.   var
  133.      data: Pdata;
  134.      len: Integer;
  135.   begin
  136.   Data := VST.GetNodeData(Node);   
  137.   Len := Length(Data^.Fnombre);
  138.   Stream.Write(Len, SizeOf(Len));
  139.   Stream.Write(PChar(Data^.Fnombre)^, Length(Data^.Fnombre) * SizeOf(Char));
  140.  
  141.   Len := Length(Data^.Fapellido);
  142.   Stream.Write(Len, SizeOf(Len));
  143.   Stream.Write(PChar(Data^.Fapellido)^, Length(Data^.Fapellido) * SizeOf(Char));
  144.  
  145.   Len := Length(Data^.Fedad);
  146.   Stream.Write(Len, SizeOf(Len));
  147.   Stream.Write(PChar(Data^.Fedad)^, Length(Data^.Fedad) * SizeOf(Char));
  148.  
  149.   Len := Length(Data^.Ftrabajando);
  150.   Stream.Write(Len, SizeOf(Len));
  151.   Stream.Write(PChar(Data^.Ftrabajando)^, Length(Data^.Ftrabajando) * SizeOf(Char));
  152.  
  153. // guardamos las imágenes
  154.   Stream.Write(Data^.FImageIndex, SizeOf(Data^.FImageIndex));   
  155.  
  156.  
  157. procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  158.   Stream: TStream);
  159.   var
  160.     Data: Pdata;
  161.     Len: Integer;
  162.   begin
  163.     Data := VST.GetNodeData(Node);
  164.   Stream.Read(Len, SizeOf(Len));
  165.   SetLength(Data^.Fnombre, Len);
  166.   Stream.Read(PChar(Data^.Fnombre)^, Len * SizeOf(Char));
  167.  
  168.   Stream.Read(Len, SizeOf(Len));
  169.   SetLength(Data^.Fapellido, Len);
  170.   Stream.Read(PChar(Data^.Fapellido)^, Len * SizeOf(Char));
  171.  
  172.   Stream.Read(Len, SizeOf(Len));
  173.   SetLength(Data^.Fedad, Len);
  174.   Stream.Read(PChar(Data^.Fedad)^, Len * SizeOf(Char));
  175.  
  176.   Stream.Read(Len, SizeOf(Len));
  177.   SetLength(Data^.Ftrabajando, Len);
  178.   Stream.Read(PChar(Data^.Ftrabajando)^, Len * SizeOf(Char));
  179.  
  180.   // cargamos las imágenes
  181.   Stream.Read(Data^.FImageIndex, SizeOf(Data^.FImageIndex));  
  182.  
  183.  
  184. procedure TForm1.Button1Click(Sender: TObject);  // botón para agregar datos
  185.   var
  186.   Data: PData;
  187.   Node: PVirtualNode;
  188. begin
  189.   VST.Clear;
  190.   VST.NodeDataSize := SizeOf(TData);
  191.  
  192.   Node := VST.AddChild(nil);
  193.   Data := VST.GetNodeData(Node);
  194.   Data^.Fnombre := 'erick';
  195.   Data^.Fapellido := 'student';
  196.   Data^.Fedad := '18';
  197.   Data^.Ftrabajando := 'si';
  198.   Data^.FImageIndex := 0;
  199.  
  200.   Node := VST.AddChild(nil);
  201.   Data := VST.GetNodeData(Node);
  202.   Data^.Fnombre := 'magui';
  203.   Data^.Fapellido := 'enfermera';
  204.   Data^.Fedad := '25';
  205.   Data^.Ftrabajando := 'no';
  206.   Data^.FImageIndex := 1;
  207.  
  208.   Node := VST.AddChild(nil);
  209.   Data := VST.GetNodeData(Node);
  210.   Data^.Fnombre := 'leo';
  211.   Data^.Fapellido := 'ingenier';
  212.   Data^.Fedad := '30';
  213.   Data^.Ftrabajando := 'si';
  214.   Data^.FImageIndex := 2;
  215.  
  216.  
  217. procedure TForm1.Button2Click(Sender: TObject);  // botón para guardar
  218. begin
  219.   VST.SaveToFile('vst.dat');  // al usarlo asi me guarda el archivo junto a mi app
  220.  
  221.  
  222. procedure TForm1.Button3Click(Sender: TObject);  // botón para abrir
  223. begin
  224.   VST.LoadFromFile('vst.dat'); // abrimos el archivo que esta junto a nuestra app
  225.  
  226. procedure TForm1.Button4Click(Sender: TObject);
  227. begin
  228.   VST.Clear;
  229.  
  230. procedure TForm1.Button5Click(Sender: TObject);
  231. begin
  232.  
  233.  

Le comento amigo Gaston que de momento me esta trabajando bien, voy a seguir haciendo unas pruebas y cualquier cosa le comento, muchas gracias.  :)


  • 1

#8 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 109 mensajes

Escrito 22 febrero 2017 - 02:32

Me alegro mucho Monchito y gracias por el código, ya tengo por donde empezar el día que estudie ese componente que parece muy interesante.

 

Igual sigo sin entender esto: SizeOf(Char)

 

Saludos.


  • 0

#9 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 22 febrero 2017 - 04:12

Me alegro mucho Monchito y gracias por el código, ya tengo por donde empezar el día que estudie ese componente que parece muy interesante.

 

Igual sigo sin entender esto: SizeOf(Char)

 

Saludos.

 

Cuando vas a guardar un string, o texto cualquiera, necesitas primero guardar el tamaño de éste y luego el texto.

Esto es necesario para luego al momento de abrir se sepa cuanto bytes hay que proceder a leer correctamente. El tipo string es un tipo "especial" cuyo tamaño varía de 0 a megas...

 

Lo que hace al algoritmo descripto arriba hace justamente esto:

 

1. Guarda el tamaño del texto

2. Guarda el texto, desde el byte 1 hasta la longitud en bytes del mismo. De esta le forma le indica que guarde exactamente todo el contenido del texto.

 

Al momento de la lectura hace el paso inverso:

1. Lee el tamaño

2. Lee el contenido de dicho tamaño y lo pone en la variable que se le pasa.

 

Cuando hace Len * SizeOf(char) justamente está reservando Len bytes necesarios, ya que un char ocupa 1 byte. En cada byte hay un caracter (1)

 

(1) Aunque esto funcionará siempre y cuando tengamos el control y usemos un juego de caracteres que ocupe exactamente 1 byte cada uno. Lazarus por defecto usa UTF-8, el cual es un formato de longitud variable. Por caso para representar la ñ se necesita 2 bytes mientras que para la n es 1 byte.

Debe tenerse especial cuidado en esto.

 

EDITO:

Ahora que lo repienso. Esto no hay que tenerle miedo ni cuidado. Al hacer Length() sobre un texto en UTF-8 este devolverá el tamaño considerando el sistema variable. Es decir que para la cadena "hola" devolverá justamente 4 y para "ñiño" devolverá 6.

 

Saludos,


  • 0

#10 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 22 febrero 2017 - 04:51

Buenas amigo Dephius, gracias por sus consejos para poder entender como trabaja los códigos, la verdad la mayoría solo los copie y pegue y estuve probando cambiando algunas cosillas, también le comento que hize una prueba rápida y efectivamente también trabaja con Ñ y Tildes, de todas maneras cualquier problema que encuentre les estaré pidiendo una mano. :)

 

Amigo Gaston el componente VirtualTreeView es como un listview con esteroides, trae muchas opciones y es muy personalizable, lo estoy comenzando a usar porque con el listview no podía hacer unas cosas, como por ejemplo hacer un filtrado de datos que contengan imágenes (íconos) tampoco el listview me permite integrarle un "treeview" y cuando uso íconos en un listview siempre aparecen con un marco blanco, según lo que he investigado todas esas cosas y más están resultas en "virtualtreeview" que es un componente creado para esos fines, como yo recién le estoy entrando me estoy encontrando con obstaculos, felizmente pude encontrar un poco de códigos por aquí y otros por allá, también me ayudo el archivo de ayuda del componente.

 

Bueno amigos espero no haberles aburrido con mi conversación, cualquier problema que me encuentre les estaré comunicando, saludos :) :)

 

PD: les adjunto mi pequeño proyecto

http://www.mediafire...ualtreeview.zip

 

Disculpen por usar mediafire, es que por este medio no me permite subirlo.


  • 0

#11 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 109 mensajes

Escrito 22 febrero 2017 - 08:46

 

Cuando hace Len * SizeOf(char) justamente está reservando Len bytes necesarios, ya que un char ocupa 1 byte. En cada byte hay un caracter (1)

 

Delphius, Estaba equivocado, creìa que solo se podìan pasar variables como parametros a la funcion pero veo que tambièn acepta tipos:

 

SizeOf returns the size, in bytes, of any variable or type-identifier.

 

De todas formas SizeOf(Char) siempre va a devolver 1 y multiplicar por 1 mucho sentido no tiene. Es lo que entiendo, desde luego puedo estar equivocado.

 

Monchito, gracias por la descripciòn de VST y mediafire lo pude descargar sin problemas.

 

Perdòn por los acentos, estoy en plena batalla con el teclado.

 

Saludos.


  • 0




IP.Board spam blocked by CleanTalk.