2011-11-13 1 views
4

J'essaye d'écrire un visualiseur de débogueur pour un TJSONObject ou un TJSONValue. La plupart des visualiseurs fonctionnent bien. Le problème que j'ai est obtenir une référence à l'objet TJSONObject, ou au moins à la valeur tostring() de TJSONObject. Selon les exemples que j'ai vus, ainsi que le bon message de Jeremy North au http://edn.embarcadero.com/article/40268, je devrais obtenir ce dont j'ai besoin de la méthode Show de mon implémentation IOTADebuggerVisualizerExternalViewer. Plus précisément, à partir des paramètres de chaîne Expression, TypeName et EvalResult. D'après ce que je comprends, Expression est le nom de la variable inspectée (visualisée), TypeName est le nom de classe de la variable, et EvalResult est la représentation par défaut de la variable.Comment puis-je obtenir une référence à l'objet ou à ses données à partir de mon visualiseur de débogueur de visionneuse externe?

Pour un test simple, j'ai placé un TMemo sur mon descendant TFrame. À partir de la méthode IOTADebuggerVisualizerExternalViewer.Show j'appelle la méthode ShowJSONObject de mon TFrame, à laquelle je passe Expression, TypeName et EvalResult. Le code correspondant apparaît ici:

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; 

Comme vous pouvez le voir, je en ce moment je ne suis en train d'afficher les valeurs de ces trois paramètres de ma méthode de ShowJSONObject.

est ici simple TJSONObject que j'ai essayé d'afficher à l'aide du Visualiseur:

var 
jo: TJSONObject; 
begin 
    jo := TJSONObject.Create; 
    jo.AddPair('one', 'one'); 
    jo.AddPair('two', TJSONNumber.Create(1)); //a breakpoint here 

Le résultat ressemble à ceci:

A debugger visualizer under development

J'espérais que EvalResult retournerait la représentation tostring de l'objet TJSONObject, mais il n'a retourné que le non-informatif(), ce qui est la même chose que vous voyez par défaut dans la fenêtre des variables locales.

Comment puis-je obtenir la représentation tostring du TJSONObject pour lequel le visualiseur a été appelé ou un handle pour l'objet réel, afin que je puisse déconstruire et afficher sa valeur?

Répondre

3

Vous devez évaluer votre expression (y compris appel ToString) à l'aide de cette procédure (juste copié de ma propre source Visualiseur de sorte qu'il pourrait utiliser certaines variables locales qui ne sont pas déclarés ici):

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; 

Alors maintenant, vous peut remplacer votre fonction Afficher avec quelque chose comme ceci:

AFrame.ShowJSONObject(Expression, TypeName, Evaluate(Expression + '.ToString')); 
Questions connexes