<Jon Payne> wrote in message news:✉forums.embarcadero.com...
> Thanks. I was really after a C++ example
Here is a C++ translation of the std::string visualizer from RAD Studio 2010
(untested):
{code:cpp}
#include <vcl.h>
#pragma hdrstop
#include <Classes.hpp>
#include <Forms.hpp>
#include <SysUtils.hpp>
#include <ToolsAPI.hpp>
#pragma package(smart_init)
const sStdStringVisualizerName = "std::string and std::wstring Visualizer for C++";
const sStdStringVisualizerDescription = "Displays the actual string value for std::string and std::wstring instances";
class TStdStringTimeVisualizer :
public TInterfacedObject,
public IOTADebuggerVisualizer,
public IOTADebuggerVisualizerValueReplacer,
public IOTAThreadNotifier
{
private:
int FNotifierIndex;
bool FCompleted;
String FDeferredResult;
public:
// IOTADebuggerVisualizer
int __fastcall GetSupportedTypeCount();
void __fastcall GetSupportedType(int Index, String &TypeName, bool &AllDescendants);
String __fastcall GetVisualizerIdentifier();
String __fastcall GetVisualizerName();
String __fastcall GetVisualizerDescription();
// IOTADebuggerVisualizerValueReplacer
String __fastcall GetReplacementValue(const String Expression, const String TypeName, const String EvalResult);
// IOTAThreadNotifier
void __fastcall EvaluteComplete(const String ExprStr, const String ResultStr, bool CanModify, Cardinal ResultAddress, Cardinal ResultSize, int ReturnCode);
void __fastcall ModifyComplete(const String ExprStr, const String ResultStr, int ReturnCode);
void __fastcall ThreadNotify(TOTANotifyReason Reason);
void __fastcall AfterSave();
void __fastcall BeforeSave();
void __fastcall Destroyed();
void ___fastcall Modified();
};
const String StdStringVisualizerTypes[2] =
{
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >",
"std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >"
};
// TStdStringTimeVisualizer
void __fastcall TStdStringTimeVisualizer::AfterSave()
{
// don't care about this notification
}
void __fastcall TStdStringTimeVisualizer::BeforeSave()
{
// don't care about this notification
}
void __fastcall TStdStringTimeVisualizer::Destroyed()
{
// don't care about this notification
}
void __fastcall TStdStringTimeVisualizer::Modified()
{
// don't care about this notification
}
void __fastcall TStdStringTimeVisualizer::ModifyComplete(const String ExprStr, const String ResultStr, int ReturnCode)
{
// don't care about this notification
}
void __fastcall TStdStringTimeVisualizer::EvaluteComplete(const String ExprStr, const String ResultStr, bool CanModify, Cardinal ResultAddress, Cardinal ResultSize, int ReturnCode)
{
FCompleted = true;
if( ReturnCode == 0 )
FDeferredResult = ResultStr;
}
void __fastcall TStdStringTimeVisualizer::ThreadNotify(TOTANotifyReason Reason)
{
// don't care about this notification
}
String __fastcall TStdStringTimeVisualizer::GetReplacementValue(const String Expression, const String TypeName, const String EvalResult)
{
_di_IOTAProcess CurProcess;
_di_IOTAThread CurThread;
Char ResultStr[4096];
bool CanModify;
LongWord ResultAddr, ResultSize, ResultVal;
TOTAEvaluateResult EvalRes;
_di_IOTADebuggerServices DebugSvcs;
String Result = EvalResult;
if( Supports(BorlandIDEServices, IID_IOTADebuggerServices, (void*)&DebugSvcs) )
CurProcess = DebugSvcs->CurrentProcess;
if( CurProcess )
{
CurThread = CurProcess->CurrentThread;
if( CurThread )
{
EvalRes = CurThread->Evaluate(Expression + "._Myptr()", ResultStr, 4096, CanModify, eseAll, "", ResultAddr, ResultSize, ResultVal, "", 0);
switch( EvalRes )
{
case erOK:
{
Result = ResultStr;
break;
}
case erDeferred:
{
FCompleted = false;
FDeferredResult = "";
FNotifierIndex = CurThread->AddNotifier(this);
while( !FCompleted )
DebugSvcs->ProcessDebugEvents();
CurThread->RemoveNotifier(FNotifierIndex);
FNotifierIndex = -1;
if( FDeferredResult != "" )
Result = FDeferredResult;
else
Result = EvalResult;
break;
}
case erBusy:
{
DebugSvcs->ProcessDebugEvents();
Result = GetReplacementValue(Expression, TypeName, EvalResult);
break;
}
}
}
}
return Result;
}
int __fastcall TStdStringTimeVisualizer::GetSupportedTypeCount()
{
Result = 2;
}
void __fastcall TStdStringTimeVisualizer::GetSupportedType(int Index, String &TypeName, bool &AllDescendants)
{
AllDescendants = false;
TypeName = StdStringVisualizerTypes[Index];
}
String __fastcall TStdStringTimeVisualizer::GetVisualizerDescription()
{
return sStdStringVisualizerDescription;
}
String __fastcall TStdStringTimeVisualizer::GetVisualizerIdentifier()
{
return ClassName();
}
String __fastcall TStdStringTimeVisualizer::GetVisualizerName()
{
return sStdStringVisualizerName;
}
_di_IOTADebuggerVisualizer StdStringVis;
namespace Stdstringvisualizer
{
void __fastcall PACKAGE Register()
{
StdStringVis = (IOTADebuggerVisualizer *) new TStdStringTimeVisualizer();
_di_IOTADebuggerServices DebuggerServices;
if( Supports(BorlandIDEServices, IID_IOTADebuggerServices, (void*)&DebuggerServices) )
DebuggerServices->RegisterDebugVisualizer(StdStringVis);
}
}
void RemoveVisualizer()
{
_di_IOTADebuggerServices DebuggerServices;
if( Supports(BorlandIDEServices, IID_IOTADebuggerServices, (void*)&DebuggerServices) )
DebuggerServices->UnregisterDebugVisualizer(StdStringVis);
StdStringVis = NULL;
}
#pragma exit RemoveVisualizer
{code}
--
Remy Lebeau (TeamB)