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.