AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Stream in Registrierung speichern

Ein Thema von dahead · begonnen am 22. Dez 2005 · letzter Beitrag vom 22. Dez 2005
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von dahead
dahead

Registriert seit: 16. Mai 2005
620 Beiträge
 
#1

Stream in Registrierung speichern

  Alt 22. Dez 2005, 10:11
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!
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: Stream in Registrierung speichern

  Alt 22. Dez 2005, 10:52
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 ).

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
  Mit Zitat antworten Zitat
Benutzerbild von dahead
dahead

Registriert seit: 16. Mai 2005
620 Beiträge
 
#3

Re: Stream in Registrierung speichern

  Alt 22. Dez 2005, 11:14
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
---------------------------
  Mit Zitat antworten Zitat
DevilsCamp
(Gast)

n/a Beiträge
 
#4

Re: Stream in Registrierung speichern

  Alt 22. Dez 2005, 12:02
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
VSTObjects.Header.LoadFromStream(Buffer); liefert einen leeren Stream, der natürlich keine Header-Informationen besitzt...
  Mit Zitat antworten Zitat
Benutzerbild von dahead
dahead

Registriert seit: 16. Mai 2005
620 Beiträge
 
#5

Re: Stream in Registrierung speichern

  Alt 22. Dez 2005, 12:22
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.
  Mit Zitat antworten Zitat
DevilsCamp
(Gast)

n/a Beiträge
 
#6

Re: Stream in Registrierung speichern

  Alt 22. Dez 2005, 12:26
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.
  Mit Zitat antworten Zitat
Benutzerbild von dahead
dahead

Registriert seit: 16. Mai 2005
620 Beiträge
 
#7

Re: Stream in Registrierung speichern

  Alt 22. Dez 2005, 12:32
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
  Mit Zitat antworten Zitat
DevilsCamp
(Gast)

n/a Beiträge
 
#8

Re: Stream in Registrierung speichern

  Alt 22. Dez 2005, 13:02
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
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.
  Mit Zitat antworten Zitat
DevilsCamp
(Gast)

n/a Beiträge
 
#9

Re: Stream in Registrierung speichern

  Alt 22. Dez 2005, 13:04
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
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?
  Mit Zitat antworten Zitat
DevilsCamp
(Gast)

n/a Beiträge
 
#10

Re: Stream in Registrierung speichern

  Alt 22. Dez 2005, 13:23
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)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:13 Uhr.
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