Autor |
Beitrag |
Schatten^parker
Hält's aus hier
Beiträge: 9
|
Verfasst: Fr 14.02.03 22:07
Hi leute,
ich habe wie immer wenn ich mich an euch wende ein problem!
zum verständnis:
ich schreibe ein programm dass eine klasse, tmitglied mit den eigenschaften .vorname .nachname blablabla, in eine liste einträgt.
nun möchte ich die Klasse in einer datei speichern, *.dat oder so, um sie später wieder laden zu können.
nun weiss ich ja nicht wie delphi eine klasse mit eigenschaften in der datei speichert (wenns jemand weiss bitte erklären), noch weiss ich ob man jede klasse in einer seperaten zeile speichern muss noch wie man allgemein sowas in dateien speichert.
bitte keine antwort mit fachsimpelei, danke
(( und bitte keine hilfeverweise, danke ))
Zuletzt bearbeitet von Schatten^parker am So 16.02.03 16:39, insgesamt 1-mal bearbeitet
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 14.02.03 22:10
Ich denke du sprichst nicht von einer Klasse, sondern von einem Record. Und den kannst mit typisierten Dateien abspeichern.
|
|
Andreas L.
      
Beiträge: 1703
Erhaltene Danke: 25
Windows Vista / Windows 10
Delphi 2009 Pro (JVCL, DragDrop, rmKlever, ICS, EmbeddedWB, DEC, Indy)
|
Verfasst: Sa 15.02.03 09:07
Oder mit INI-Dateien, deren du einfach eine andere Dateiendung gibst!
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: Sa 15.02.03 15:18
Hi, natürlich kannst du auch klassen-properties in dateien speichern! Sie muss dazu von TPersistent abgeleitet sein und die properties müssen 'published' sein! Dann kannst du mittels RTTI (RunTimeTypeInformation) die props speichern und laden, und zwar automatisch alle auf einmal.
Wenn du von TComponent ableitest, dann kannst du dies sogar mit jedem beliebigen Stream tun -> Stream.writeComponent(compo) ,...readComponent(compo)!
Is aber nicht so schön, weil du dann viel unnötigen quatsch in der klasse hasst.
viel spass!
PS: auf [url] www.joachimDeVries.de[/url] findest du eine gute RTTI unit.
|
|
Schatten^parker 
Hält's aus hier
Beiträge: 9
|
Verfasst: Sa 15.02.03 15:42
Ich verstehe nicht ganz was ich machen soll, hier mein quelltext zum verständnis! danke
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: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101:
| unit Mhaupt;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, mdialog,mmitglied;
type TFHaupt = class(TForm) bt_dialog: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Button1: TButton; lb_mitglied: TListBox; procedure bt_dialogClick(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private fdialog: Tfdialog; mitglied: tmitglied; mitgliedliste: Tlist; listbox: tlistbox; { Private-Deklarationen } public function getvorname: string; function getnachname: string; function getgebdatum: string; function getnummer: string;
{ Public-Deklarationen } end;
var FHaupt: TFHaupt;
implementation
{$R *.DFM} function TFHaupt.getvorname; begin getvorname:= fdialog.edit1.text; end;
function TFHaupt.getnachname; begin getnachname:= fdialog.edit2.text; end;
function TFHaupt.getgebdatum; begin getgebdatum:= fdialog.edit3.text; end;
function TFHaupt.getnummer; begin getnummer:= fdialog.edit4.text; end;
procedure TFHaupt.bt_dialogClick(Sender: TObject); begin fdialog:= tfdialog.create(SELF); fdialog.showmodal;
edit1.text:= getvorname; edit2.text:= getnachname; edit3.text:= getgebdatum; edit4.text:= getnummer;
mitglied:= tmitglied.create; mitglied.vorname:= getvorname; mitglied.nachname:= getnachname; mitglied.gebdatum:= getgebdatum; mitglied.nummer:=getnummer; mitgliedliste.add(mitglied);
lb_mitglied.items.add(mitglied.nummer+' - '+mitglied.nachname+', '+mitglied.vorname+'('+mitglied.gebdatum+')'); { mitgliedliste.items[0].savetofile('c:\schule\info\ml.dat'); } showmessage(mitglied.vorname+' wurde erfolgreich in die Liste aufgenommen!');
fdialog.free;
end;
procedure TFHaupt.Button1Click(Sender: TObject); begin close; end;
procedure TFHaupt.FormCreate(Sender: TObject); begin mitgliedliste:= tlist.create; listbox:= tlistbox.create(self); { mitgliedliste.items.loadfromfile('Mitgliedliste.dat'); } end;
end. |
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| unit mmitglied;
interface
type tmitglied = class(Tobject) vorname: string; nachname: string; gebdatum: string; nummer: string; private { Private-Deklarationen } public { Public-Deklarationen } end;
implementation
end. |
|
|
aogwaba
      
Beiträge: 109
|
Verfasst: Sa 15.02.03 17:43
benutz doch statt TList( welches eigentlich nur Pointer aufnimmt), ein TStringList, da sind die Read und Write Methoden mit onBoard.
cu
waba
|
|
Schatten^parker 
Hält's aus hier
Beiträge: 9
|
Verfasst: Sa 15.02.03 18:10
Quelltext 1:
| [Fehler] Mhaupt.pas(81): Inkompatible Typen: 'String' und 'tmitglied' |
die klasse mitglied kann nicht in die stringlist aufgenommen werden da sie warscheinlich garkein string ist, sie hatt properties vom typ string ( .vorname , .nachname ,...).
|
|
aogwaba
      
Beiträge: 109
|
Verfasst: Sa 15.02.03 19:20
gemeint war das so:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| myList:tstringList; myList:=tstringList.create;
mitglied:= tmitglied.create; mitglied.vorname:= getvorname; mitglied.nachname:= getnachname; mitglied.gebdatum:= getgebdatum; mitglied.nummer:=getnummer; myList.add(mitglied.nummer+' - '+mitglied.nachname+', ' +mitglied.vorname+'('+mitglied.gebdatum+')'); myList.saveToFile(...); |
Dieses Konstruct fügt die Strings zu einem String zusammen und speicht diesen.
Beim Laden muss dieser wieder zerbröselt, und die Token den einzelnen Propertys zugewiesen werden.
Sehr primitiv. Besser man benutzt, wie Luckie schon sagte, typisierte Dateien.
Hier ein Link: www.tutorials.delphi...urce.de/sequdateien/
oder noch besser TFileStream.
cu
waba
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: Sa 15.02.03 20:30
Hallo! Hier die möglichkeit via RTTI...das rockt hart!
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:
| unit mmitglied;
interface
type tmitglied = class(TComponent) // TComponent weil es sich mit streams speichern lässt! Fvorname: string; Fnachname: string; Fgebdatum: string; Fnummer: string; private { Private-Deklarationen } published // edit { Public-Deklarationen } SaveToFile(FileName); LoadFromFile(FileName);
property Vorname : string read FVorname write FVorname; property Nachname : string read FNachname write FNachname ; . . . end;
implementation
procedure tmitglied.SaveToFile; var fs:TFileStream; begin fs:=TFileStream.create(fileName,fmCreate); try fs.writeComponent(self); finally fs.free; end; end;
procedure tmitglied.LoadFromFile; var fs:TFileStream; begin if not fileExists(filename) then exit; fs:=TFileStream.create(fileName,fmOpenRead); try fs.ReadComponent(self); finally fs.free; end; end;
end. |
Hierbei musst du dich halt nicht mehr um die einzelnen properties kümmern, da sie alle automatisch gespeichert werden (im binären DFM format). Mit 'ObjectBinaryToText' oder 'ObjectTextToBinary' könntest du das format sogar in regulären DFM-text convertieren und zurück!
IMHO sehr cool, da voll dynamisch
mfg maximus
|
|
Schatten^parker 
Hält's aus hier
Beiträge: 9
|
Verfasst: So 16.02.03 16:36
Hi Maximus, danke für deinen Tip.
Etwas ähnliches habe ich auch schon probiert, aber jedes mal wenn ich eine Klasse von TComponent ableiten will kommt folgender Fehler
Quelltext 1:
| [Fehler] mmitglied.pas(6): Undefinierter Bezeichner: 'TComponent' |
Ich weiss auch nicht woran es liegt, vielleicht hab ich vergessen was zu deklrieren??? bitte hilf mir  ))
|
|
Tino
      

