Hi,
ich komme einer EInvalidPointer-
Exception nicht auf die Schliche.
Ich verwendet die aktuellste Version von SynEdit (2.0.4 glaube ich) unter Turbo Delphi. D.h. ich erstelle sie dynamisch auf meinem Formular. Der Inhalt der SynEdits (genau genommen sind es zwei), werden hin und her geschoben und auch an eine Klasse weitergeleitet zu Verwendung.
Diese Klassen mal schematisch:
Delphi-Quellcode:
TWorker = class
private
FSource: TStrings;
protected
function GetSource: TStrings;
procedure SetSource(const ASource: TStrings);
published
property Source: TStrings read FSource write FSource;
end;
function TWorker.GetSource: TStrings;
begin
Result := FSource;
end;
procedure TWorker.SetSource(const ASource: TStrings);
begin
// Source-Code setzen
if ASource <> nil then
FSource.Assign(ASource);
end;
Delphi-Quellcode:
TInterpreter = class(TWorker)
protected
function GetSource: TStrings;
procedure SetSource(const Value: TStrings);
published
property Source: TStrings read GetSource write SetSource;
end;
function TInterpreter.GetSource: TStrings;
begin
Result := inherited GetSource;
end;
procedure TInterpreter.SetSource(const Value: TStrings);
begin
inherited SetSource(Value);
// Zurücksetzen
EIP := 0;
PrepareSource;
end;
Im Programm gibt es dann einige Zuweisungen:
Delphi-Quellcode:
procedure TfrmMain.Create(Sender: TObject);
begin
// SynEdit erzeugen
sedtSourceCode := TSynEdit.Create(tabEditCode);
with sedtSourceCode do
begin
Parent := tabEditCode;
Align := alClient;
WordWrap := true;
Gutter.ShowLineNumbers := true;
Gutter.AutoSize := true;
Gutter.LeadingZeros := false;
Gutter.DigitCount := 3;
Gutter.LineNumberStart := 0;
end;
// SynView erzeugen
sedtViewCode := TSynEdit.Create(tabRun);
with sedtViewCode do
begin
ReadOnly := true;
Align := alClient;
Parent := tabRun;
WordWrap := true;
Gutter.ShowLineNumbers := true;
Gutter.AutoSize := true;
Gutter.LeadingZeros := false;
Gutter.DigitCount := 3;
Gutter.LineNumberStart := 0;
end;
aLexer := TLexer.Create;
aInterpreter := TInterpreter.Create(sedtSourceCode.Lines, aLexer);
end;
procedure TfrmMain.pgcModesChange(Sender: TObject);
begin
// Code übernehmen
sedtViewCode.Lines.Assign(sedtSourceCode.Lines);
aInterpreter.Source := sedtViewCode.Lines;
end;
Läuft das Programm so, wie es hier steht, gibt es kein Problem.
Das Problem entsteht erst, wenn in der
TInterpreter-Klasse ein Aufruf geschieht, der den SynEdit-Text verarbeiten soll:
Delphi-Quellcode:
procedure TfrmMain.RunRun1Execute(Sender: TObject);
begin
// Initialisieren
sedtViewCode.Lines.Assign(sedtSourceCode.Lines);
aInterpreter.Source := sedtViewCode.Lines;
pgcModes.ActivePage := tabRun;
aInterpreter.OnGetData := self.GetDataInput;
aInterpreter.OnFinished := self.ExecutionFinished;
aInterpreter.Execute(lbxOutput.Items);
end;
procedure TAsmWorker.ParseLine(ALine: integer; var AOperation, AParam: string);
var
iPos: integer;
begin
FSource[ALine] := Trim(FSource[ALine]);
// Erstmal alles als Operation ansehen
AOperation := FSource[ALine];
// Parameter-Anfang finden
iPos := Pos(' ', AOperation[ALine]);
if iPos > 0 then
begin
// Es sind Parameter vorhanden
AParam := Copy(AOperation[ALine], iPos + 1, Length(AOperation) - iPos);
Delete(AOperation, iPos, Length(AOperation) - iPos + 1);
end else begin
// Keine Parameter vorhanden
AParam := '';
end;
// Nochmal alles trimmen
AOperation := Trim(AOperation);
AParam := Trim(AParam);
end;
function TInterpreter.Execute(AOutput: TStrings): Boolean;
{...}
begin
// Initialisieren
Result := true;
EIP := 0;
// Execution-Loop
if (Source <> nil) and (EIP < Source.Count) then
begin
while ((cmdCommand <> nil) and (cmdCommand.Operation <> opStop))
and (Result) and (EIP < Source.Count) and (not FTerminated) do
begin
// Zeile parsen
ParseLine(EIP, sOperation, sParam);
// Lexer ausführen
cmdCommand := Lexer.CreateCommand(sOperation, sParam);
if cmdCommand <> nil then
begin
// Operation ausführen
case cmdCommand.Operation of
{ ... }
end;
end;
Application.ProcessMessages;
EIP := EIP + 1;
end;
end;
{ ... }
end;
Ich habe das soweit eingrenzen können, als dass das Problem in dem
sedtSourceCode-SynEdit liegt. Außerdem liegt das Problem definitiv im Aufruf von
aInterpreter.Execute.
Was mich allerdings wundert, da überall nur auf StringListen zugegriffen, wird, die nur den Text-Inhalt des SynEdits haben, jedoch eigentlich keinen Zeiger sein sollten (
Assign weist ja den Inhalt zu und nicht den Zeiger auf den Inhalt aus einem anderen Feld).
So oder so bekomme ich eine
EInvalidPointer-
Exception in der
SynTextDrawer.pas in
TheTextDrawer.ReleaseETODist beim Beenden des Programmes.
Hat jemand eine Idee?
Chris