Recent

Author Topic: Savetostream  (Read 1574 times)

seghele0

  • Full Member
  • ***
  • Posts: 222
Savetostream
« on: August 10, 2024, 04:51:25 pm »
Heb deze code via Google kunnen ontvangen.
'Save', 'Load', 'Print' werkt niet.
Hopelijk kan iemand de juiste code aangeven.
 :-[

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5.  Forms, Controls, Graphics, Dialogs, StdCtrls, ComCtrls,
  6.  ExtCtrls, Classes, SysUtils, Printers;
  7. type
  8.     TPerson = class
  9.     Name: string;
  10.     BirthDate: string;
  11.     procedure SaveToStream(Stream: TStream);
  12.     procedure LoadFromStream(Stream: TStream);
  13.   end;
  14.  
  15. { TMAINFORM }
  16.   TMAINFORM = class(TForm)
  17.     ButtonEXIT: TButton;
  18.     TreeView: TTreeView;
  19.     AddButton: TButton;
  20.     EditButton: TButton;
  21.     DeleteButton: TButton;
  22.     SaveButton: TButton;
  23.     LoadButton: TButton;
  24.     PrintButton: TButton;
  25.     NameEdit: TEdit;
  26.     BirthDateEdit: TEdit;
  27.     NameLabel: TLabel;
  28.     BirthDateLabel: TLabel;
  29.     Panel1: TPanel;
  30.     procedure ButtonEXITClick(Sender: TObject);
  31.     procedure FormCreate(Sender: TObject);
  32.     procedure AddButtonClick(Sender: TObject);
  33.     procedure EditButtonClick(Sender: TObject);
  34.     procedure DeleteButtonClick(Sender: TObject);
  35.     procedure SaveButtonClick(Sender: TObject);
  36.     procedure LoadButtonClick(Sender: TObject);
  37.     procedure PrintButtonClick(Sender: TObject);
  38.  
  39.   private
  40.     procedure SaveTree(Node: TTreeNode; Stream:TStream);
  41.     procedure LoadTree(Node: TTreeNode; Stream:TStream);
  42.   public
  43.   end;
  44.  
  45. var
  46.   MAINFORM: TMAINFORM;
  47. implementation
  48. {$R *.lfm}
  49. { TPerson }
  50. procedure TPerson.SaveToStream(Stream: TStream);
  51. var
  52.   NameLen, BirthDateLen: Integer;
  53. begin
  54.   NameLen := Length(Name);
  55.   Stream.WriteBuffer(NameLen, SizeOf(NameLen));
  56.   Stream.WriteBuffer(Name[1], NameLen);
  57.   BirthDateLen := Length(BirthDate);
  58.   Stream.WriteBuffer(BirthDateLen, SizeOf(BirthDateLen));
  59.   Stream.WriteBuffer(BirthDate[1], BirthDateLen);
  60. end;
  61.  
  62. procedure TPerson.LoadFromStream(Stream: TStream);
  63. var
  64.   NameLen, BirthDateLen: Integer;
  65. begin
  66.   BirthDateLen:=0;
  67.   NameLen:=0;
  68.   Stream.ReadBuffer(NameLen, SizeOf(NameLen));
  69.   SetLength(Name, NameLen);
  70.   Stream.ReadBuffer(Name[1], NameLen);
  71.   Stream.ReadBuffer(BirthDateLen, SizeOf(BirthDateLen));
  72.   SetLength(BirthDate, BirthDateLen);
  73.   Stream.ReadBuffer(BirthDate[1], BirthDateLen);
  74. end;
  75.  
  76. { TMainForm }
  77.  
  78. procedure TMAINFORM.FormCreate(Sender: TObject);
  79. begin
  80.   TreeView.Items.Add(nil, 'Family Tree');
  81. end;
  82.  
  83. procedure TMAINFORM.ButtonEXITClick(Sender: TObject);
  84. begin
  85.   Close;
  86. end;
  87.  
  88. procedure TMAINFORM.AddButtonClick(Sender: TObject);
  89. var
  90.   Node: TTreeNode;
  91.   Person: TPerson;
  92. begin
  93.   if NameEdit.Text = '' then
  94.   begin
  95.     ShowMessage('Name input ....');
  96.     Exit;
  97.   end;
  98.   Person := TPerson.Create;
  99.   Person.Name := NameEdit.Text;
  100.   Person.BirthDate := BirthDateEdit.Text;
  101.   if TreeView.Selected <> nil then
  102.     Node := TreeView.Items.AddChildObject(TreeView.Selected, Person.Name, Person)
  103.   else
  104.     Node := TreeView.Items.AddObject(nil, Person.Name, Person);
  105.   Node.Text := Person.Name + ' (' + Person.BirthDate + ')';
  106.   NameEdit.Clear;
  107.   BirthDateEdit.Clear;
  108. end;
  109.  
  110. procedure TMAINFORM.EditButtonClick(Sender: TObject);
  111. var
  112.   Person: TPerson;
  113. begin
  114.   if TreeView.Selected = nil then
  115.   begin
  116.     ShowMessage('Select EDIT button.');
  117.     Exit;
  118.   end;
  119.   if NameEdit.Text = '' then
  120.   begin
  121.     ShowMessage('Name input.');
  122.     Exit;
  123.   end;
  124.   Person := TPerson(TreeView.Selected.Data);
  125.   Person.Name := NameEdit.Text;
  126.   Person.BirthDate := BirthDateEdit.Text;
  127.   TreeView.Selected.Text := Person.Name + ' (' + Person.BirthDate + ')';
  128.   NameEdit.Clear;
  129.   BirthDateEdit.Clear;
  130. end;
  131.  
  132. procedure TMAINFORM.DeleteButtonClick(Sender: TObject);
  133. begin
  134.   if TreeView.Selected = nil then
  135.   begin
  136.     ShowMessage('Select DELETE button.');
  137.     Exit;
  138.   end;
  139.   TreeView.Items.Delete(TreeView.Selected);
  140. end;
  141. procedure TMAINFORM.SaveButtonClick(Sender: TObject);
  142. var
  143.   Stream: TFileStream;
  144. begin
  145.   Stream := TFileStream.Create('FamilyTree.dat', fmCreate);
  146.   try
  147.     SaveTree(TreeView.Items[0], Stream);
  148.   finally
  149.     Stream.Free;
  150.   end;
  151. end;
  152. procedure TMAINFORM.LoadButtonClick(Sender: TObject);
  153. var
  154.   Stream: TFileStream;
  155. begin
  156.   Stream := TFileStream.Create('FamilyTree.dat', fmOpenRead);
  157.   try
  158.     TreeView.Items.Clear;
  159.     LoadTree(TreeView.Items.Add(nil, 'Family Tree'), Stream);
  160.   finally
  161.     Stream.Free;
  162.   end;
  163. end;
  164.  
  165. procedure TMAINFORM.PrintButtonClick(Sender: TObject);
  166. var
  167.   Node: TTreeNode;
  168.   Line: string;
  169. begin
  170.   Printer.BeginDoc;
  171.   try
  172.     Node := TreeView.Items.GetFirstNode;
  173.     while Node <> nil do
  174.     begin
  175.       Line := StringOfChar(' ', Node.Level * 4) + Node.Text;
  176.       Printer.Canvas.TextOut(100, 100 + Node.Index * 20, Line);
  177.       Node := Node.GetNext;
  178.     end;
  179.   finally
  180.     Printer.EndDoc;
  181.   end;
  182. end;
  183. procedure TMainForm.SaveTree(Node: TTreeNode; Stream: TStream);
  184. var
  185.   Person: TPerson;
  186.   ChildNode: TTreeNode;
  187.   ChildCount: Integer;
  188. begin
  189.   if Node.Data <> nil then
  190.   begin
  191.     Person := TPerson(Node.Data);
  192.     Person.SaveToStream(Stream);
  193.   end;
  194.   ChildCount := Node.Count;
  195.   Stream.WriteBuffer(ChildCount, SizeOf(ChildCount));
  196.   ChildNode := Node.GetFirstChild;
  197.   while ChildNode <> nil do
  198.   begin
  199.     SaveTree(ChildNode, Stream);
  200.     ChildNode := Node.GetNextChild(ChildNode);
  201.   end;
  202. end;
  203. procedure TMainForm.LoadTree(Node: TTreeNode; Stream: TStream);
  204. var
  205.   Person: TPerson;
  206.   ChildCount, i: Integer;
  207. begin
  208.   ChildCount:=0;
  209.   if Stream.Position < Stream.Size then
  210.   begin
  211.     Person := TPerson.Create;
  212.     Person.LoadFromStream(Stream);
  213.     Node.Data := Person;
  214.     Node.Text := Person.Name + ' (' + Person.BirthDate + ')';
  215.   end;
  216.   Stream.ReadBuffer(ChildCount, SizeOf(ChildCount));
  217.   for i := 0 to ChildCount - 1 do
  218.     LoadTree(TreeView.Items.AddChild(Node, ''), Stream);
  219. end;
  220.  
  221. end.                        

jamie

  • Hero Member
  • *****
  • Posts: 6587
Re: Savetostream
« Reply #1 on: August 10, 2024, 05:40:55 pm »
You need to include "PRinters4Lazarus"  in your project file list.
The only true wisdom is knowing you know nothing

seghele0

  • Full Member
  • ***
  • Posts: 222
Re: Savetostream
« Reply #2 on: August 11, 2024, 04:03:20 pm »
Heb nu in Project Inspector : Required packages: LCL , Printer4Lazarus.
Afdrukken 'Print' werkt nu wel.

Nog het lettertype: Printer.cavas.Font.Size:=15;

'Save', 'Load' are not working !
Via [Save] wordt een bestandje aangemaakt: FamilyTree.dat.
Code steun ?
 :-\


jamie

  • Hero Member
  • *****
  • Posts: 6587
Re: Savetostream
« Reply #3 on: August 11, 2024, 05:22:17 pm »
what exactly is going wrong with the code?

I do see where TPerson is created in the Load process and reused in the Save process? This is kind of confusing because it means you need to first load something before you can save it. Which means a predefine file needs to be there.

Secondly:

  Please translate to English before posting.


 
The only true wisdom is knowing you know nothing

seghele0

  • Full Member
  • ***
  • Posts: 222
Re: Savetostream
« Reply #4 on: August 11, 2024, 06:01:37 pm »
Thanks for the response.
I'm not a professional programmer, just an experimental one, and this with a low level of Pascal.
I try to maintain a kind of hobby with Lazrus, just for the pleasure of having some programs.
Maybe someone can give me the correct code, because I can't find it on Google.
 ;)
So the two procedures with the 'SAVE' and 'LOAD' buttons do not work.
Thanks in advance.




jamie

  • Hero Member
  • *****
  • Posts: 6587
Re: Savetostream
« Reply #5 on: August 11, 2024, 07:35:51 pm »
If you copied only the source code from the website and not the complete project, then the Load and save buttons may not be connected to the OnClick event.

Checkout the "OnClick" event in the object inspector to see if they are assigned, if not, hit the little arrow to the right of that event edit box and it will give you a list of possible candidates to chouse from.
The only true wisdom is knowing you know nothing

seghele0

  • Full Member
  • ***
  • Posts: 222
Re: Savetostream
« Reply #6 on: August 12, 2024, 02:25:29 pm »
Perhaps it is necessary to show the complete application.
The 'LOAD' button still doesn't work and probably the 'SAVE' button doesn't either.
 :(
See attachment.

eny

  • Hero Member
  • *****
  • Posts: 1644
Re: Savetostream
« Reply #7 on: August 12, 2024, 09:12:26 pm »
'Save' werkt wel, maar alle nieuwe namen moeten onder 'Family Tree' worden toegevoegd.
Alleen de eerste 'rootnode' met alle onderliggende nodes worden opgeslagen.

<<ENG>>
Save does work, but all newly added names should be added onder one root node 'Family Tree'.
Only the first root node with all it's children is saved.

All posts based on: Win10 (Win64); Lazarus 3_4  (x64) 25-05-2024 (unless specified otherwise...)

wp

  • Hero Member
  • *****
  • Posts: 12368
Re: Savetostream
« Reply #8 on: August 12, 2024, 10:36:24 pm »
Good that you provide a working sample project, this makes it much easier to help you.

  • Saving: First of all you must be clear on the meaning of the Node parameter provided to SaveTree. Is it a node to be saved or is it the parent of the nodes to be saved? The code is easier when you pick the second option. In this case, you first store the count of the Node's children, and then iterate over the children and store the associated person data. Then you call SaveTree recursively, which again, for each child, writes is child count and the person, and repeats that with its children again by another recursive call, etc, etc.
  • Reading must follow exactly the same steps. So, first we read the child count of the top node. Then we loop over this count of steps in which the person is read, a node is created as child of the parameter Node. And finally we must call LoadTree again for these child nodes, etc, etc.

No bug, but I think it's clearer when all node handling is contained in SaveTree and LoadTree only. Therefore I usesd the convention that the very first call to these function must have the parameter Node=nil. This is interpreted as the top node, which in your case is the node with caption "Family tree". Be careful with this, because it has no person assigned to its Data.

There is also an issue with the printing function since it prints only nodes at the first level. You must use a recursive call similar to LoadTree/SaveTree in order to print all levels.

Find a working version of your project in the attachment. Since I don't have printer available the printing function is not tested.

seghele0

  • Full Member
  • ***
  • Posts: 222
Re: Savetostream
« Reply #9 on: August 13, 2024, 12:08:31 pm »
A sincere thank you for your efforts in forwarding your own application.
But it is not a 'Family Tree'.
I was hoping that you could make my application work, with a working 'Save' and 'Load' procedure.
Maybe there is someone who can solve this!


wp

  • Hero Member
  • *****
  • Posts: 12368
Re: Savetostream
« Reply #10 on: August 13, 2024, 12:24:02 pm »
But it is not a 'Family Tree'.
Now I am confused: Why does your top node display the text "family tree"?

I was hoping that you could make my application work, with a working 'Save' and 'Load' procedure.
Maybe there is someone who can solve this!
Confused again: I was convinced that I made it work (except maybe for the printing function which I could not test).

Did you download the attachment of my previous post?

seghele0

  • Full Member
  • ***
  • Posts: 222
Re: Savetostream
« Reply #11 on: August 13, 2024, 01:18:37 pm »
Sorry, sorry. Unbelievable, but my head was overheating at my age.
I was working on another application (testing).
Your adjustments in my application 'FamilyTraa' work well.
Thank you.
 :)


 

TinyPortal © 2005-2018