Beiträge: 9839
Erhaltene Danke: 45
Windows 8.1
Delphi XE4
|
Verfasst: So 16.02.03 17:28
Du musst die Datei Classes einbinden:
Quelltext
Gruß
TINO
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: So 16.02.03 18:26
Genau! Mit 'ObjectBinaryToText' oder 'ObjectTextToBinary' echten DFM-text zu erzeugen ist nicht ganz so leicht! Deshalb der vollständigkeit halber, wie ich es gemacht habe: 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:
| ... function SaveCompoToFile(aCompo : TComponent; FileName: string; asBinary: Boolean = false): boolean; var Stream1:TMemoryStream; Stream2:TMemoryStream; format : TStreamOriginalFormat; begin result := false; format := sofText; Stream1 := TMemoryStream.Create; Stream2 := TMemoryStream.Create; try Stream1.WriteComponent(aCompo); Stream1.Position := 0; if not asBinary then begin format := sofText; ObjectBinaryToText(Stream1,Stream2,format); end else Stream1.SaveToStream(Stream2); Stream2.SaveToFile(FileName); result := true; finally Stream1.Free; Stream2.Free; end; end;
function LoadCompoFromFile(aCompo : TComponent; FileName: string; asBinary: Boolean = false): boolean; var FileStream:TFileStream; MemoryStream:TMemoryStream; format:TStreamOriginalFormat; begin result := false; if not FileExists(fileName) then exit; MemoryStream := TMemoryStream.Create; FileStream := TFileStream.Create(FileName,fmOpenRead); try if not asBinary then begin format := sofBinary; ObjectTextToBinary(FileStream,MemoryStream,format); end else MemoryStream.LoadFromStream(FileStream); MemoryStream.Position := 0; MemoryStream.ReadComponent(aCompo); result := true; finally FileStream.Free; MemoryStream.Free; end; end; | ...wer an einer lösung interessiert, die ohne TComponent auskommt und mit der man auch einzelne properties speichern kann, der soll sich hier melden
mfg maximus
|
|
Eisenherz
      
Beiträge: 48
|
Verfasst: Mo 17.02.03 18:59
maximus hat folgendes geschrieben: | Hierbei musst du dich halt nicht mehr um die einzelnen properties kümmern, da sie alle automatisch gespeichert werden (im binären DFM format). |
Somit kann man mit sehr wenig Code etwas speichern. Ich habe aber das Gefühl, dass das unter die Rubrik "Quick and dirty" fällt.
Das automatische Speichern klappt nur, wenn das Property die Sichtbarkeit Published hat. Will man etwas Speichern, was vom Konzept her Private sein sollte, dann wird man gezwungen dies Published zu machen. Das stimmt nicht ganz, da es auch eine Möglichkeit gibt, dass man "Properties" speichern kann, die nicht published sind. Dann muss man allerdings deutlich mehr Code schreiben.
Weiterhin ist man so gezwungen ein published Property bis in alle Ewigkeit beizubehalten. Man kassiert eine Exception, wenn man versucht eine Komponente aus einer Datei zu laden, die erzeugt wurde, als die Komponente noch Properties hatte, über die sie jetzt nicht mehr verfügt.
_________________ aloa Eisenherz
|
|
Tino
      

Beiträge: 9839
Erhaltene Danke: 45
Windows 8.1
Delphi XE4
|
Verfasst: Di 18.02.03 10:12
Hallo Leute,
eine weitere Möglichkeit wäre mal auf die Website von Eisenherz zu gehen. Dort kann man sich die Unit RakBinaryStreamData downloaden. Dadurch wird das speichern und laden von beliebigen Daten vereinfacht.
Gruß
TINO
|
|
FBrk
Hält's aus hier
Beiträge: 8
|
Verfasst: Di 18.02.03 11:51
Titel: tud dat not???
Sag mal muss das sein das die Daten in einer Klasse gespeichert werden???
Klassen sind da um Daten und Routinen in einer Komponente zu verbinden und zu vererben um dann neue Komponenten hinzu zu fürgen. In diesem Falle ist ein Record das mittel der wahl, und das Speichert man logischer weise in Typisierten Datein.
Das ist erstens einfacher und zweitens sauberer.
Gruß Felix
_________________ Warum einfach wenn´s auch kompliziert geht??
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: Di 18.02.03 14:27
Eisenherz hat folgendes geschrieben: | Somit kann man mit sehr wenig Code etwas speichern. Ich habe aber das Gefühl, dass das unter die Rubrik "Quick and dirty" fällt.
Das automatische Speichern klappt nur, wenn das Property die Sichtbarkeit Published hat. Will man etwas Speichern, was vom Konzept her Private sein sollte, dann wird man gezwungen dies Published zu machen. Das stimmt nicht ganz, da es auch eine Möglichkeit gibt, dass man "Properties" speichern kann, die nicht published sind. Dann muss man allerdings deutlich mehr Code schreiben... |
 Klar is das Quick&Dirty (hab ich aber auch, in einem nebensatz draufhin gewiesen) , deshalb hab ich ja auch eine möglichkeit angeboten das quick aber nicht dirty zu machen: Zitat: | ...wer an einer lösung interessiert, die ohne TComponent auskommt und mit der man auch einzelne properties speichern kann, der soll sich hier melden. |
. ...mit einem einzigen befehl zB. Width, height,top,left,windowState zu speichern ist IMHO sehr geil. Bei allen componenten bezogenen sachen hat man die wichtigen props eh immer published( zumindest die, die gespeichert werden sollen). Und schicken DFM-text zu haben ist halt auch nicht zu verübeln, da man die datei dann automatisch als config benutzen kann, was man bei einem binär-stream getrost vergessen kann
Mich würd mal interessieren wie ich nicht 'published' properties automatisch speicherst...wie machst du das, via RTTI oder hab ich was verpasst?
Grüsse.
maximus
PS: Der code oben eignet sich prima um ganze Componenten-bäume zur laufzeit zu erstellen und deren aktuelle einstellungen zu speichern! Die von delphi erstellten compos sollte man damit nicht speichern wollen, weil er dann versucht, die im DFM-text definierten compos zu erstellen, obwolh sie schon existieren 
|
|
Eisenherz
      
Beiträge: 48
|
Verfasst: Di 18.02.03 15:44
Titel: Re: tud dat not???
FBrk hat folgendes geschrieben: | Sag mal muss das sein das die Daten in einer Klasse gespeichert werden??? |
Wenn man streng objektorientiert programmiert, dann ja.
Zitat: | Klassen sind da um Daten und Routinen in einer Komponente zu verbinden und zu vererben um dann neue Komponenten hinzu zu fürgen. |
Klassen wissen erst einmal gar nichts von Komponenten. Komponenten zeichnen sich dadurch aus, dass sie von der Klasse TComponent direkt oder indirekt abgeleitet sind. Eine Komponente ist also nur ein Spezialfall einer Klasse.
Zitat: | In diesem Falle ist ein Record das mittel der wahl, und das Speichert man logischer weise in Typisierten Datein. |
Man kann Records in typisierten Dateien speichern, das ist aber nicht die einzige Möglichkeit und somit nicht logisch.
Records sind ein Überbleibsel aus der nicht objektorientierten Zeit von Pascal. Bei Java gibt es z.B. keine Records. Das braucht man auch nicht, da Records nur ein Spezialfall von Klassen sind, nämlich Klassen ohne Methoden.
Der einzig wirklich gewichtige Grund, der mir jetzt einfällt, um Daten in typisierten Dateien zu speichern ist, dass man schnellen Zugriff auch auf Daten braucht, die sich in der Mitte oder am Ende der Datei befinden.
Wenn man bedenkt, dass heutige Festplatten 20MByte/sec und mehr übertragen, lohnt sich der Einsatz von typisierten Dateien nur dann richtig, wenn man große Datenmengen hat. Dann sollte man aber darüber nachdenken, ob man nicht gleich mit einer richtigen Datenbank arbeitet.
Zitat: | Das ist erstens einfacher |
Bei kleinen Programmen mag das stimmen.
Zitat: | und zweitens sauberer. |
Das kommt darauf an, was man als "sauber" ansieht.
_________________ aloa Eisenherz
|
|
Eisenherz
      
