Re: VirtualTreeView: Es klappt nicht ganz
Das hab ich jetzt nicht so erwartet ;) Nochmal gaaaanz langsam:
Problem 1: Speichern. Wie speichere ich ein Objekt? Übernimmt das Programm die interne Verwaltung der internen Objekt-Daten oder muss ich manuell an die Daten ran? Im Moment speichere ich ganz einfach das Objekt in den Stream. Er macht das auch ohne zu murren und in der Datei auf der Festplatte sehe ich einen der internen Strings (aber nur diesen einen) und jede Menge anderes ASCII-Zeugs, das für mich als Betrachter sicher nicht wichtig ist. Problem 2 stelle ich erst, wenn das Speichern funktioniert ;) |
Re: VirtualTreeView: Es klappt nicht ganz
Du speicherst nur einen Pointer auf das Objekt in den Stream ... das Objekt selber ist nicht in der VTV ... genaus wird es mit dem String gemacht (halt nur der Pointer auf den String in der VTV), nur das man da halt auf den Referenzzähler achten muß.
Du kannst natürlich den String auch in einem ShortString (String[255], odeer so) speichern, wobei der hortString wieder nur ein Record wäre und somit selbst in der VTV landet. PS: hatte oben noch einiges nachgetragen. |
Re: VirtualTreeView: Es klappt nicht ganz
Puh, oje, das ist mir im Moment etwas zu hoch... kannst Du mir vielleicht etwas konkreten Code zu meinem konkreten Objekt (hier ganz oben) geben? :|
|
Re: VirtualTreeView: Es klappt nicht ganz
warum macht ihr alle das so umständlich.
schaut euch bitte von mir nochmal folgenden beispielcode an: http://www.delphipraxis.net/internal...=484809#484809 |
Re: VirtualTreeView: Es klappt nicht ganz
zu deinem Projekt steht's ja sozusagen schon dort oben (Beitrag #7)
Du muß halt bedenken, das dein Objekt ja nicht nur aus einem zusammenhängendem Speicherblock besteht. Var irgendwas: TSessionObject; ist halt nur ein Pointer auf das Objekt und in dem Objekt sind ja auch wiederum Pointer auf andere Dinge (z.B. die Strings). Also, will man jetzt ein Objekt "nur" mit der VTV verbinden, dann stimmt das schon, aber die gesamten Daten eines Objekts in einen Stream zu bekommen ist nicht so leicht ... man kann da eigentlich nur das Objekt zerlegen und eine Kopie der einzelnen ObjektDaten in dem Stream speichern und müßte dann daraus (beim Auslesen) dann wieder ein neues Objekt erstellen. |
Re: VirtualTreeView: Es klappt nicht ganz
@generic: Von OnLoad und OnSave steht da aber nichts drin ;)
Ich probiere nun, die Daten des Objekts einzeln in den Stream zu schreiben (erstmal nur der erste Parameter) mit
Delphi-Quellcode:
Funktioniert soweit. Nur wie bekomme ich die Daten da wieder raus?
// save nodes to disk
procedure TForm1.VST1SaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream); var Data: PTreeData; Len: integer; begin Data := VST1.GetNodeData(Node); Len := Length(TSessionObject(Data.FObject).name); Stream.Write(Len, SizeOf(Len)); Stream.write(PChar(TSessionObject(Data.FObject).name)^, Len); end;
Delphi-Quellcode:
Das klappt irgendwie nicht, wegen der markierten Zeile. Wieso?
// load nodes from disk
procedure TForm1.VST1LoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream); var Data: PTreeData; Len: integer; begin Data := VST1.GetNodeData(Node); Stream.read(Len, SizeOf(Len)); SetLength(TSessionObject(Data.FObject).name, Len); //<---- Error: Ein Konstantenobjekt kann nicht als Var-Parameter übergeben werden Stream.read(PChar(TSessionObject(Data.FObject).name)^, Len); end; |
Re: VirtualTreeView: Es klappt nicht ganz
Ah, jetzt verstehe ich Dich ;) Dann muss ich das Objekt beim Laden ja neu erstellen durch ein Create. Dann mach ich das mal...
|
Re: VirtualTreeView: Es klappt nicht ganz
OK, jetzt habe ich folgenden Code und eine EAccessViolation:
Delphi-Quellcode:
// save nodes to disk
procedure TForm1.VST1SaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream); var Data: PTreeData; Len: integer; begin Data := VST1.GetNodeData(Node); Stream.Write(TSessionObject(Data.FObject).datum, SizeOf(TSessionObject(Data.FObject).datum)); Len := Length(TSessionObject(Data.FObject).name); Stream.Write(Len, SizeOf(Len)); Stream.write(PChar(TSessionObject(Data.FObject).name)^, Len); //[... die restlichen Parameter] end;
Delphi-Quellcode:
Aber wieso die Exception? Irgendwo ein Pointer oder ein Objekt nicht richtig?
// load nodes from disk
procedure TForm1.VST1LoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream); var Data: PTreeData; Len,datum,ndatum: integer; SessionObject: TSessionObject; name,sessiontyp,protokollant,teilnehmer,verteiler: string; begin Data := VST1.GetNodeData(Node); SessionObject:=TSessionObject.Create; Stream.Read(datum, SizeOf(datum)); Stream.read(Len, SizeOf(Len)); SetLength(name, Len); Stream.read(name, Len); // [... + der rest] SessionObject.datum:=datum; SessionObject.name:=name; // <--------------- hier kommt die Exception // [... + der rest] Data^.FObject:=SessionObject; end; EDIT: Habe die Zeile markiert, wo die Exc geworfen wird. Muss aber jetzt leider für heute weg. Komme beim nächsten Arbeitstag wieder auf diesen Thread zurück. Danke soweit! :) |
Re: VirtualTreeView: Es klappt nicht ganz
Der Code zum Lesen der String-Var ist nicht ganz richtig. So ist es besser:
Delphi-Quellcode:
Gruß Hawkeye
Stream.read(Len, SizeOf(Len));
SetLength(name, Len); // Stream.read(name, Len); // <-- name ist nur ein Zeiger! if (Len > 0) then Stream.read(name[1], Len); |
Re: VirtualTreeView: Es klappt nicht ganz
Wo kommt den der Fehler und warum willst du unbedingt das gesamte Objekt din haben?
Es ist zumindestens Platzsparender, wenn nur der Pointer in der VTV steht und man bräuchte dann das Objekt nicht zu zerlegen... Aber versuch es mal so:
Delphi-Quellcode:
oder
Stream.Write(TSessionObject(Data.FObject).Name[1], Len);
Stream.Read(TSessionObject(Data.FObject).Name[1], Len);
Delphi-Quellcode:
Ich weiß nicht, ob Write/Read 'nen VAR-Parameter (ersteres), oder 'nen Pointer (zweiteres) will.
Stream.Write(@TSessionObject(Data.FObject).Name[1], Len);
Stream.Read(@TSessionObject(Data.FObject).Name[1], Len); [add] OK, Markierung gesehn ^^ Dann lag es bestimmt an der Stringübergabe (siehe Code) [/add] PS: @generic Na ja, eigentlichj ist es von der interen Speicherung in der VTV her egal wo man die Daten übergibt, aber wie man sie übergibt/ließt ist da schon wichtig.
Delphi-Quellcode:
Hier ist ja mehr das Problem, wie die Daten in der VTV gespeichert/verwaltet sollen.
vst.addchild(nil, [b]Data[/b]);
[i][b]Pointer[/b][/i] := [b]Data[/b]; vst.addchild(nil, [i][b]Pointer[/b][/i]); N := vst.addchild(nil); AVST.SetNodeData(N, [b]Data[/b]); [i][b]Pointer[/b][/i] := [b]Data[/b]; n := vst.addchild(nil); AVST.SetNodeData(N, [i][b]Pointer[/b][/i]); ... // vieles, vieles mehr So, nun noch der wohl einfachere Weg ... das Objekt erzeigen und nur die referenz daruf übergeben:
Delphi-Quellcode:
procedure insertSession();
var SessionObject: TSessionObject; begin SessionObject := TSessionObject.Create; SessionObject.datum:=DateTimeToUnix(Form1.DateTimePicker1.Date); SessionObject.sessiontyp:=Form1.ComboBox1.Text; SessionObject.protokollant:=Form1.Edit1.text; SessionObject.teilnehmer:=Form1.Edit2.Text; SessionObject.verteiler:=Form1.Edit3.Text; SessionObject.ndatum:=DateTimeToUnix(Form1.DateTimePicker2.Date); Result:=Form1.VST1.AddChild(nil, SessionObject); end; Diese kann auch ins OnCreate der Form (falls man es nicht auch direkt im OI ändern kann/will) ... einmal reicht ja, die Größe ändert sich ja nicht (PS: SizeOf(TTreeData) = Pointer = 4 Byte, also 4)
Delphi-Quellcode:
VST1.NodeDataSize:=SizeOf(TTreeData);
Delphi-Quellcode:
procedure deleteSession(Node: PVirtualNode);
var SessionObject: TSessionObject; begin TSessionObject(Form1.VST1.GetNodeData(Node)).Free; Form1.VST1.Delete; // keine Ahnung ob das wirklich so heißt end; Folgendes kann auch ins OnCreate der Form (falls man es nicht direkt im OI ändern kann/will) ... einmal reicht ja, die Größe ändert sich schließlich nicht (PS: SizeOf(TTreeData) = Pointer = 4 Byte, also 4)
Delphi-Quellcode:
VST1.NodeDataSize:=SizeOf(TTreeData);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:18 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz