Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Ein Objekt in der Registry speichern
N8Falter74 - Mi 25.01.06 16:31
Titel: Ein Objekt in der Registry speichern
Hallo
ich habe folgendes Problem: In einer Combobox zum Beispiel, habe ich lauter unterschiedliche Einträge und möchte diese in der Registrierung speichern. Ich könnte nun in einer Schleife alle Items durchgehen und für jedes Item und dessen Eigenschaften, Schlüssel und Werte in die Registrierung schreiben. Das ist aber eigendlich recht unflexibel.
Ist es nicht auch möglich das komplette Items Objekt per WriteBinaryData in die Registrierung zu scheiben?
Ich habe mal folgendes probiert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure WriteInReg; var reg: TRegistry; buffer: TJvImageItems; iCount: Integer; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Software\bitfarm\test', True);
buffer := cbx.Items; iCount := cbx.Items.InstanceSize * cbx.Items.Count; reg.WriteBinaryData('cbxtest', buffer, iCount);
reg.CloseKey; FreeAndNil(reg); end; |
Leider liefert mir das aber noch nicht das gewünschte Ergebnis.
Hat jemand eine Idee wie man sowas in die Registrierung schreiben und wieder lesen könnte? Geht das überhaupt?
Grüße
Sebastian
Marco D. - Mi 25.01.06 20:04
Warum unbedingt in die Registrierung? Das verlangsamt das System nur unnötig. :roll: :wink:
Willst du nur die Einträge speichern?
Dann mache es doch so:
Delphi-Quelltext
1:
| combobox1.items.savetofile(extractfilepath(paramstr(0))+'items.txt'); |
tgr - Mi 25.01.06 20:15
Speichern...
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| var ms: TMemoryStream; reg: TRegistry; begin ms:=TMemoryStream.Create; reg:=TRegistry.Create; try ms.WriteComponent(cbx); ms.Seek(0,soFromBeginning); reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Software\bitfarm\test', True); reg.WriteBinaryData('cbxtest',ms.Memory^,ms.Size); reg.CloseKey; finally reg.Free; ms.Free; end; end; |
Laden...
Delphi-Quelltext
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:
| var ms: TMemoryStream; reg: TRegistry; cb: TComboBox; begin ms:=TMemoryStream.Create; reg:=TRegistry.Create; try reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Software\bitfarm\test', True); ms.Size:=reg.GetDataSize; reg.ReadBinaryData('cbxtest',ms.Memory^,ms.Size); reg.CloseKey; ms.Seek(0,soFromBeginning); cb:=TComboBox(ms.ReadComponent); try cbx.Items.Assign(cb.Items); finally cb.Free; end; finally reg.Free; ms.Free; end; end; |
Habe den Quelltext nicht probiert, müsste aber funktionieren..
Thomas
N8Falter74 - Do 26.01.06 10:57
Hallo Thomas,
vielen dank für den Tipp mit den Streams, da wäre ich nicht so schnell drauf gekommen.
tgr hat folgendes geschrieben: |
Speichern...
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| var ms: TMemoryStream; reg: TRegistry; begin ms:=TMemoryStream.Create; reg:=TRegistry.Create; try ms.WriteComponent(cbx); ms.Seek(0,soFromBeginning); reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Software\bitfarm\test', True); reg.WriteBinaryData('cbxtest',ms.Memory^,ms.Size); reg.CloseKey; finally reg.Free; ms.Free; end; end; |
|
Das sieht eigendlich ganz gut aus...
tgr hat folgendes geschrieben: |
Laden...
Delphi-Quelltext 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:
| var ms: TMemoryStream; reg: TRegistry; cb: TComboBox; begin ms:=TMemoryStream.Create; reg:=TRegistry.Create; try reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Software\bitfarm\test', True); ms.Size:=reg.GetDataSize; reg.ReadBinaryData('cbxtest',ms.Memory^,ms.Size); reg.CloseKey; ms.Seek(0,soFromBeginning); cb:=TComboBox(ms.ReadComponent); try cbx.Items.Assign(cb.Items); finally cb.Free; end; finally reg.Free; ms.Free; end; end; |
|
Da musste ich noch ein paar änderungen machen, GetDataSize möchte als Parameter den Reg-Key haben und ReadComponent möchte als Parameter Nil haben. (zumindest laut Delphi Hilfe):
Zitat: |
Wenn Instance nil (Delphi) bzw. NULL (C++) ist, erstellt ReadComponent auf Grundlage der Typinformationen im Stream eine Komponente und gibt die neue Komponente zurück. |
Bei mir sieht das nun so aus:
Delphi-Quelltext
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:
| var ms: TMemoryStream; reg: TRegistry; cb: TJvImageComboBox; begin ms:=TMemoryStream.Create; reg:=TRegistry.Create; try reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Software\bitfarm\test', True); ms.Size:=reg.GetDataSize('cbxtest'); reg.ReadBinaryData('cbxtest',ms.Memory^,ms.Size); reg.CloseKey; ms.Seek(0,soFromBeginning); cb := TJvImageComboBox(ms.ReadComponent(nil)); try cbx.Items.Assign(cb.Items); finally cb.Free; end; finally reg.Free; ms.Free; end; end; |
Leider erzeugt das ms.ReadComponent(nil) bei mir nun eine Exception "EClassNotFound" für die Klasse TJvImageComboBox. Laut Delphi Hilfe habe ich vergessen die Klasse zu deklarieren:
Zitat: |
EClassNotFound wird aufgerufen, wenn beim Lesen einer Komponente aus einem Stream ein Klassenname angetroffen wird, der nicht mit der aktuellen Anwendung verknüpft ist. Dies kann geschehen, wenn eine Komponente zwar in einem Formular existiert, aber aus der Typdeklaration entfernt wurde. |
Also im Formular und in der Lade-Prozedur habe ich die Komponente deklariert, was stimmt hier nicht?
Ich habe auch spasseshalber mal das NIL durch die Komponente ersetzt: ms.ReadComponent(cbx)
Das bringt nun zwar keine Exception mehr, aber dafür verschwindet die ComboBox nun beim Laden vom Formular :gruebel:
grüße
Sebastian
Kroko - Do 26.01.06 11:03
Koller hat folgendes geschrieben: |
Warum unbedingt in die Registrierung? Das verlangsamt das System nur unnötig. :roll: :wink:
Willst du nur die Einträge speichern?
Dann mache es doch so:
Delphi-Quelltext 1:
| combobox1.items.savetofile(extractfilepath(paramstr(0))+'items.txt'); | |
APPLAUS APPLAUS APPLAUS
Warum versuchen eigentlich so viele die Registry zu zumüllen, habt ihr schon 20GHZ und 1TB RAM :?:
Dafür sind doch IniFiles gemacht!
N8Falter74 - Do 26.01.06 11:22
Kroko hat folgendes geschrieben: |
Koller hat folgendes geschrieben: | Warum unbedingt in die Registrierung? Das verlangsamt das System nur unnötig. :roll: :wink:
Willst du nur die Einträge speichern?
Dann mache es doch so:
Delphi-Quelltext 1:
| combobox1.items.savetofile(extractfilepath(paramstr(0))+'items.txt'); | |
APPLAUS APPLAUS APPLAUS
Warum versuchen eigentlich so viele die Registry zu zumüllen, habt ihr schon 20GHZ und 1TB RAM :?:
Dafür sind doch IniFiles gemacht! |
Hallo Kroko und Koller,
danke für euren Tipp, aber die ComboBox war nur ein Beispiel! Es geht um Komponenten die Collections als Eigenschaften haben und diese können sehr komplex sein. TJvImageComboBox ist schon viel komplexer als die normale TComboBox, es gibt aber auch Komponenten die Collections mit viel mehr Eigenschaften haben zB.: 20. Stell dir mal vor du hast davon vieleicht 10 Stück auf einem Formular. Die alle einzeln durchzugehen und abzuspeichern ist recht aufwendig und eigendlich auch unnötig!
Wo schlussendlich gespeichert wird ist eigendlich egal. Mir geht es darum, alles in einem Rutsch zu speichern.
Übrigens hat die Komponente in diesem Falle nur rund 300 Byte Speicherbedarf, ich schätze das ich nie in den Bereich von mehr als 1000 Byte komme. Das ist für die Registry kein problem - aber wie gesagt, darum geht es auch garnicht.
Grüße
Sebastian
tgr - Do 26.01.06 11:37
Hallo,
Deine Einwände sind i.o. - Flüchtigkeitsfehler!?!
Die Klasse muss wie folgt deklariert werden:
Delphi-Quelltext
1:
| RegisterClass(TJvImageComboBox); |
Am besten im INTIALIZE Zweig.
Für saubere Programmierung kannst Du beim Programmbeenden,
d.h. im FINALIZE-Zweig die Klasse wieder deregistrieren:
Delphi-Quelltext
1:
| UnRegisterClass(TJvImageComboBox); |
Gruss
Thomas
Kroko - Do 26.01.06 13:44
N8Falter74 hat folgendes geschrieben: |
...
Übrigens hat die Komponente in diesem Falle nur rund 300 Byte Speicherbedarf, ich schätze das ich nie in den Bereich von mehr als 1000 Byte komme. Das ist für die Registry kein problem - aber wie gesagt, darum geht es auch garnicht.
Grüße
Sebastian |
Mir sind 1000 Byte auf der HDD 3x lieber als in der Registry, eine Klasse zu schreiben die alle Streams in einen schreibt und wieder ausliest dürfte auch nicht die meiste Zeit brauchen!
N8Falter74 - Do 26.01.06 14:19
Kroko hat folgendes geschrieben: |
N8Falter74 hat folgendes geschrieben: | ...
Übrigens hat die Komponente in diesem Falle nur rund 300 Byte Speicherbedarf, ich schätze das ich nie in den Bereich von mehr als 1000 Byte komme. Das ist für die Registry kein problem - aber wie gesagt, darum geht es auch garnicht.
Grüße
Sebastian |
Mir sind 1000 Byte auf der HDD 3x lieber als in der Registry, eine Klasse zu schreiben die alle Streams in einen schreibt und wieder ausliest dürfte auch nicht die meiste Zeit brauchen! |
Tja, aber genau das ist mein Problem! Ich möchte eigendlich nichts weiter tun, als eine Collection in einen Stream packen und irgendwie speichern & laden können. Das ist leichter gesagt als getan, hast du soetwas schonmal gemacht?
Ich spiele gerade mit TWriter und TReader rum, komme da aber auch nicht richtig weiter!
Sebastian
N8Falter74 - Do 26.01.06 15:07
So, mit eurer Hilfe und ein bischen Googeln, habe ich nun folgende Lösung gefunden: :dance:
Delphi-Quelltext
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:
| procedure LoadCollectionFromStream(Stream: TStream; Collection: TCollection); var rd: TReader; begin rd := TReader.Create(Stream, 4096); try rd.CheckValue(vaCollection); rd.ReadCollection(Collection); finally if Assigned(rd) then FreeAndNil(rd); end; end;
procedure LoadCollectionFromFile(const FileName: string; Collection: TCollection); var fs: TFileStream; begin fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try LoadCollectionFromStream(fs, Collection); finally if Assigned(fs) then FreeAndNil(fs); end; end;
procedure SaveCollectionToStream(Collection: TCollection; Stream: TStream); var wr: TWriter; begin wr := TWriter.Create(Stream, 4096); try wr.WriteCollection(Collection); finally if Assigned(wr) then FreeAndNil(wr); end; end;
procedure SaveCollectionToFile(Collection: TCollection; const FileName: string); var fs: TFileStream; begin fs := TFileStream.Create(FileName, fmCreate or fmShareDenyWrite); try SaveCollectionToStream(Collection, fs); finally if Assigned(fs) then FreeAndNil(fs); end; end; |
Bei mir funktioniert alles soweit. Vieleicht kann das ja nochmal jemand gebrauchen.
Grüße
Sebastian
Martin1966 - Do 26.01.06 16:37
Kroko hat folgendes geschrieben: |
Warum versuchen eigentlich so viele die Registry zu zumüllen, habt ihr schon 20GHZ und 1TB RAM :?: |
Warum müssen eigentlich so viele von "zumüllen" reden? :?
Marco D. - Do 26.01.06 16:44
Gefällt dir der Begriff nicht oder verstehst du nicht, was dahinter steht?
Martin1966 - Do 26.01.06 16:47
Warum zumüllen? Die Registry ist dafür da um Einstellungen/Optionen abzuspeichern. Und so weit ich das hier mitbekommen habe handelt sich um solche Daten.
Marco D. - Do 26.01.06 16:53
Dieser Auszug stammt aus dem EasyHelper von Delphi-Source:
Zitat: |
Was ist die Registry?
Die Registry ist die zentrale Datenbank eines Windows-Betriebssystems
In der Registry werden die meisten Einstellungen und Informationen des Betriebssystems gespeichert. Dazu gehören zum Beispiel der Dateiname des Hintergrundbildes, Informationen über installierte Software und vieles mehr. Diese Werte/Informationen lassen sich ohne große Umstände aus der Datenbank auslesen und abändern.
ACHTUNG! Beachten Sie, dass durch die Manipulation der Registry ins System eingegriffen wird. Legen Sie zuvor ein Backup Ihrer persönlichen Dateien an, um Datenverlust vorzubeugen.
Trotz dieses relativ einfachen Zugriffs und der hirarchisch aufgebauten Struktur sollte man darauf verzichten, zu viele Werte in der Registry zu speichern, da dadurch das System ausgebremst wird. Die Registry dient hauptsächlich zum Speichern von Daten, die von mehreren Programmen verwendet werden.
|
Mein Rechner wird mit zunehmendem 'Alter' immer langsamer, und ich denke das liegt zum großen Teil an der immer fetter werdenden Registry.
Martin1966 - Do 26.01.06 17:02
Keine Ahnung wer den Text geschrieben hat. Ich zitiere da jedefalls lieber Microsoft: ;-)
Zitat: |
A central hierarchical database used in Microsoft Windows 9x, Windows CE, Windows NT, and Windows 2000 used to store information necessary to configure the system for one or more users, applications and hardware devices.
The Registry contains information that Windows continually references during operation, such as profiles for each user, the applications installed on the computer and the types of documents that each can create, property sheet settings for folders and application icons, what hardware exists on the system, and the ports that are being used.
The Registry replaces most of the text-based .ini files used in Windows 3.x and MS-DOS configuration files, such as the Autoexec.bat and Config.sys. Although the Registry is common to several Windows operating systems, there are some differences among them. |
Lg Martin
Marco D. - Do 26.01.06 17:06
Martin1966 hat folgendes geschrieben: |
Keine Ahnung wer den Text geschrieben hat. Ich zitiere da jedefalls lieber Microsoft: ;-)
Zitat: | A central hierarchical database used in Microsoft Windows 9x, Windows CE, Windows NT, and Windows 2000 used to store information necessary to configure the system for one or more users, applications and hardware devices.
The Registry contains information that Windows continually references during operation, such as profiles for each user, the applications installed on the computer and the types of documents that each can create, property sheet settings for folders and application icons, what hardware exists on the system, and the ports that are being used.
The Registry replaces most of the text-based .ini files used in Windows 3.x and MS-DOS configuration files, such as the Autoexec.bat and Config.sys. Although the Registry is common to several Windows operating systems, there are some differences among them. |
Lg Martin |
Ist ja auch logisch, dass Microsoft die negativen Aspekte seiner Produkte nicht anspricht. Das würde ich zumindest nicht machen. :wink:
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!