Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Stream in Registrierung speichern (https://www.delphipraxis.net/59432-stream-registrierung-speichern.html)

dahead 22. Dez 2005 10:11


Stream in Registrierung speichern
 
Hallo,

ich speichere Einstellungen von meinem akt. Projekt in der Registrierung. Nun muss ich auch die Header (TVTHeader) der TVirtualStringTree (von Mike Lischke) in der Registrierung speichern.

Da die Header nur die Prozedur SaveToStream bzw. LoadFromStream besitzen, weiß ich nicht, wie ich diese Daten in der Registrierung kriegen soll.

Hoffe jemand hat einen Tipp für mich.

Danke im Voraus!

Der_Unwissende 22. Dez 2005 10:52

Re: Stream in Registrierung speichern
 
Hi,
das Wichtigste zuerst: Du solltest lieber keine Streams in der Registry speichern.

Natürlich hat es keine Performance-Nachteile oder ähnliches, aber imho ist es kein schöner Weg. Daten die zu deinem Programm gehören sollten möglichst auch bei diesem Programm liegen. Macht dein Programm auch leichter portierbar (z.B. auf einen USB-Stick der mal keine eigene Registry hat :wink:).

Aber du kannst ganz einfach einen MemoryStream als Puffer benutzen, die Daten dort reinspeichern und von diesem Stream auch gleich als binary-data in die Registry schreiben.
Hier mal als ungetesteter Ansatz:

Delphi-Quellcode:
procedure VTHeaderToRegistry(const VirtualStringTree : TVirtualStringTree; const Registry : TRegistry);
var buffer : TMemoryStream;
begin
  if assigned(VirtualStringTree) and assigned(Registry) then
    begin
      buffer := TMemoryStream.Create;
      VirtualStringTree.SaveToStream(buffer);
      Registry.WriteBinaryData('Dein Schlüssel', buffer.Memory, buffer.Size);
      buffer.Free;
    end;
end;
Wie gesagt ungetestet.

Gruß Der Unwissende

dahead 22. Dez 2005 11:14

Re: Stream in Registrierung speichern
 
Hallo,

erstmal danke für deine zügige und informative Antwort.

Ich habe das natürlich gleich mal getestet und dann wie folgt umgebaut:

Delphi-Quellcode:
 Buffer := TMemoryStream.Create;
 VSTObjects.Header.SaveToStream(Buffer);
 Reg.WriteBinaryData(SSetVSTObjectsHeader, buffer, buffer.Size);
 Buffer.Free;
Also ich habe nur das .memory von Buffer entfernt, da der Compiler mir gemeldet hat, dass ein "constant object nicht als var parameter übergeben werden darf".

So wie es aussieht speichert er die Infos aber korrekt ab.

Nun möchte ich sie allerdings auch wieder laden. Das mache ich momentan wie folgt:

Delphi-Quellcode:
if Reg.ValueExists(SSetVSTObjectsHeader) then
 begin
  Buffer := TMemoryStream.Create;
  Reg.ReadBinaryData(SSetVSTObjectsHeader, Buffer, Buffer.Size);
  VSTObjects.Header.LoadFromStream(Buffer);
  Buffer.Free;
 end;
Leider bekomme ich da den Fehler:

Delphi-Quellcode:
---------------------------
Debugger Exception Notification
---------------------------
Project raised exception class ERegistryException with message 'Invalid data type for 'VSTObjects.Header''. Process stopped. Use Step or Run to continue.
---------------------------
OK  Help  
---------------------------

DevilsCamp 22. Dez 2005 12:02

Re: Stream in Registrierung speichern
 
Da hast du einen Fehler gemacht, den ich Anfangs auch immer gemacht habe.


Delphi-Quellcode:
if Reg.ValueExists(SSetVSTObjectsHeader) then
begin
  Buffer := TMemoryStream.Create;
  Reg.ReadBinaryData(SSetVSTObjectsHeader, Buffer, Buffer.Size);

// Buffer.Position ist jetzt auf Position buffer.size.
// Daher musst du die Position zurücksetzen

  buffer.position := 0;

// Jetzt sollte es gehen

  VSTObjects.Header.LoadFromStream(Buffer);
  Buffer.Free;
end;
Siehe Kommentare im Code.

Ich vermute mal, dass VSTObjects.Header.LoadFromStream die Position nicht zurücksetzt.
Da aber die Position von buffer auf buffer.size steht, wird nicht kopiert
Delphi-Quellcode:
VSTObjects.Header.LoadFromStream(Buffer);
liefert einen leeren Stream, der natürlich keine Header-Informationen besitzt...

dahead 22. Dez 2005 12:22

Re: Stream in Registrierung speichern
 
Danke für deine Antwort!

Die Idee hörte sich gut an, leider tritt immer noch der selbe Fehler (s. o.) auf. Scheint wohl also doch nicht an "Position" zu liegen.

DevilsCamp 22. Dez 2005 12:26

Re: Stream in Registrierung speichern
 
Ich denke mal der Fehler liegt schon beim speichern:

Delphi-Quellcode:
Buffer := TMemoryStream.Create;
VSTObjects.Header.SaveToStream(Buffer);

// Buffer.Position auf 0 setzen
  Buffer.Position := 0;


Reg.WriteBinaryData(SSetVSTObjectsHeader, buffer, buffer.Size);
Buffer.Free;

Versuch das mal.
Möglicherweise lag hier schon der Fehler und im Reg-Eintrag war ein leerer Stream gespeichert.

dahead 22. Dez 2005 12:32

Re: Stream in Registrierung speichern
 
Hätte das vielleicht schon oben schreiben sollen: das habe ich auch gleich getestet.

Der REG_Binary Eintrag wird auch korrekt (sieht zumindest so aus) erstellt und gespeichert. Leider tritt der Fehler beim Laden immer noch auf.

Hier mal ein Auszug aus beiden Routinen:

Delphi-Quellcode:
procedure LoadSettings;
...
       if Reg.ValueExists(SSetVSTObjectsHeader) then
        begin
         Buffer := TMemoryStream.Create;
         Reg.ReadBinaryData(SSetVSTObjectsHeader, Buffer, Buffer.Size);
         Buffer.Position := 0; //hier
         VSTObjects.Header.LoadFromStream(Buffer);
         Buffer.Free;
        end;
end;

procedure SaveSettings;
...
       Buffer := TMemoryStream.Create;
       VSTObjects.Header.SaveToStream(Buffer);
       Buffer.Position := 0; //hier
       Reg.WriteBinaryData(SSetVSTObjectsHeader, Buffer, Buffer.Size);
       Buffer.Free;
end;
edit: hier mal der code aus der registrierung:

Code:
"ViewToolbar"=dword:00000001
"VSTObjects.Header"=hex:3c,c8,ad,00,00,da,ad,00,84,f3,12,00,26,15,4b,00,8c,1f,\
  ab,00,a1,08,47,00,8c,1f,ab,00,ee,3e,47,00,01,31,47,00,8c,1f,ab,00,04,f4,12,\
  00,71,31,47,00,b3,8c,45,00,7c,f4,12,00,04,f4,12,00,8c,1f,ab,00,83,8a,45,00,\
  00,00,00,00,4e,bc,00,00,f4,02,2b,00,14,f6,12,00,00,00,00,00,d0,f3,12,00,4c,\
  be,45,00,14,f6,12,00,c8,f4,12,00,8c,1f,ab,00,50,f4,12,00,c6,c4,45,00,8c,1f,\
  ab,00,50,f4,12,00,b3,8c,45,00,c8,f4,12,00,50,f4,12,00,8c,1f,ab,00,88,00,d7,\
  77,4c,f2,12,00,00,f3,12,00,cc,b3,d1,77,a7,b3,d1,77,66,03,24,00,48,71,15,00,\
  01,00,00,02,00,00,00,00,01,00,00,00,00,00,00,00,d0,f2,12,00,01,00,00,02,e4,\
  f5,12,00,67,04,d4,77,b0,b3,d1,77,ff,ff,ff,ff,a7,b3,d1,77,7c,2e,46,5d,f4,02,\
  2b,00,20,00,00,00,66,03,24,00,01,00,00,02,c8,f5,12,00,7b,ec,45,5d,1c,ed,45,\
  5d,86,d8,97,7c,d8,79,95,00,4c,f5,12,00,9c,60,0f,5b,d8,79,95,00,fe,ff,ff,ff,\
  fe,ff,ff,ff,d8,7c,95,00,24,79,95,00,64,f3,12,00,41,50,92,7c,8c,f3,12,00,e4,\
  00,13

DevilsCamp 22. Dez 2005 13:02

Re: Stream in Registrierung speichern
 
Ich wollte gerade das selber testen, da habe ich den Fehler gefunden:

Delphi-Quellcode:
Buffer := TMemoryStream.Create;
Reg.ReadBinaryData(SSetVSTObjectsHeader, Buffer, Buffer.Size); // <---- Hier ist der Fehler.
Folgendes Problem existiert:
Du createst eine TMemoryStream Instanz.
Dann ist
Delphi-Quellcode:
Buffer.Size = 0
Jetzt liest du NULL Bytes aus der Registry in einen Buffer

Es ist zwar anders als ich erst vermutete aber in einem hatte ich Recht:
Der MemoryStream ist leer ;)


