[Delphi 4] TTreeview aan data koppelen en opslaan

Pagina: 1
Acties:

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 22:14
Eerst even een uitleg van wat ik in elkaar aan't prutsen ben.
Het betreft een FTP client (jaja ik weet het die zijn er al genoeg, maar ik doe het om met delphi te leren werken).
Nu ben ik met de "site manager" van de ftpclient bezig en dat wil ik dus m.b.v. een TTreeview realiseren.
Als er een van de ftpsites in de treeview wordt geselecteerd moeten van deze site het adres en de login gegevens zichtbaar worden in Tedit componenten.
Hoe ga ik al deze gegevens aan een TNode koppelen?!
En nog een probleem, de gebruiker moet in runtime dus ftp sites kunnen toevoegen (lijkt me logisch anders heb je er niets aan), maar deze toevoeginen (en wijziginen aan de treeview in het algemeen) moeten dus wel opgeslagen worden. Nu is het volgens mij wel mogelijk om een Ttreeview op te slaan en te laden met resp. de SaveToFile en LoadFromFile methoden, maar hoe zit het dan met de data die er aan gekoppeld zit?
Alvast bedankt.


Edit: Kijk maar naar de sitemanager van bijv CuteFTP als mijn uitleg niet geheel duidelijk is. Daar heb ik het idee ook van gejat ;)

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 07:18

Tomatoman

Fulltime prutser

Kijk eens naar Virtual TreeView. Daar zit een hoop van de logica die jij nodig hebt al ingebouwd.

Edit: hij blijkt bij Delphi 7 ook op de companion cd te staan.

Een goede grap mag vrienden kosten.


  • whoami
  • Registratie: December 2000
  • Laatst online: 30-08 19:34
[nohtml]
FallenAngel666 schreef op 20 oktober 2002 @ 15:58:
Als er een van de ftpsites in de treeview wordt geselecteerd moeten van deze site het adres en de login gegevens zichtbaar worden in Tedit componenten.
Hoe ga ik al deze gegevens aan een TNode koppelen?!
Je kunt een class maken die deze gegevens bijhoudt. Je kunt dan aan de Data prperty van die Node een object van die class toekennen dat de gewenste gegevens bevat.
En nog een probleem, de gebruiker moet in runtime dus ftp sites kunnen toevoegen (lijkt me logisch anders heb je er niets aan), maar deze toevoeginen (en wijziginen aan de treeview in het algemeen) moeten dus wel opgeslagen worden. Nu is het volgens mij wel mogelijk om een Ttreeview op te slaan en te laden met resp. de SaveToFile en LoadFromFile methoden, maar hoe zit het dan met de data die er aan gekoppeld zit?
IMO sla je die data misschien beter op in een databank. Dan kan je die gegevens gestructureerd opslaan. Bij het opslaan overloop je dan de Treeview en sla je de data in de gekoppelde objecten op.

https://fgheysels.github.io/


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

VirtualTree is wel heel mooi, maar niet erg simpel in de meeste gevallen.

Net als whoami zegt heeft een TTreeNode een Data property wat een pointer is. Daar kan je aan hangen wat je wilt. Jij wilt er waarschijnlijk een object of een record aan hangen.

Het loaden en saven van de nodes zal je zelf moeten schrijven. Je kan het doen zoals whoami voorsteld, maar het lijkt me een beetje zwaar voor een ftp client. Je zou het in je eigen binaire of tekst formaat kunnen doen of een ini of xml bestand. Of een locale TClientDatsET gebruiken, maar ik weet niet of D4 die al heeft. De SaveToFile and LoadFromFile methodes van de TTreeView zijn nutteloos in jouw geval.

We adore chaos because we like to restore order - M.C. Escher


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 22:14
Jah die Data property had ik ook wel gevonden, maar het idee om het aan een class te koppelen was niet bij me opgekomen! dat ga ik dus iig proberen.
Het opslaan van die Treeview zelf en de gekoppelde data kan ik dus gewoon met die SaveToFile methode in een .txt bestand gieten? Of heb ik het verkeerd begrepen...
Een database zal ook wel lukken en de mogelijkheid tot het gestructureerd opslaan van data is natuurlijk wel handig, maar idd wel wat overdreven lijk me.
Het lieft zou ik het gecodeert in een tekstbestand willen gieten of binair opslaan.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

nee, SaveToFile bewaart alleen de Captions. Als je ook de daaraan verbonden gegevens wil opslaan ben je op jezelf aangewezen. Verzin je eigen text formaat of sla het binair op.

