unit U_Store_Classes
benötigt U_Store_Dynamic_Params
Inhalt
======
class "TCustomStore"
Beschreibung
============
Klassen, die von TcustomStore abgeleitet werden bringen folgende zwei Methoden mit
-SaveToStream
-LoadFromStream
Damit wird der komplette Inhalt (Records, strings, dynamische arrays, ...)
der Klasse im Stream gespeicher bzw. aus dem Stream geladen. Dies geschieht
unabhängig von den definierten Properties.
Zusätzlich werden alle registrierten Klassen die in der Basisklasse
enthalten sind, gespeichert/geladen.
Je nach Einstellung von der Eigenschaft FreeallObjects werden alle
registrierten Objekte freigegeben
Verwendung
==========
type TTest=class(TCustomStore)
private
x:integer;
t:string;
n:array of string;
Int_Store:TStore; //abgeleitet von TCustomStore
myclass:Tmyclass;
p:pointer;
timer:Ttimer;
public
//... hier können auch weiter Variablen stehen
constructor create; override;
end;
//....
constructor TTest.create;
begin
list:=Tstringlist.create;
myclass:=tmyclass.create;
//ganz wichtig, jede Klasse muss vor der Verwendung von
//savetostream/loadfromstream registriert werden
RegisterObject(@int_Store);
//dies gilt nur für bestimmte Klassen (siehe unten)
//alternativ können auch Klasse (und auch Variablen, wie pointer)
//als Don't-Save registriert werden.
//Dadurch wird beim Laden, der ursprüngliche Inhalt in der Klasse nicht überschrieben
RegisterdontSave(@p,sizeof(p));
Registerdontsave(@timer) //size=4 ist standard für Klassen
//Hierbei ist die Größe der Variablen anzugeben
//Klassen, die nicht wie oben registriert werden können
//und ihre eigenen SaveToStream und LoadFromStream -methoden mitbringen
//können wie folgt registriert werden
RegisterObjectMethod(@myclass,myclass.savetostream ,myclass.loadfromstream);
end;
//
Aufruf:
var test:Ttest;
stream:TFilestream;
begin
test:=TTest.create;
//...Eigenschaften setzen etc.
//Zustand speichern
stream:=Tfilestream.create('xyz.dat',fmcreate);
test.savetofile(stream);
stream.free;
//...
//Zustand wieder laden
stream:=Tfilestream.create('xyz.dat',fmopenread);
test.Loadfromfile(stream);
stream.free;
//...
test.free; //Die StringList wird auch freigegeben
end;
Für Klassen innerhalb der Basisklasse, die nicht von TCustomStore abgeleitet
werden, kann auch das Ereignis TClassStoreEvent (ClassLoadEvent und ClassSaveEvent)
definiert werden. Dieses wird ausgelöst, sobald eine Klasse von RegisterObject
gespeichert oder geladen werden soll, die nicht TCustomStore als Vorfahr hat.
Diese Ereignisbehandlungsroutine kann dann das Speichern des Objektes übernehmen.
Desweiteren können alle Klassen, die in ihren Variablen keine
weiteren Klassen enthalten direkt registriert (RegisterObject) werden.
Hinweise
========
1. Klassen müssen mit
RTTI compiliert werden (siehe Compilerdirektive $M+)
2. Es können keine Interfaces bearbeitet werden
3. NICHTREGISTRIERTE Klassen werden beim laden wahrscheinlich ungültig
==>Speicherlöcher
4. Eine untergeordnete Klasse, die beim Aufruf von SavetoStream instanziert,
war, muss es auch noch/wieder bei LoadfromStream sein.
5. Es wird nicht kontrolliert, ob Variablen/Klassen mehrfach in verschiedenen
Listen registriert wurden (sollte vermieden werden, da es zu unerwünschten
Effekten kommen kann)
6. Es können keine Klassen innerhalb von dynamischen Komponenten (
Records und dynamischen Arrays) registriert werden
7. RegisterDontSave geht nur für einfache Pointer oder für Klassen
Es geht nicht für Records und Arrays.