Ausweg:
Nutze statt TRegistry die Klasse TRegistryIniFile.
Da hast du zwei Methoden Namens WriteBinaryStream und ReadBinaryStream. Damit hast du keine Probleme (das nutze ich in einem Programm selber).

Oder du speicherst in einem anderen Key die Größe des Headers und liest die dann aus, bevor du die Daten lädst.

DevilsCamp 22. Dez 2005 13:04

Re: Stream in Registrierung speichern
 
Zitat:

Zitat von DevilsCamp
Ich wollte gerade das selber testen, da habe ich den Fehler gefunden:

Delphi-Quellcode:
Buffer := TMemoryStream.Create;
Reg.ReadBinaryData(SSetVSTObjectsHeader, Buffer, Buffer.Size); // <---- Hier ist der Fehler.
Folgendes Problem existiert:
Du createst eine TMemoryStream Instanz.
Dann ist
Delphi-Quellcode:
Buffer.Size = 0
Jetzt liest du NULL Bytes aus der Registry in einen Buffer

Es ist zwar anders als ich erst vermutete aber in einem hatte ich Recht:
Der MemoryStream ist leer ;)


Ausweg:
Nutze statt TRegistry die Klasse TRegistryIniFile.
Da hast du zwei Methoden Namens WriteBinaryStream und ReadBinaryStream. Damit hast du keine Probleme (das nutze ich in einem Programm selber).

Oder du speicherst in einem anderen Key die Größe des Headers und liest die dann aus, bevor du die Daten lädst.

Narf. Bin ausversehen auf den Zitat-Button gekommen.
Kann jemand diesen Post hier löschen?

DevilsCamp 22. Dez 2005 13:23

Re: Stream in Registrierung speichern
 
Folgender Code funktioniert definitiv (hab's gerade getestet):

Delphi-Quellcode:
uses
  Registry;

// Speichern des Headers in die Registry
procedure TForm1.Button1Click(Sender: TObject);
var
  regi   : TRegistryIniFile;
  buffer : TMemoryStream;
begin
  regi         := TRegistryIniFile.Create(DEINKEY);


  Buffer := TMemoryStream.Create;
  VirtualStringTree1.Header.SaveToStream(Buffer);
  Buffer.Position := 0; //hier
  Regi.WriteBinaryStream(SECTION, NAME, Buffer);
  regi.Free;

  VirtualStringTree1.Header.Columns.Clear;
end;


// Laden der Daten aus der Registry
procedure TForm1.Button2Click(Sender: TObject);
var
  regi   : TRegistryIniFile;
  buffer : TMemoryStream;
  i      : Integer;
  p      : PChar;
begin
  regi         := TRegistryIniFile.Create(DEINKEY);
  Buffer := TMemoryStream.Create;
  regi.ReadBinaryStream(SECTION, NAME, Buffer);
  Buffer.Position := 0;
  VirtualStringTree1.Header.LoadFromStream(Buffer);
  Buffer.Free;
  regi.Free;
end;
Delphi-Quellcode:
DEINKEY = Pfad zu deinem Key ohne den Key in den gespeichert werden soll
SECTION = Key in den gespeichert werden soll
NAME   = (selbsterklärend)


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:33 Uhr.
Seite 1 von 2  1 2      

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