?
Solved

Save Nodes from a VirtualTree

Posted on 2010-01-02
2
Medium Priority
?
612 Views
Last Modified: 2012-05-08
I am trying to save the node data in a VirtualTree, so I can load the data back after the applications restarts. Saving the GroupName from the record is causing problems. This is with Delphi 2010 and the latest VST.

  // this is a record structure for the virtual treeview to hold the object
  PTVgrplst = ^RTVgrplst;
  RTVgrplst = record
    Index: Integer;
    GroupName: string;  
    LastArticle: Cardinal;  
    FirstArticle: Cardinal;
    AllowPost: boolean;
    ArticleCount: Cardinal;
  end;

...

procedure TFormMain.VTreeGroupsSaveNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Stream: TStream);
var
  Data: PTVgrplst;
  Len: integer;
begin

  Data := VTreeGroups.GetNodeData(Node);

  Stream.write(Data.LastArticle, SizeOf(Data.LastArticle));
  Stream.write(Data.FirstArticle, SizeOf(Data.FirstArticle));
  Stream.write(Data.AllowPost, SizeOf(Data.AllowPost));
  Stream.write(Data.Index, SizeOf(Data.Index));

  len := Length(Data.GroupName);
  Stream.Write(Len, SizeOf(Len));
  Stream.Write(Data.GroupName, Len);  <<--
end;

If I add like 100 to the "Len" like so...
  Stream.Write(Data.GroupName, Len+100);

then I can see the GroupName string in the dat/textfile that I save the contents to... but if I dont then the groupname isnt saved to the file (cut off actually, not missing). When I log the data, GroupName is not "" and the length is correct too. But why isnt the stream saving it correctly?
0
Comment
Question by:LMuadDIb
  • 2
2 Comments
 
LVL 4

Accepted Solution

by:
LMuadDIb earned 0 total points
ID: 26163406
I think I found the correct answer to my question, this seems to work correctly:
I need to test more



//My Code ->>

procedure TFormMain.VTreeGroupsLoadNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Stream: TStream);
var
  Data: PTVgrplst;
  Len: integer;
begin
  Data := VTreeGroups.GetNodeData(Node);

  Stream.read(Data.LastArticle, SizeOf(Data.LastArticle));
  Stream.read(Data.FirstArticle, SizeOf(Data.FirstArticle));
  Stream.read(Data.AllowPost, SizeOf(Data.AllowPost));
  Stream.read(Data.Index, SizeOf(Data.Index));
  // Correct for Unicode string data
  Stream.read(Len, SizeOf(Integer));  // Read the string length
  SetLength(Data.GroupName, Len div SizeOf(Char));
  Stream.Read(Pointer(Data.GroupName)^, Len);  // <<-- Specify buffer size in bytes
end;

procedure TFormMain.VTreeGroupsSaveNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Stream: TStream);
var
  Data: PTVgrplst;
  Len: integer;
begin
  Data := VTreeGroups.GetNodeData(Node);

  Stream.write(Data.LastArticle, SizeOf(Data.LastArticle));
  Stream.write(Data.FirstArticle, SizeOf(Data.FirstArticle));
  Stream.write(Data.AllowPost, SizeOf(Data.AllowPost));
  Stream.write(Data.Index, SizeOf(Data.Index));
  // Correct for Unicode string data
  Len := Length(Data.GroupName) * SizeOf(Char);
  Stream.Write(Len, SizeOf(integer));   // Write the string length
  Stream.Write(Pointer(Data.GroupName)^, Length(Data.GroupName) * SizeOf(Char)); // <<-- Specifcy buffer size in bytes
end;


//example code which help me fix my problem above
//Answer came from: http://edn.embarcadero.com/article/38693

var
   S: string;
   L: Integer;
   Stream: TStream;
   Temp: AnsiString;
 begin
   // Existing code - incorrect when string = UnicodeString
   Stream.Read(L, SizeOf(Integer));
   SetLength(S, L);
   Stream.Read(Pointer(S)^, L);
   
   // Correct for Unicode string data
   Stream.Read(L, SizeOf(Integer));
   SetLength(S, L);
   Stream.Read(Pointer(S)^, L * SizeOf(Char));  // <<-- Specify buffer size in bytes
   
   // Correct for Ansi string data
   Stream.Read(L, SizeOf(Integer));
   SetLength(Temp, L);              // <<-- Use temporary AnsiString
   Stream.Read(Pointer(Temp)^, L * SizeOf(AnsiChar));  // <<-- Specify buffer size in bytes
   S := Temp;                       // <<-- Widen string to Unicode
 end;

//...

var
   S: string;
   Stream: TStream;
   Temp: AnsiString;
 begin
   // Existing code - incorrect when string = UnicodeString
   Stream.Write(Pointer(S)^, Length(S));
   
   // Correct for Unciode data
   Stream.Write(Pointer(S)^, Length(S) * SizeOf(Char)); // <<-- Specifcy buffer size in bytes
   
   // Correct for Ansi data
   Temp := S;          // <<-- Use temporary AnsiString
   Stream.Write(Pointer(Temp)^, Length(Temp) * SizeOf(AnsiChar));// <<-- Specify buffer size in bytes
 end;

Open in new window

0
 
LVL 4

Author Comment

by:LMuadDIb
ID: 26167779
yes, the above code I found has worked fine
the problem was unicode and handling a string with the record

so I answered my own question.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Is your OST file inaccessible, Need to transfer OST file from one computer to another? Want to convert OST file to PST? If the answer to any of the above question is yes, then look no further. With the help of Stellar OST to PST Converter, you can e…
Suggested Courses

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question