![]() |
[TCustomStore] Klasse, die sich komplett selber speichert
Liste der Anhänge anzeigen (Anzahl: 3)
Beschreibung
Jede Klasse, die von TCustomStore (siehe Anhang) abgeleitet wird kann sich komplett selber in einen Stream (oder nonVCL-Unit: in einen String) speichern, und natürlich auch davon wiederherstellen. Und dabei ist es völlig irrelevant, welche Variablen als Properties definiert wurden. Es werden alle Variablen gespeichert. Diese Varibalen können statisch oder dynamisch sein, also alles was Delphi so an Typen kennt inkl. Records und weiterer Klassen. (Es können aber auch einzelne Variablen davon ausgenommen werden) Anwendung Ich stelle einfach kurz ein Beispiel vor:
Delphi-Quellcode:
//Diese Klasse ist von TCustomStore abgeleitet und bringt deswegen die Methoden
//SaveToStream und LoadFromStream mit. //die nonVCL-Variante muss natürlich ohne Stream auskommen und verwendet daher Strings type TStore=class(TCustomStore) public i:integer; Store2:TStore_2; Strings:TStrings; other_class:TMyOwn; p:pointer; //der soll in diesem Beispiel nicht gespeichert werden constructor create; //Im constructor werde ich hier die Klassen registrieren. //Dies kann allerdings auch später passieren. end; constructor TStore.create; begin inherited create; Store2:=TStore2.Create; Strings:=tstringlist.Create; other_class:=tmyown.Create; //der wichtige Teil, der gemacht werden muss, da Klassen nicht in der RTTI enthalten sind RegisterObject(@Store3); //die Registrerung über RegisterObject geht für Klassen, die // -von TCdustomStore abgleitet sind // -keine dynamischen Varibalen enthalten // -mittels der Ereignisbehandlung ClassSaveEvent und ClassLoadEvent gespeichert werden //Für andere Klassen müssen die Stream-Methoden mit angegeben werden //die Methoden müssen vom Typ "procedure(Stream:TStream) of object" sein //Der Stream, der übergeben wird ist exklusiv, mann muss sich also nicht die Länge merken RegisterobjectMethod(@other_class, other_class.Save, other_class.Load); RegisterObjectMethod(@Strings, Strings.SaveToStream, Strings.LoadFromStream); //und noch Variablen/Klassen registrieren die nicht gespeichert werden sollen //in dem Fall, der untypisierte pointer Registerdontsave(@p,sizeof(p)); //letztenendes bedeutet dies Registrierung, dass der pointer durch //LoadFromStream nicht überschrieben wird //Klassen innerhalb von Records und dynamischen Arrays können nicht registriert werden //und sollten daher nicht verwendet werden --> in eine Klasse kapseln //RegisterDontSave ist nur für Pointer und Klassen gedacht //--> geht definitiv nicht für Records und Dynamische Arrays end; //speichern der Klasse TStore procedure TForm1.SaveButtonClick(Sender: TObject); var Class_to_Store:TStore; File:TFileStream; begin Class_to_Store:=TStore.create; Class_to_Store.i:=9; Class_to_Store.Store2.x:='Hallo'; //eine dynamische String-Variable aus TStore3 belegen Strings.add('Lala'); other_class.s:='Hilfe'; Class_to_Store.p:=pointer(10); File:=TfileStream.Create('Test_SPclass.dat',fmcreate); Class_to_Store.SaveToStream(File); File.free; Class_to_Store.free; //Da Class_to_Store.FreeAllObjects per default auf True ist, werden alle registrierten //Klassen von RegisterObject und RegisterObjectMethods mit freigegeben. //Andere Klassen und Variablen (auch die von RegisterDontSave) müssen selber freigegeben werden end; //Laden der Klasse TStore procedure TForm1.LoadButtonClick(Sender: TObject); var Class_Stored:TStore; File:TFilestream; begin memo1.clear; Class_Stored:=TStore.create; Class_Stored.i:=-1; //zum Test, dass sich nach loadfromstream auch etwas ändert Class_Stored.x:='Das will ich gleich nicht mehr sehen'; Class_Stored.p:=pointer(50); //Der sollte gleich bleiben File:=TfileStream.Create('Test_SPclass.dat',fmopenread); Class_Stored.LoadfromStream(File); File.free; memo1.lines.add(Class_Stored.Store2.x); memo1.lines.Add(inttostr(Class_Stored.i)); memo1.lines.AddStrings(Class_Stored.Strings); memo1.lines.Add(Class_Stored.other_class.s); memo1.lines.add(inttostr(integer(Class_Stored.p))); Class_Stored.free; end;
Delphi-Quellcode:
//hie noch die Testklassen, die in der eigentlichen Klasse verwendet werden type tmyown=class s:string; procedure save(Stream:Tstream); procedure Load(Stream:Tstream); end; type TStore2=class(TCustomStore) public x:string; end; //Methoden der HilfsTestKlassen procedure TmyOwn.save; begin stream.Write(s[1],length(x)); end; procedure Tmyown.Load; begin setlength(s,stream.size); stream.read(s[1],length(s)); end; Soweit dazu. Ansonsten noch der Text, der auch in der Unit steht: Zitat:
![]() (Ich will die Unit nicht hier nochmal anhängen. Falls ich an ihr noch etwas ändere müsste ich sonst in beiden Threads updaten) Edit 19.7.07 23:15 -- Überarbeitete Version hochgeladen Edit 20.7.07 10:00 -- Noch ein Beispielprojekt angefertigt Edit 08.8.07 21:15 -- nonVCL-Variante ergänzt |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz