我正在尝试为TJSONObject或TJSONValue编写调试器可视化工具。我的大部分可视化工作都很好。我遇到的问题是获取对TJSONObject的引用,或至少引用TJSONObject的tostring()值。
根据我见过的样本,以及Jeremy North在http://edn.embarcadero.com/article/40268发表的精彩帖子,我应该从我的IOTADebuggerVisualizerExternalViewer实现的Show方法中得到我需要的东西。具体来说,来自Expression,TypeName和EvalResult字符串参数。
据我所知,Expression是被检查变量的名称(可视化),TypeName是变量的类名,EvalResult是变量的默认字符串表示。
对于一个简单的测试,我在我的TFrame后代放置了一个TMemo。从IOTADebuggerVisualizerExternalViewer.Show方法我调用我的TFrame的ShowJSONObject方法,我传递Expression,TypeName和EvalResult。相关代码显示在此处:
function TDebuggerJSONVisualizer.Show(const Expression, TypeName, EvalResult: string;
SuggestedLeft, SuggestedTop: Integer):
IOTADebuggerVisualizerExternalViewerUpdater;
var
AForm: TCustomForm;
AFrame: TJSONViewerFrame;
VisDockForm: INTACustomDockableForm;
begin
VisDockForm := TJSONVisualizerForm.Create(Expression) as INTACustomDockableForm;
AForm := (BorlandIDEServices as INTAServices).CreateDockableForm(VisDockForm);
AForm.Left := SuggestedLeft;
AForm.Top := SuggestedTop;
(VisDockForm as IFrameFormHelper).SetForm(AForm);
AFrame := (VisDockForm as IFrameFormHelper).GetFrame as TJSONViewerFrame;
AFrame.ShowJSONObject(Expression, TypeName, EvalResult);
Result := AFrame as IOTADebuggerVisualizerExternalViewerUpdater;
end;
{ TStringListViewerFrame }
procedure TJSONViewerFrame.ShowJSONObject(const Expression, TypeName,
EvalResult: string);
begin
Memo1.Lines.Add(Expression);
Memo1.Lines.Add(TypeName);
Memo1.Lines.Add(EvalResult);
end;
正如您所看到的,此时我只是尝试从ShowJSONObject方法中显示这三个参数的值。
这是我尝试使用可视化工具显示的简单TJSONObject:
var
jo: TJSONObject;
begin
jo := TJSONObject.Create;
jo.AddPair('one', 'one');
jo.AddPair('two', TJSONNumber.Create(1)); //a breakpoint here
结果如下:
我希望EvalResult会返回TJSONObject的tostring表示,但它只返回uninformative(),这与你在局部变量窗口中默认看到的一样。
如何获取调用可视化器的TJSONObject的tostring表示或实际对象的句柄,以便我可以解构并显示其值?
答案 0 :(得分:3)
您需要使用此过程评估您的表达式(包括ToString调用)(只是从我自己的可视化工具源复制,因此它可以使用一些未在此处声明的局部变量):
function TJSONViewerFrame.Evaluate(Expression: string): string;
var
CurProcess: IOTAProcess;
CurThread: IOTAThread;
ResultStr: array[0..4095] of Char;
CanModify: Boolean;
ResultAddr, ResultSize, ResultVal: LongWord;
EvalRes: TOTAEvaluateResult;
DebugSvcs: IOTADebuggerServices;
begin
begin
Result := '';
if Supports(BorlandIDEServices, IOTADebuggerServices, DebugSvcs) then
CurProcess := DebugSvcs.CurrentProcess;
if CurProcess <> nil then
begin
CurThread := CurProcess.CurrentThread;
if CurThread <> nil then
begin
EvalRes := CurThread.Evaluate(Expression, @ResultStr, Length(ResultStr),
CanModify, eseAll, '', ResultAddr, ResultSize, ResultVal, '', 0);
case EvalRes of
erOK: Result := ResultStr;
erDeferred:
begin
FCompleted := False;
FDeferredResult := '';
FDeferredError := False;
FNotifierIndex := CurThread.AddNotifier(Self);
while not FCompleted do
DebugSvcs.ProcessDebugEvents;
CurThread.RemoveNotifier(FNotifierIndex);
FNotifierIndex := -1;
if not FDeferredError then
begin
if FDeferredResult <> '' then
Result := FDeferredResult
else
Result := ResultStr;
end;
end;
erBusy:
begin
DebugSvcs.ProcessDebugEvents;
Result := Evaluate(Expression);
end;
end;
end;
end;
end;
end;
现在您可以用以下内容替换Show函数:
AFrame.ShowJSONObject(Expression, TypeName, Evaluate(Expression + '.ToString'));