Visualizing and viewing data

Applies to: yesVisual Studio noVisual Studio for Mac

Note

This article applies to Visual Studio 2017. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here

Type visualizers and custom viewers present data in a way that is quickly meaningful to a developer. The expression evaluator (EE) can support third-party type visualizers as well as supply its own custom viewers.

Visual Studio determines how many type visualizers and custom viewers are associated with the object's type by calling the GetCustomViewerCount method. If there is at least one type visualizer or custom viewer available, Visual Studio calls the GetCustomViewerList method to retrieve a list of those visualizers and viewers (actually, a list of s that implements the visualizers and viewers) and presents them to the user.

Supporting type visualizers

There are a number of interfaces that the EE must implement to support type visualizers. These interfaces can be broken down into two broad categories: interfaces that list the type visualizers and interfaces that access the property data.

Listing type visualizers

The EE supports listing the type visualizers in its implementation of IDebugProperty3::GetCustomViewerCount and IDebugProperty3::GetCustomViewerList. These methods pass the call to the corresponding methods GetCustomViewerCount and GetCustomViewerList.

The IEEVisualizerService is obtained by calling CreateVisualizerService. This method requires the IDebugBinder3 interface, which is obtained from the IDebugBinder interface passed to EvaluateSync. IEEVisualizerServiceProvider::CreateVisualizerService also requires the IDebugSymbolProvider and IDebugAddress interfaces, which were passed to IDebugParsedExpression::EvaluateSync. The final interface required to create the IEEVisualizerService interface is the IEEVisualizerDataProvider interface, which the EE implements. This interface allows changes to be made to the property being visualized. All property data is encapsulated in an IDebugObject interface, which is also implemented by the EE.

Accessing property data

Accessing property data is done through the IPropertyProxyEESide interface. To obtain this interface, Visual Studio calls QueryInterface on the property object to get the IPropertyProxyProvider interface (implemented on the same object that implements the IDebugProperty3 interface) and then calls the GetPropertyProxy method to obtain the IPropertyProxyEESide interface.

All data passed into and out of the IPropertyProxyEESide interface is encapsulated in the IEEDataStorage interface. This interface represents an array of bytes and is implemented by both Visual Studio and the EE. When a property's data is to be changed, Visual Studio creates an IEEDataStorage object holding the new data and calls CreateReplacementObject with that data object in order to obtain a new IEEDataStorage object that, in turn, is passed to InPlaceUpdateObject to update the property's data. IPropertyProxyEESide::CreateReplacementObject allows the EE to instantiate its own class that implements the IEEDataStorage interface.

Supporting custom viewers

The flag DBG_ATTRIB_VALUE_CUSTOM_VIEWER is set in the dwAttrib field of the DEBUG_PROPERTY_INFO structure (returned by a call to GetPropertyInfo) to indicate that the object has a custom viewer associated with it. When this flag is set, Visual Studio obtains the IDebugProperty3 interface from the IDebugProperty2 interface using QueryInterface.

If the user selects a custom viewer, Visual Studio instantiates the custom viewer using the viewer's CLSID supplied by the IDebugProperty3::GetCustomViewerList method. Visual Studio then calls DisplayValue to show the value to the user.

Normally, IDebugCustomViewer::DisplayValue presents a read-only view of the data. To allow changes to the data, the EE must implement a custom interface that supports changing data on a property object. The IDebugCustomViewer::DisplayValue method uses this custom interface to support changing the data. The method looks for the custom interface on the IDebugProperty2 interface passed in as the pDebugProperty argument.

Supporting both type visualizers and custom viewers

An EE can support both type visualizers and custom viewers in the GetCustomViewerCount and GetCustomViewerList methods. First, the EE adds the number of custom viewers that it is supplying to the value returned by the GetCustomViewerCount method. Second, the EE appends the CLSIDs of its own custom viewers to the list returned by the GetCustomViewerList method.

See also