Beiträge: 48
|
Verfasst: Di 18.02.03 16:17
maximus hat folgendes geschrieben: | Klar is das Quick&Dirty (hab ich aber auch, in einem nebensatz draufhin gewiesen) , deshalb hab ich ja auch eine möglichkeit angeboten das quick aber nicht dirty zu machen: Zitat: | ...wer an einer lösung interessiert, die ohne TComponent auskommt und mit der man auch einzelne properties speichern kann, der soll sich hier melden. | . |
Mich würde Deine Lösung interessieren. Ich glaube zwar nicht, dass ich sie einsetzen werde, da ich viel von Datenkapselung halte und mir somit der Gedanke nicht gefällt, dass ich Properties published und schreibbar machen muss, die vom Konzept her protected/private oder readonly sind. Aber vielleicht hast Du ein paar interessante Ideen gehabt.
Zitat: | Und schicken DFM-text zu haben ist halt auch nicht zu verübeln, da man die datei dann automatisch als config benutzen kann, was man bei einem binär-stream getrost vergessen kann |
Textdateien haben natürlich den Vorteil, dass man sie sogar mit Notepad bearbeiten kann. Sie haben damit aber auch den Nachteil, dass man sie schnell unbrauchbar machen kann.
Damit man meinem "binär-stream" editieren kann habe ich extra ein Tool erstellt.
Zitat: | Mich würd mal interessieren wie ich nicht 'published' properties automatisch speicherst...wie machst du das, via RTTI oder hab ich was verpasst? |
Ich speichere bisher nichts automatisch. Aber vielleicht greife ich den Gedanken auf und erweitere meine Klassen in diese Richtung.
_________________ aloa Eisenherz
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: Di 18.02.03 18:13
@Eisenherz: Zitat: | Mich würde Deine Lösung interessieren. Ich glaube zwar nicht, dass ich sie einsetzen werde, da ich viel von Datenkapselung halte und mir somit der Gedanke nicht gefällt, dass ich Properties published und schreibbar machen muss, die vom Konzept her protected/private oder readonly sind. Aber vielleicht hast Du ein paar interessante Ideen gehabt.
|
Dich zwingt ja auch niemand irgendwas gegen deinen willen schreibbar zumachen  Wenn deine props vom konzept her privat sein sollen, dann ist es ja auch unwahrscheinlich das du sie auf platte speichern willst, oder?
Du hast mich auf die idee gebracht, meinen ansatz mal auf read-only properties zu prüfen...die funktion ist da aber ob ich es hier auch berücksichtigt habe werde ich mal schecken.
Ich poste morgen mal den code.
bis denn. mx
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: Mi 19.02.03 00:46
So. Ich hab meinen code auf 'read-only' und 'stored false' properties sensibilisiert. Damit der code läuft, wird noch eine (sehr gute, IMO) RTTI unit benötigt (von Joachim De Vries).
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: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135:
| {----------------------------------------------------------------------------- Unit Name : mxService Author : maximus (mäxeus, maxantat, muku) Date : 10.02.2003 -----------------------------------------------------------------------------} unit mxService;
interface
uses classes, sysUtils, TypInfo, dvRTTI {<-- von www.joachimDeVries.de -} ;
function SaveObjectToFile(aObject : TPersistent; FileName: string; includedProps : String = '*'; filter : TTypeKinds = tkAny): boolean; function LoadObjectFromFile(aObject : TPersistent; FileName: string; includedProps : String = '*'; filter : TTypeKinds = tkAny): boolean;
procedure CleanSpacesVar(var s:String; inQuotes:boolean=false; QuoteChar: Char = ''''); function CleanSpaces(s:String; inQuotes:boolean=false; QuoteChar:Char = ''''):string;
implementation
function CleanSpaces(s:String; inQuotes:boolean=false; QuoteChar:Char = ''''):string; var i:integer; f:boolean; begin result := s; i := 0; f := false; while i <= length(result) do begin if not inQuotes and (result[i] = QuoteChar) then f := not f; if (result[i] = ' ') and not f then Delete(result,i,1) else inc(i); end; end;
procedure CleanSpacesVar(var s:String; inQuotes:boolean=false; QuoteChar:Char = ''''); var i:integer; f:boolean; begin i := 0; f := false; while i <= length(s) do begin if not inQuotes and (s[i] = QuoteChar) then f := not f; if (s[i] = ' ') and not f then Delete(s,i,1) else inc(i); end; end;
function isWholeWordInString(aWord,s:string; delimiter:char = ','):boolean; var n,i:integer; m:string; c1,c2:char; begin result := false; m := delimiter+lowercase(s)+delimiter; n := pos(lowercase(aWord),m); if n <= 0 then exit; m := copy(m,n-1,length(m)-n+2); c1 := m[1]; c2 := m[length(aWord)+2]; if ((c1 = delimiter) or (c1 = ' '))and((c2 = delimiter) or (c2 = ' ')) then result := true else begin delete(m,2,length(aWord)); result := isWholeWordInString(aWord, m, delimiter); end; end;
//----------------------------------------------------------------------------------------
function SaveObjectToFile(aObject : TPersistent; FileName: string; includedProps : String = '*'; filter : TTypeKinds = tkAny): boolean; var RTTI:TdvRTTIList; sl:TSTringList; i:integer; s,v,name:string; All:boolean; begin result := false; if aObject = nil then exit; All := includedProps = '*'; RTTI := TdvRTTIList.create(aObject); sl := TSTringList.Create; try RTTI.Filter := filter; if aObject is TComponent then name := TComponent(aObject).Name+' : ' else name := ''; sl.Add('object '+name+aObject.ClassName); for i := 0 to RTTI.count-1 do begin if RTTI.Items[i].PropInfo.StoredProc = nil then continue; if not All and not isWholeWordInString(RTTI.Items[i].Name,includedProps) then continue; v := RTTI.Items[i].Value; if v <> '' then sl.Add(' ' + RTTI.Items[i].Name+' = '+ v); end; sl.Add('end'); sl.SaveToFile(fileName); result := true; finally sl.Free; RTTI.Free; end; end;
function LoadObjectFromFile(aObject : TPersistent; FileName: string; includedProps : String = '*'; filter : TTypeKinds = tkAny): boolean; var RTTI:TdvRTTIList; sl:TSTringList; i:integer; s,name:string; All : boolean; begin result := false; if aObject = nil then exit; if not FileExists(fileName) then exit; All := includedProps = '*'; RTTI := TdvRTTIList.create(aObject); sl := TSTringList.Create; try RTTI.Filter := filter; sl.LoadFromFile(fileName); sl.Text := CleanSpaces(sl.Text); for i := 0 to RTTI.count-1 do begin if RTTI.Items[i].PropInfo.SetProc = nil then continue; name := RTTI.Items[i].Name; if not All and not isWholeWordInString(name,includedProps) then continue; if sl.IndexOfName(name) > -1 then RTTI[i].Value := sl.Values[name]; end; result := true; finally sl.Free; RTTI.Free; end; end;
end. |
Bindet man die unit ein, so kann man nu beliebige 'published' props eines objekts speichern und laden (ab D6):
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| uses mxService; ... SaveObjectToFile(self, MyDir+self.Name+'.dmx','top,left,width,height,name,windowstate'); LoadObjectFromFile(self, MyDir+self.Name+'.dmx','top,left,width,height,name,windowstate'); // oder SaveObjectToFile(self, MyDir+self.Name+'.dmx','*'); // speichert alle LoadObjectFromFile(self, MyDir+self.Name+'.dmx','*'); // speichert alle // oder uses mxService, typInfo; ... SaveObjectToFile(self, MyDir+self.Name+'.dmx','*', tkInteger); // speichert alle integer props LoadObjectFromFile(self, MyDir+self.Name+'.dmx','*', tkInteger); |
Das objekt muss von TPersistent abgeleitet sein(kann man vielleicht auch umbauen für Objekte die mit {M+} erstellt worden sind, allerdings beide units  besser nicht!)
Viel spass damit...und wenn jemand verbesserungen hat, dann würd es mich freuen diese zu sehen(hier oder an maximus@eyer-systems.de).
mfg mx.
|
|
|