Merkwürdiger EStringListError

Ich habe hier gerade einen ziemlich seltsamen Fehler, aus dem ich nicht schlau werde:

  TDate = class
    private
    fComment: TStringList ;
    …
    public
     property Comment:TStringList read fComment ;
    …
   end ;

  TFrmNotes = class (TForm)
    MmoNotes: TMemo;
    private
    fDate: TDate ;
     procedure SetDate(D:TDate) ;
    public
     property Date:TDate read fDate write SetDate ;
   end ;

procedure TFrmNotes.SetDate(D:TDate) ;
var
  i: Integer ;
begin
  fDate:=D ;
   if Assigned(fDate) then begin
    MmoNotes.Lines.Clear ;
     for i:=0 to fDate.Comment.Count-1 do
      MmoNotes.Lines.Add(fDate.Comment[i]) ;
   end ;
end ;

Die entscheidende Zeile habe unterstrichen. Vor der ersten Ausführung dieses Befehls steht in den überwachten Ausdrücken

fDate.Comment.count: 2
MmoNotes.Lines.Count: 0
i: 0
fDate.Comment[0]: ‚abc‘
fDate.Comment[1]: ‚xyz‘

Danach steht dort

fDate.Comment.count: 1
MmoNotes.Lines.Count: 1
i: 0
fDate.Comment[0]: ‚abc‘
fDate.Comment[1]: Delphi Exception EStringListError bei $4C3FCD9

Das Ganze führt beim nächsten Schleifendurchlauf natürlich zu einem Fehler (Der Index der Liste überschreitet das Maximum(1)), der übrigens auch auftritt, wenn ich die Stringlisten nicht zeilenweise, sondern mit Assign kopiere.

Woran liegt das und (vor allem) wie kann ich das Problem lösen?

Schuss ins Blaue
Hallo…

Hm…

Versuch mal Folgendes:

  • Statt TStringList TStrings verwenden.

  • Im Constructor Deiner Klasse auch dafür sorgen, dass das Objekt kreiert wird

  • TDate in TmyDate umbenennen

    TmyDate = class
    private
    fComment: TStrings ;

    public
    constructor create; override;
    property Comment:TStringList read fComment ;

    end ;

    constructor TmyDate.Create;
    begin
    inherited;
    fComment := TStrings.Create(self);
    end;

Ist aus dem Kopf heraus, aber was ich meine sollte klar werden…

Gruß Thorsten

PS: Rückmeldung wäre schön.

Hallo Thorsten,

  • Statt TStringList TStrings verwenden.

Damit habe ich mir erwartungsgemäß einen abstrakten Fehler eingehandelt. Ich könnte mir aus TStrings natürlich eine eigene TStringList basteln, aber davon abgesehen, daß das wohl kaum Sinn der Sache ist, kann mir niemand garantieren, daß das Problem damit gelöst wird.

  • Im Constructor Deiner Klasse auch dafür sorgen, dass das
    Objekt kreiert wird

Wenn ich das nicht schon längst gemacht hätte, wäre ich gar nicht so weit gekommen (Daß die Inhalte der Objete in den überwachten Ausdrücken erscheinen, zeigt ja, daß sie existieren.)

  • TDate in TmyDate umbenennen

Das hat nichts gebracht.

Hallo MrStupid,

der Quellcode, den du gesendet hast scheint OK zu sein,
der Fehler könnte sich in dem Teil befinden, den du mit … beschrieben hast.

Evtl. ligt es daran, dass du in der Methode SetDate mit fDate := D; direkt den Zeiger des Objectes zuweist. Ändert sich irgendwo in deinem Programm etwas mit dem Object D dann ist das identisch mit einer Änderung an fDate direkt. Falls möglich versuche mal zuerst das Objekt fDate zu erzeugen und anschließend via fDate.Assign(D) das Objekt D nach fDate zu kopieren.
Ich möchte betonen, dass dies warscheinlich keine Lösung bringt, aber den gesuchten Fehler eingrenzen kann.

Du solltest auch dein Objektnamen ändern, da TDate bereits existiert (ist vom Typ TDateTime). Eigentlich sollte der Compiler das richtig handhaben, aber seit Delphi 1 sind mir schon die merkwürdigsten Dinge passiert.

Gruß

Mike

Problem gelöst
Vielen Dank an alle, aber der Fehler lag tatsächlich in einem anderen Bereich des Codes und zwar in der Ereignisbehandlungsroutine für das OnChange-Event von MmoNotes:

procedure TFrmNotes.MmoNotesChange(Sender: TObject);
begin
   if Assigned(fDate) then fDate.Comment.Assign(MmoNotes.Lines) ;
end ;

Verwirrt hat mich dabei, daß dieses Ereignis während (und nicht etwa am Ende) der Methode Assign ausgelöst und bearbeitet wird. Das hat zur Folge, daß MmoNotes.Lines.Assign(fDate.Comment) zunächst die erste Zeile von fDate.Comment nach MmoNotes.Lines kopiert. Dann wird die Methode unterbrochen und fDate.Comment.Assign(MmoNotes.Lines) schreibt die unvollständige Liste nach fDate.Comment zurück. Wenn MmoNotes.Lines.Assign(fDate.Comment) dann mit der zweiten Zeile weitermachen will, ist diese nicht mehr da und es kommt zum beschrieben Fehler. Warum ich das gestern beim Debuggen übersehen habe, weiß ich allerdings auch nicht.

Ich habe jetzt in TFrmNotes.SetDate kurzerhand ein Flag gesetzt, das TFrmNotes.MmoNotesChange veranlaßt, sich rauszuhalten und damit ist das Problem gelöst.