We adore chaos because we like to restore order - M.C. Escher


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 22:14
Zat zelf aan het volgende te denken:
Bij de OnActivate event van het sitemanger form waar de ttreeview opstaat wordt de LoadFromFile methode van de treeview aangeroepen. Bij het OnClose event van hetzelfde form wordt de SaveToFile methode aangeroepen.
Dit werkt dus perfect voor het opslaan van de structuur van de Ttreeview zelf.
Nu komt het volgende deel, de gegevens. Of dit gaat werken is afhankelijk van het volgende: worden de itemid's van de Treenodes ook opgeslagen in die file?!
Als dit zo is dan kan ik dus bij het aanmaken van een ttreenode gelijk de itemid ervan opvragen en aan de hand hiervan de gegevens die aan de node gekoppeld moeten worden opslaan in een .ini file. Dit werkt dan ook zo bij het opvragen van de gegevens.

Dus in de .ini file wordt het dan zo opgeslagen:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
[8850054]        //ItemId
SiteName=waarde
Username=waarde
Password=waarde
Port=waarde

[8850055]        //volgende ItemId
SiteName=waarde
Username=waarde
Password=waarde
Port=waarde

etc.



Dit zou een heel stuk eenvoudiger zijn dan een klasse schrijven lijkt me.
De tekst is dan wel niet gecodeert, maar eigenlijk hoeft dat ook niet perse.

  • whoami
  • Registratie: December 2000
  • Laatst online: 30-08 19:34
[nohtml]
FallenAngel666 schreef op 21 oktober 2002 @ 00:00:
Zat zelf aan het volgende te denken:
Bij de OnActivate event van het sitemanger form waar de ttreeview opstaat wordt de LoadFromFile methode van de treeview aangeroepen. Bij het OnClose event van hetzelfde form wordt de SaveToFile methode aangeroepen.
Ik zou zeker de OnActivate handler niet gebruiken voor het inladen. OnActivate wordt nl. afaik iedere keer getriggerd als het venster het actieve venster wordt.
Je zorgt er beter voor dat de treeview maar 1x ingeladen wordt, en die functie om hem in te laden pas 1 maal opgeroepen wordt. Dit kan je doen in de OnCreate.

https://fgheysels.github.io/


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

ItemID is een Handle voor windows. Is wel uniek, maar ik denk alleen per instantie van die TTreeView? Beter is denk ik TTreeNode.AbsoluteIndex te nemen.

Je hebt dan wel altijd 2 bestanden terwijl het met weinig moeite er ook gewoon 1 kan worden.

PS: Wachtwoorden zo clear text opslaan zou ik niet waarderen :)

[ Voor 0% gewijzigd door LordLarry op 21-10-2002 09:11 . Reden: typo ]

We adore chaos because we like to restore order - M.C. Escher


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 22:14
whoami schreef op 21 oktober 2002 @ 09:04:
[nohtml]
[...]

Ik zou zeker de OnActivate handler niet gebruiken voor het inladen. OnActivate wordt nl. afaik iedere keer getriggerd als het venster het actieve venster wordt.
Je zorgt er beter voor dat de treeview maar 1x ingeladen wordt, en die functie om hem in te laden pas 1 maal opgeroepen wordt. Dit kan je doen in de OnCreate.
Idd wat een stomme fout zeg, dan wordt telkens de "oude" versie van de treeview ingeladen als je de sitemanager oproept |:(
Bedankt voor de tip!

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 22:14
LordLarry schreef op 21 oktober 2002 @ 09:11:
ItemID is een Handle voor windows. Is wel uniek, maar ik denk alleen per instantie van die TTreeView? Beter is denk ik TTreeNode.AbsoluteIndex te nemen.

Je hebt dan wel altijd 2 bestanden terwijl het met weinig moeite er ook gewoon 1 kan worden.

PS: Wachtwoorden zo clear text opslaan zou ik niet waarderen :)
Jah dat vraag ik me dus ook af, worden die nummers per instantie random toegekend of worden ze statisch toegekend en kan je ze dus ook opslaan met de rest van de treeview structuur :?
Nou ja, er is maar 1 manier om daar achter te komen --> proberen :*)
AbsoluteIndex gebruiken komt natuurlijk op hetzelfde neer, maar die is dus wel altijd hetzelfde en niet per instantie verschillend :?
Enne, dat opslaan van wachtwoorden, daar zit wel wat in natuurlijk...
Tsja, anders moet ik misschien toch eerst maar eens uitzoeken hoe je de data property aan een class kan koppelen en hoe ik die class dan op moet stellen.
Ik kijk wel even.
Bedankt iig!

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 22:14
Heb even een class geschreven om te kijken of ik het werkend kon krijgen.
Hier even de hele test unit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type

