Building a Value Replacer for UCSChar

Before we delve into the development of a debugger visualizer, let me point you to a specific situation in which the debugger provides limited information about the values of a type. Consider the following code snippet, which is part of the DebugVisual example which is also used to demonstrate the other debugger visualizers.

procedure TForm39.btnUcs4CharClick(Sender: TObject); var ch: UCS4Char; begin ch := Ord ( 'u');

ShowMessage (Character.ConvertFromUtf32 (ch)); end ;

If you put a breakpoint in the code above and look to the value of ch, you'll see its numerical value, not the character is represents, as shown on the right. It fâ ^ variables

15 Refer to the source code of the TStringsVisualizer for an example of the other type (which is certainly more interesting, but also quite complex).

would be nice to see the accented letter, something we can now do thanks to this new feature.

IB Self Sender di

Name

Value

2-49

IB Self Sender di

Name

Value

2-49

To install a custom visualizer we have to create a design time package that requires the designide.dcp package and add a unit with a class implementing two debugger visualizer interfaces (the base one and the specific one) plus the IOTAThreadNotifier interface.

The class must provide all of the methods (here grouped by interface), even if most of them will have an empty implementation: type

TDebuggerUcs4CharVisualizer = class (

TinterfacedObject, IOTADebuggerVisualizer, IOTADebuggerVisualizerValueReplacer, IOTAThreadNotifier) public

{ IOTADebuggerVisualizer }

function GetSupportedTypeCount: Integer;

procedure GetSupportedType(Index: Integer;

var TypeName: string; var AllDescendants: Boolean); function GetVisualizerIdentifier: string; function GetVisualizerName: string; function GetVisualizerDescription: string;

  • IOTADebuggerVisualizerValueReplacer } function GetReplacementValue(const Expression, TypeName, EvalResult: string): string;
  • IOTAThreadNotifier }

procedure EvaluteComplete(const ExprStr: string; const ResultStr: string; CanModify: Boolean; ResultAddress: Cardinal; ResultSize: Cardinal; ReturnCode: Integer); procedure ModifyComplete(const ExprStr: string;

const ResultStr: string; ReturnCode: Integer); procedure ThreadNotify(Reason: TOTANotifyReason); procedure AfterSave; procedure BeforeSave; procedure Destroyed; procedure Modified; end ;

The methods implementing the IOTADebuggerVisual izer interface provide information about the debugger visualizer, including the name and description that will be displayed in the Debugger Options | Visualizers page of the Options dialog box, covered earlier:

function TDebuggerUcs4CharVisualizer.

GetVisualizerIdentifier: string; begin

function TDebuggerUcs4CharVisualizer.ù

GetVisualizerName: string; begin

Result := 'Ucs4Char Visualizer for Delphi '; end;

function TDebuggerUcs4CharVisualizer.

GetVisualizerDescription: string; begin

Result := 'Displays the Unicode string for a Ucs4Char'; end;

The last two methods return the number of types the visualizer can be used for, and each of their names (in this case, there is only one type, making the code much simpler):

function TDebuggerUcs4CharVisualizer.

GetSupportedTypeCount: Integer; begin

procedure TDebuggerUcs4CharVisualizer.GetSupportedType( Index: Integer; var TypeName: string; var AllDescendants: Boolean); begin

AllDescendants := False; TypeName := 'UCS4Char'; end;

The other relevant method is GetReplacementVal ue of the specific interface for this type of visualizer, IOTADebuggerVisual izerValueReplacer:

function TDebuggerUcs4CharVisualizer.GetReplacementValue( const Expression, TypeName, EvalResult: string): string; var ch: UCS4Char; begin ch := StrToIntDef (EvalResult, 0); Result := Character.ConvertFromUtf32 (ch); end;

In this specific example, all of the IOTAThreadNotifier methods have an empty body (but if you don't refer to that interface, the IDE will raise a low-level exception, so it is compulsory to have those empty methods).

Now that we have a class implementing our debugger visualizer for the UCS4Char type, we can install it after creating a global object, and clean up when the package is unloaded: var

Ucs4CharVis: IOTADebuggerVisualizer;

0 0

Post a comment

  • Receive news updates via email from this site