Hier mein Vorschlag, wie man das Problem angehen könnte. (Habe schon gestern abend daran getüftelt, konnte aber nicht ausprobieren, ob es funktioniert, weil ich nicht weiß, wie genau der Compiler die Informationen aus dem Quelltext liest. Das muß ich Dir überlassen, diese fehlenden Programmteile zu programmieren.
Mein Ansatz ist, bei RecordArrays die Recordstruktur nur ein einziges Mal einzulesen (in das array recs), dazu bräuchte es dann variants o.ä., und dann so oft wie gewünscht daraus einen String zu erstellen für jeden Record und diesen am Bildschirm ausgeben.
Dann könnte man auch schon bei der Angabe im Watch-Fenster nach dem Variablennamen,
durch Komma getrennt, die gewünschten Optionen angeben:
10 = die nächsten 10 Records bzw Datenfelder
3h4 = 3x als HexZahl zu 4 Bytes, mit $ zu Beginn, nicht 0x, das spart ein Byte (- oder gleich ganz ohne)
3L oder 3z = 3 Zeilen lang ausgeben, eingerückt ab hinter dem Namen der Variablen, wie in meinem Programm unten)
b = Byte, c=Char, d=dezimal, sh=shortint, sm=smallint, w=word, i=integer, dw=Dword, qw=qword, i64=int64
zB: 12sh = 12 x shortint; 4li = 4 Zeilen lang als Integer; etc.
Zu Beginn (am besten bereits, wo der Record definiert wird), lasse ich die Struktur des Records in folgender Weise speichern:
Code: Alles auswählen
var p: pointer; // = Zeiger auf Beginn des Records
Type TRec =
record name;string; adresse:dword;
vt:vartype; // $F000 + '(' oder ')' ==> Klammer einfügen
ArrayPtr:pointer; //(wenn vt = vararray)
offs:integer;
modus:word; end; //falls noch mehr differenziert werden muß, zB shortstring oder ansistring
end;
Type TRecs = array of TRec;
var recs:TRecs; Reclg:integer; // Anzahl der Recs zur Darstellung eines Records
ArrayPtr weist auf einen Record mit den Daten zum entsprechenden Array:
Code: Alles auswählen
TArrayRec = record cnt:integer; vtype:word; PARec: PArrayRec; Voffs; word; end
PArrayRec = ^TArrayRec;
PArec brauche ich, falls es mehrmals geschachtelte arrays gibt (array of array of ..)
ArrayPtr wird durch die Funktion VarArray_to_String in einen String umgewandelt
( mit () als Eingrenzung )
Code: Alles auswählen
function VarArray_To_String(PR: PArrayRec):string;
var s:string; i:integer;
begin
with PR^ do
begin
....
for i:=0 to cnt-1 do
begin
case vtype of
varinteger: s:=intToStr(pinteger(p+offs[i])^);
vararray: s:=VarArray_To_String(parec);
...
end;
if result='' then result:=result+s else result:=result + ',' + s;
end;
result:='('+result+')';
end;
TRec wird dann beim Anzeigen in einen String umgewandelt:
Zu Beginn werden mittels der Prozedur
Read_offsets_and_Vartypes - die muß noch erstellt werden -
die einzelnen Offsets und Vartypes der RecordFelder in die WordArrays
vt und offs übertragen (Platz freilassen für evtl. Klammern bzw in einem zweiten Schritt einfügen).
bei klammer: vt = $F000 + ord(Klammer)
Dann wird damit der Record in einen String übertragen:
Code: Alles auswählen
function Record2String(p:pchar; recs:TRecs):string:
var s:string; i:integer;
begin
i:=0; result:='';
repeat with recs[i] do
case vt of
vararray:
begin with PArrayPtr(p+offs[i])^ do s:=var_array_To_String(ArrayPtr);
varinteger; s:=intToStr((p+offs[i])^);
$F000 + ord('('): s:='(';
$F000 + ord (')'): s:=')';
....
end;
if result='' then result :=s else result :=result+','+s;
inc(i);
until i>=reclg;
end;
Zur Ausgabe des strings am Bildschirm wird wohl der Canvas des Fensters benutzt, oder?
Wenn nicht, dann die Prozedur entsprechend ändern.
Code: Alles auswählen
Procedure Record_Ausgeben(x,y:integer; varname:string; recs:TRecs;
count:integer; Zeilen:integer);
// Zeilen = wenn >0, dann max. Anzahl Zeilen zur Ausgabe der Records,
// sonst max. eine Zeile
var maxlg:integer; // Ausgabeschirm-Breite
z,c,n, x,x0, y:integer; s:string;
p:pchar;
procedure OutText(s:string);
begin with canvas do
begin textout(x,y,s); x:=penpos.x; y:=penpos.y; end;
end;
begin
Read_offsets_and_Vartypes;
.... maxlg=.. p=..
with canvas do
begin
x:=PenPos.x; y:=PenPos.y;
outtext(varname);
x0:=PenPos.x;
{ outtext( VarAdresse } ); // wenn gewünscht
n:=0; z:=0; // z=Anzahl ausgegebener Zeilen
repeat
p:= ... = adresse des n-ten Records
s:=Record2String(p, recs);
outtext(s);
if PenPos.x>=maxlg then // über den rechten Rand hinauasgeschrieben
begin inc(z); if z>=zeilen then exit;
inc(y, Textheight('M'));
if x>maxlg then begin x:=x0; textout(x,y,s); end // Ausgabe wdh in neuer Zeile
else x:=x0;
end;
inc(i);
until i>=count;
end; // with canvas
end;
Ich denke, in dieser Form dürfte es nicht so lange dauern, bis der Debugger die Records am BNildschirm ausgibt.
Vielleicht könnte masn auch die Ausgabe der anderen lokalen Varablen am Bildschirm beschleunigen, indem man man zuerst alles in einer TStringList speichrt und dann in einem Rutsch ausgibt?