// Klasse die gekoppeld wordt aan de data property van de Treenode.
  
  TNodeData = class
  public
  waarde1 : string;
  waarde2 : string;
  end;

  TForm1 = class(TForm)
    tv1: TTreeView;
    BtnAdd: TButton;
    Edwrd1: TEdit;
    Edwrd1: TEdit;
    procedure BtnAddClick(Sender: TObject);
    procedure tv1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  NewNode:TTreenode;

implementation

{$R *.DFM}

// Door op de knop BtnAdd te klikken wordt er een nieuwe node aangemaakt als
// child van de geselecteerde node. Aan de data property wordt een tweetal
// standaard waarden toegekend. 

procedure TForm1.BtnAddClick(Sender: TObject);
begin  
   tv1.SetFocus;
   NewNode:=tv1.items.addchild(tv1.selected, 'New Site'); 
   NewNode.makevisible;
   NewNode.EditText;
   NewNode.selected:=true;
   NewNode.data := TNodeData.Create;
   TNodeData(Newnode.data).waarde1:='Standaard waarde 1';
   TNodeData(Newnode.data).waarde2:='Standaard waarde 2';
end;


// Als er op een node in de TreeView wordt geklikt dan wordt de data die er aan
// toegekend is, mits deze aanwezig is, in de betreffende tekstvelden 
// weergegeven.

procedure TForm1.tv1Click(Sender: TObject);
begin
   if tv1.selected.data <> nil then
      begin
         Edwrd1.Text:=TNodeData(tv1.selected.data).waarde1;
         Edwrd2.Text:=TNodeData(tv1.selected.data).waarde2;
      end
   else
      begin
         Edwrd1.Text:='';
         Edwrd2.Text:='';
      end;
end;

end.



Dit werkt dus perfect, maar nu moet ik het hele zooitje dus nog opgeslagen zien te krijgen.

  • whoami
  • Registratie: December 2000
  • Laatst online: 30-08 19:34
Je kunt de ganse TreeView gaan overlopen en ieder object gaan wegschrijven naar een file.

https://fgheysels.github.io/


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 22:14
Ok, ik heb geen flauw idee hoe, maar ik gaat opzoek!
Zal wel iets met SaveToStream methode te maken hebben zeker?

  • whoami
  • Registratie: December 2000
  • Laatst online: 30-08 19:34
FallenAngel666 schreef op 21 oktober 2002 @ 14:12:
Ok, ik heb geen flauw idee hoe, maar ik gaat opzoek!
Zal wel iets met SaveToStream methode te maken hebben zeker?


Zou kunnen. Ik heb hier geen Delphi staan om het ff op te zoeken...
Ik denk dat je TFileStream classes oid hebt in Delphi.

https://fgheysels.github.io/


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 22:17

mulder

ik spuug op het trottoir

Weet je zeker dat je de tree wilt opslaan en niet gewoon de data waarmee de tree is opgebouwd?

oogjes open, snaveltjes dicht


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Nee, SaveToStream is hetzelfde als SaveToFile, alleen gaat het dan naar een stream ipv direct naar een bestand.

Maak eerst maar eens een (recursive) functie die alle nodes in de boom afgaat. Je begint bij de root en je gaat al zn kinderen af. En voor alle kinderen roep je dezelfde functie weer aan. Die dus ook weer hun kinderen afgaan enz. enz. enz.

Als je dat hebt gedaan kan je dus elke keer als je een node tegekomt een stukje naar een bestand schrijven. Ook wegschrijven wie je ouder is :) dat heb je nodig om de boom weer terug op te bouwen.

We adore chaos because we like to restore order - M.C. Escher


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 22:14
Jaja, dus eigenlijk hetzelfde principe als er een sort op loslaten, alleen wordt er dan niets gesorteerd, maar wordt het weggeschreven.

Edit:

Ik ben even opzoek gegaan en ik heb heel wat intressante dingen gevonden m.b.t. het opslaan van een TTreeView in een bestand.


Deze site pakt het probleem aan d.m.v. steamen i.pv. recursief de tree doorlopen en wegschrijven:

http://www.adug.org.au/Pa...s/ABulkaApr99/Default.htm

Deze site slaat de hele bende op in een .doc file, maar dan heb je wel een paar classes nodig die je daar kan downloaden:

http://users.iafrica.com/...lphi/DocFile/DocFile.html


Dit is misschien nuttige info voor mensen die dit probleem ook nog eens op willen lossen, bespaard weer wat zoek werk :)
Ik ga eens aan de slag met die stream methode.
Pagina: 1