AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Problem mit dpCollection, loadfromStream / assign
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit dpCollection, loadfromStream / assign

Ein Thema von JohannesK · begonnen am 16. Apr 2009 · letzter Beitrag vom 17. Apr 2009
Antwort Antwort
JohannesK

Registriert seit: 17. Jul 2003
Ort: Abtwil
118 Beiträge
 
Delphi 2010 Professional
 
#1

Problem mit dpCollection, loadfromStream / assign

  Alt 16. Apr 2009, 16:06
Hallo, ich habe folgendes Problem bei der Verwendung der DpCollection:

savetostream funktioniert, bei loadfromstream kommt Fehlermeldung.

Die Klassen sind wir folgt definiert:
Delphi-Quellcode:
 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;
Der Stream wird in ein Blob-Feld geschrieben bzw. von dort ausgelesen.
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 ?
mit freundlichem Gruss

So einfach wie möglich. Aber nicht einfacher.
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#2

Re: Problem mit dpCollection, loadfromStream / assign

  Alt 16. Apr 2009, 21:25
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
42
  Mit Zitat antworten Zitat
JohannesK

Registriert seit: 17. Jul 2003
Ort: Abtwil
118 Beiträge
 
Delphi 2010 Professional
 
#3

Re: Problem mit dpCollection, loadfromStream / assign

  Alt 16. Apr 2009, 22:06
Die Fehlermeldung kommt in der Zeile
Assign(CheckListDummy.items); Es ist eine Zugriffsverletzung (EAccessViolation).
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.
mit freundlichem Gruss

So einfach wie möglich. Aber nicht einfacher.
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#4

Re: Problem mit dpCollection, loadfromStream / assign

  Alt 17. Apr 2009, 06:20
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:
  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;
ich sehe bei dir nur die Klasse TChecklistItems, die Deklaration bezieht sich aber auf TChecklistItem.

Gruß oki
42
  Mit Zitat antworten Zitat
JohannesK

Registriert seit: 17. Jul 2003
Ort: Abtwil
118 Beiträge
 
Delphi 2010 Professional
 
#5

Re: Problem mit dpCollection, loadfromStream / assign

  Alt 17. Apr 2009, 07:52
1. Danke für den Hinweis, die Klasse TChecklistItem ist natürlich auch definiert, TChecklistItems ist die Collection dazu.

Delphi-Quellcode:
  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;
Zur Klasse TChecklistItem gehört ebenso ein Dummy for das Streaming, TCheckdummy. Schreiben und Lesen in den Stream funktioniert ohne Probleme.

2. Der Fehler kommt direkt beim Aufruf der Assign-Methode, aber nur beim Lesen:

Delphi-Quellcode:
  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;
Gruss JK
mit freundlichem Gruss

So einfach wie möglich. Aber nicht einfacher.
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#6

Re: Problem mit dpCollection, loadfromStream / assign

  Alt 17. Apr 2009, 09:12
Deine Assign-Methode ist nicht vollständig:
Delphi-Quellcode:
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;
Ich gehe mal davon aus, dass TCollectionItem.Assign() im Sourcecode der VCL existiert (bitte prüfen).
Also kannst du diese Methode aufrufen und danach (!) noch das kopieren was noch fehlt:
Delphi-Quellcode:
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;
Die Struktur sieht jetzt etwas anderst aus, als man das von der Assign-Methode gewöhnt ist, aber das hat damit zu tun,
dass wir es uns sparen ALLE Properties zu kopieren.
  Mit Zitat antworten Zitat
JohannesK

Registriert seit: 17. Jul 2003
Ort: Abtwil
118 Beiträge
 
Delphi 2010 Professional
 
#7

Re: Problem mit dpCollection, loadfromStream / assign

  Alt 17. Apr 2009, 11:19
Wenn ich die Prozedur so anpasse bekomme ich auch wieder eine Exception: TChecklistItem kann nicht zu TChecklistItem zugewiesen werden.
mit freundlichem Gruss

So einfach wie möglich. Aber nicht einfacher.
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#8

Re: Problem mit dpCollection, loadfromStream / assign

  Alt 17. Apr 2009, 11:57
imho wird dann die nicht überschriebene Methode Assign von TPersistent aufgerufen. Prüf mal deine Vererbung.

Gruß oki
42
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#9

Re: Problem mit dpCollection, loadfromStream / assign

  Alt 17. Apr 2009, 11:59
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
42
  Mit Zitat antworten Zitat
Antwort Antwort


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 20:29 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