Ich habe etwas ähnliches umgesetzt.
Wenn Du grundsätzlich mit den OTAPI zurecht kommst, sollte es dann mit folgendem Ansatz klappen:
Ich habe einen Containerliste gebaut, in der ich die Breakpoints der aktuellen
Unit sammle und dann die Container nach meiner Logik umsortiere.
Dann lösche ich die Breakpoints und lege sie neu an.
Funktioniert für mich vollständig so.
Parnassis-Breakpoints werden damit nicht unterstützt.
Delphi-Quellcode:
class procedure TXXX.GetBreakpoints(const aSL: TStringList; const aBreakPointList: TList<IOTASourceBreakpoint>; const aUnitFileName: String);
var
DebugSvcs : IOTADebuggerServices;
i : Integer;
BreakPoint: IOTASourceBreakpoint;
begin
if not Supports(BorlandIDEServices, IOTADebuggerServices, DebugSvcs) then
Exit;
aBreakPointList.Clear;
for i := 0 to DebugSvcs.GetSourceBkptCount - 1 do
begin
BreakPoint := DebugSvcs.SourceBkpts[i];
if (BreakPoint.FileName = aUnitFileName) then
begin
aBreakPointList.Add(BreakPoint);
xxTags.RegisterTag(BreakPoint.LineNumber - 1, 0, '!' + IntToStr(aBreakPointList.Count - 1));
end;
end;
end;
class procedure TXXX.RestoreBreakpoints(const BreakpointPosList: TList<TBreakpointPos>);
var
DebugSvcs : IOTADebuggerServices;
i : Integer;
BreakpointPos: TBreakpointPos;
BreakPoint_ : IOTABreakpoint;
begin
if not Supports(BorlandIDEServices, IOTADebuggerServices, DebugSvcs) then
Exit;
for i := 0 to BreakpointPosList.Count - 1 do
begin
BreakpointPos := BreakpointPosList[i];
if (BreakpointPos.Y >= 0) then
begin
BreakPoint_ := DebugSvcs.NewSourceBreakpoint(BreakpointPos.BreakPoint.FileName, BreakpointPos.Y, nil);
BreakPoint_.ThreadCondition := BreakpointPos.BreakPoint.ThreadCondition;
BreakPoint_.StackFramesToLog := BreakpointPos.BreakPoint.StackFramesToLog;
BreakPoint_.DoHandleExceptions := BreakpointPos.BreakPoint.DoHandleExceptions;
BreakPoint_.DoIgnoreExceptions := BreakpointPos.BreakPoint.DoIgnoreExceptions;
BreakPoint_.GroupName := BreakpointPos.BreakPoint.GroupName;
BreakPoint_.DoBreak := BreakpointPos.BreakPoint.DoBreak;
BreakPoint_.LogMessage := BreakpointPos.BreakPoint.LogMessage;
BreakPoint_.EvalExpression := BreakpointPos.BreakPoint.EvalExpression;
BreakPoint_.LogResult := BreakpointPos.BreakPoint.LogResult;
BreakPoint_.EnableGroup := BreakpointPos.BreakPoint.EnableGroup;
BreakPoint_.DisableGroup := BreakpointPos.BreakPoint.DisableGroup;
BreakPoint_.Enabled := BreakpointPos.BreakPoint.Enabled;
BreakPoint_.Expression := BreakpointPos.BreakPoint.Expression;
BreakPoint_.PassCount := BreakpointPos.BreakPoint.PassCount;
end;
BreakpointPos.Free;
end;
end;
class procedure TXXX.ScanBreakpoints(const aBreakPointList: TList<IOTASourceBreakpoint>; const BreakpointPosList: TList<TBreakpointPos>);
var
i : Integer;
BreakPoint : IOTASourceBreakpoint;
LineNumber : Integer;
BreakpointPos: TBreakpointPos;
function GetLineNumber(aNr: Integer): Integer;
var
i : Integer;
S : string;
sNr : string;
Nr : Integer;
lxxTag: TxxTag;
begin
Result := -1;
i := 0;
while (i <= xxTags.Items.Count - 1) do
begin
lxxTag := xxTags.Items[i];
S := lxxTag.S;
if (Copy(S, 1, 1) = '!') then
begin
sNr := Copy(S, 2);
Nr := StrToInt(sNr);
if (Nr = aNr) then
begin
Result := lxxTag.Y;
xxTags.Items.Delete(i);
Exit;
end;
end;
Inc(i);
end;
end;
begin
for i := 0 to aBreakPointList.Count - 1 do
begin
BreakPoint := aBreakPointList[i];
LineNumber := GetLineNumber(i);
if (LineNumber >= 0) then
begin
BreakpointPos := TBreakpointPos.Create;
BreakpointPos.Y := LineNumber;
BreakpointPos.BreakPoint := BreakPoint;
BreakpointPosList.Add(BreakpointPos);
end;
end;
end;