![]() |
Problem mit dpCollection, loadfromStream / assign
Hallo, ich habe folgendes Problem bei der Verwendung der DpCollection:
savetostream funktioniert, bei loadfromstream kommt Fehlermeldung. Die Klassen sind wir folgt definiert:
Delphi-Quellcode:
Der Stream wird in ein Blob-Feld geschrieben bzw. von dort ausgelesen.
type TChecklistItems = class(TCollection) // Definition Typ TChecklistItems -
private // Beginn des privaten Bereichs bj, rw, knlevel: Integer; selected : boolean; icount : integer; parent : TComponent; iclass : TChecklistItem; tn : string; function liesParent: TComponent; procedure schreibParent(tx: TComponent); function liesListname: string; procedure schreibListname(tx: string); function LiesItemclass: TCollectionItemClass; function GetItem(w: integer): TChecklistItem; procedure SetItem(w: Integer; const Value: TChecklistItem); public // Beginn des öffentlichen Bereichs property Items[X : Integer] : TChecklistItem read GetItem write SetItem; default; constructor create; procedure SaveToStream(Stream: TStream); procedure LoadFromStream(Stream: TStream); property itemlistname: string read lieslistname write schreiblistname; property ItemClass : TCollectionItemClass read LiesItemclass; function add: TChecklistItem; end; TCheckListDummy = class(TComponent) private FItems : TChecklistItems; public constructor Create(AOwner : TComponent); override; destructor Destroy; override; procedure Assign(Source: TPersistent); override; published property Items : TChecklistItems read FItems write FItems; end; procedure TChecklistItem.Assign(Source: TPersistent); begin If Source is TChecklistItem then begin tn:=TChecklistItem(Source).itemname; // FNumbers.Assign(TChecklistItem(Source).Numbers); end else inherited Assign(Source); end; procedure TChecklistItems.SaveToStream(Stream: TStream); var CheckListDummy : TCheckListDummy; begin CheckListDummy:=TCheckListDummy.Create(Nil); Try CheckListDummy.Items.Assign(self); Stream.WriteComponent(CheckListDummy); Finally CheckListDummy.Free; end; end; procedure TChecklistItems.LoadFromStream(Stream: TStream); var CheckListDummy : TCheckListDummy; begin CheckListDummy := TCheckListDummy.Create(Nil); Try Stream.ReadComponent(CheckListDummy); Assign(CheckListDummy.items); Finally CheckListDummy.Free; end; end; Beim Versuch ein loadfromstream zu nutzen kommt eine EAccessViolation, der gleiche Vorgang für die einzelitems funktioniert ebenfalls ohne Probleme. Die originale Version der dpCollection funktioniert einwandfrei. Was habe ich übersehen :cry: ? |
Re: Problem mit dpCollection, loadfromStream / assign
hi,
ich kenn die dpCollection zwar nicht, aber folgende Fragen: In welcher Zeile genau kommt die Fehlermeldung? Welche Fehlermeldung kommt? Dann fällt mir auf, dass du beim Assign die Items übergibst. In deiner Assign-Methode weist du aber Item zu. Entweder ich bring da jetzt was durcheinander oder da ist was falsch. Gruß oki |
Re: Problem mit dpCollection, loadfromStream / assign
Die Fehlermeldung kommt in der Zeile
Delphi-Quellcode:
Es ist eine Zugriffsverletzung (EAccessViolation).
Assign(CheckListDummy.items);
Die dpcollection ist eine Sammlung von Routinen für Collection und deren Ablage in Streams. Die von mir verwendeten Routinen sind praktisch 1:1 übernommen. |
Re: Problem mit dpCollection, loadfromStream / assign
Welche Zugriffsverletzung? Auf einen Nil-Zeiger?
Dann stepp mal mit dem Debugger durch und schau genau an welcher Stelle die Fehlermeldung kommt. Entweder du musst auch Assign vererben (keine Ahnung ob) oder der gelesene Inhalt aus dem Stream ist nicht korrekt. Mich würde auch mal interessieren wozu diese Methode gehört:
Delphi-Quellcode:
ich sehe bei dir nur die Klasse TChecklistItems, die Deklaration bezieht sich aber auf TChecklistItem.
procedure TChecklistItem.Assign(Source: TPersistent);
begin If Source is TChecklistItem then begin tn:=TChecklistItem(Source).itemname; // FNumbers.Assign(TChecklistItem(Source).Numbers); end else inherited Assign(Source); end; Gruß oki |
Re: Problem mit dpCollection, loadfromStream / assign
1. Danke für den Hinweis, die Klasse TChecklistItem ist natürlich auch definiert, TChecklistItems ist die Collection dazu.
Delphi-Quellcode:
Zur Klasse TChecklistItem gehört ebenso ein Dummy for das Streaming, TCheckdummy. Schreiben und Lesen in den Stream funktioniert ohne Probleme.
type TChecklistItem = class(TcollectionItem) // Definition Typ TChecklistItem ---
private tn : string; function liesItemname: string; procedure schreibItemname(tx: string); public constructor create(AOwner: TCollection); override; destructor Destroy; override; property itemname: string read liesItemname write schreibItemname; procedure Assign(Source: TPersistent); override; procedure SaveToStream(Stream: TStream); procedure ReadFromStream(Stream: TStream); end; // TChecklistItem -------------------------------------------------------------- constructor TChecklistItem.Create(AOwner: TCollection); begin inherited Create(AOwner); end; destructor TChecklistItem.Destroy; begin inherited Destroy; end; procedure TChecklistItem.SaveToStream(Stream: TStream); var CheckDummy : TCheckDummy; begin CheckDummy:=TCheckDummy.Create(Nil); Try CheckDummy.ItemTx := self.ItemTx; CheckDummy.tn := self.tn; stream.Position := stream.Size; Stream.WriteComponent(CheckDummy); Finally end; end; procedure TChecklistItem.ReadFromStream(Stream: TStream); var CheckDummy : TCheckDummy; begin CheckDummy:=TCheckDummy.Create(Nil); Try Stream.ReadComponent(CheckDummy); self.itemtext := CheckDummy.ItemTx; self.itemname := CheckDummy.tn; Finally end; end; procedure TChecklistItem.Assign(Source: TPersistent); begin If Source is TChecklistItem then begin tn:=TChecklistItem(Source).itemname; end else inherited Assign(Source); end; 2. Der Fehler kommt direkt beim Aufruf der Assign-Methode, aber nur beim Lesen:
Delphi-Quellcode:
Gruss JK
procedure TChecklistItems.LoadFromStream(Stream: TStream);
var CheckListDummy : TCheckListDummy; begin CheckListDummy := TCheckListDummy.Create(Nil); Try Stream.ReadComponent(CheckListDummy); Assign(CheckListDummy.items); // Hier kommt die Zugriffsverletzung Finally CheckListDummy.Free; end; end; |
Re: Problem mit dpCollection, loadfromStream / assign
Deine Assign-Methode ist nicht vollständig:
Delphi-Quellcode:
Ich gehe mal davon aus, dass TCollectionItem.Assign() im Sourcecode der VCL existiert (bitte prüfen).
procedure TChecklistItem.Assign(Source: TPersistent);
begin If Source is TChecklistItem then begin // hier wird nur ein einziges Property kopiert tn:=TChecklistItem(Source).itemname; // alle Properties der Basisklasse TCollectionItem werden nicht kopiert end else inherited Assign(Source); end; Also kannst du diese Methode aufrufen und danach (!) noch das kopieren was noch fehlt:
Delphi-Quellcode:
Die Struktur sieht jetzt etwas anderst aus, als man das von der Assign-Methode gewöhnt ist, aber das hat damit zu tun,
procedure TChecklistItem.Assign(Source: TPersistent);
begin inherited Assign(Source); // sollte (Source is TCollectionItem) nicht wahr sein, dann gibts 'ne Exception If Source is TChecklistItem then begin tn:=TChecklistItem(Source).tn; end; end; dass wir es uns sparen ALLE Properties zu kopieren. |
Re: Problem mit dpCollection, loadfromStream / assign
Wenn ich die Prozedur so anpasse bekomme ich auch wieder eine Exception: TChecklistItem kann nicht zu TChecklistItem zugewiesen werden.
|
Re: Problem mit dpCollection, loadfromStream / assign
imho wird dann die nicht überschriebene Methode Assign von TPersistent aufgerufen. Prüf mal deine Vererbung.
Gruß oki |
Re: Problem mit dpCollection, loadfromStream / assign
Mal ne andere Frage. Warum gehst du nicht mit dem Debugger Zeile für Zeile durch? Dann siehst du doch wo genau der Fehler kommt und welche Mathode aufgerufen wird.
Gruß oki |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:51 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz