Skip to content

Commit f786c2f

Browse files
authored
Merge pull request #273 from Microsoft/brpeek-tfs384493
Fix escaped characters and missing code snippets
2 parents 09660ae + 6a43531 commit f786c2f

File tree

1 file changed

+53
-66
lines changed

1 file changed

+53
-66
lines changed

docs/debugger/create-custom-views-of-native-objects.md

Lines changed: 53 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ ms.tgt_pltfrm: ""
1010
ms.topic: "article"
1111
f1_keywords:
1212
- "natvis"
13-
dev_langs:
14-
- "FSharp"
15-
- "VB"
16-
- "CSharp"
17-
- "C++"
13+
#dev_langs:
14+
# - "FSharp"
15+
# - "VB"
16+
# - "CSharp"
17+
# - "C++"
1818
ms.assetid: 2d9a177a-e14b-404f-a6af-49498eff0bd7
1919
caps.latest.revision: 19
2020
author: "mikejo5000"
@@ -66,8 +66,7 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
6666

6767
The basic structure of a .natvis file is one or more `Type` elements, where each `Type` element represents a visualization entry for a type whose fully qualified name is specified in the `Name` attribute.
6868

69-
```xml
70-
69+
```xml
7170
<?xml version="1.0" encoding="utf-8"?>
7271
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
7372
<Type Name="MyNamespace::CFoo">
@@ -125,10 +124,10 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
125124
To control how an expression is displayed in a variable window, you can use any of the format specifiers that are described in the [Format Specifiers](../debugger/format-specifiers-in-cpp.md#BKMK_Visual_Studio_2012_format_specifiers) section of the [Format Specifiers in C++](../debugger/format-specifiers-in-cpp.md) topic. Note that format specifiers are ignored when the virtualization entry is used internally by Natvis, such as the `Size` expression in in a [ArrayItems expansion](../debugger/create-custom-views-of-native-objects.md#BKMK_ArrayItems_expansion).
126125

127126
## Natvis views
128-
Natvis views allow you to see any type in more than one way. For example, you can define a view named **simple** that gives you a simplified view of a type. For example, here is the visualization of `std::vector`:
127+
Natvis views allow you to see any type in more than one way. For example, you can define a view named **simple** that gives you a simplified view of a type. For example, here is the visualization of `std::vector`:
129128

130-
```xml
131-
<Type Name="std::vector<*>">
129+
```xml
130+
<Type Name="std::vector&lt;*&gt;">
132131
<DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
133132
<Expand>
134133
<Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item>
@@ -153,7 +152,7 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
153152
### <a name="BKMK_AutoVisualizer"></a> AutoVisualizer element
154153
The `AutoVisualizer` element is the root node of the .natvis file and contains the namespace `xmlns:` attribute.
155154

156-
```xml
155+
```xml
157156
<?xml version="1.0" encoding="utf-8"?>
158157
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
159158
.
@@ -164,14 +163,13 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
164163
### <a name="BKMK_Type"></a> Type element
165164
A basic Type looks like this:
166165

167-
```xml
166+
```xml
168167
<Type Name="[fully qualified type name]">
169168
<DisplayString Condition="[Boolean expression]">[Display value]</DisplayString>
170169
<Expand>
171170
...
172171
</Expand>
173172
</Type>
174-
175173
```
176174

177175
It specifies:
@@ -184,8 +182,8 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
184182

185183
**Templated classes** The `Name` attribute of the `Type` element accepts an asterisk `*` as a wildcard character that can be used for templated class names:
186184

187-
```xml
188-
<Type Name="ATL::CAtlArray<*>">
185+
```xml
186+
<Type Name="ATL::CAtlArray&lt;*&gt;">
189187
<DisplayString>{{Count = {m_nSize}}}</DisplayString>
190188
</Type>
191189

@@ -201,8 +199,8 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
201199
#### Inheritable attribute
202200
You can specify whether a visualization applies only to a base type or to a base type and all derived types with the optional `Inheritable` attribute. In the following, the visualization applies only to the `BaseClass` type:
203201

204-
```xml
205-
<Type Name="Namespace::BaseClass" Inheritable=true>
202+
```xml
203+
<Type Name="Namespace::BaseClass" Inheritable="true">
206204
<DisplayString>{{Count = {m_nSize}}}</DisplayString>
207205
</Type>
208206
```
@@ -216,17 +214,17 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
216214

217215
In the following example, we will first parse the entry that matches the 2015 STL, and if that fails to parse, we will use the alternate entry for the 2013 version of the STL:
218216

219-
```xml
217+
```xml
220218
<!-- VC 2013 -->
221-
<Type Name="std::reference_wrapper<*>" Priority="MediumLow">
219+
<Type Name="std::reference_wrapper&lt;*&gt;" Priority="MediumLow">
222220
<DisplayString>{_Callee}</DisplayString>
223221
<Expand>
224222
<ExpandedItem>_Callee</ExpandedItem>
225223
</Expand>
226224
</Type>
227225

228226
<!-- VC 2015 -->
229-
<Type Name="std::reference_wrapper<*>">
227+
<Type Name="std::reference_wrapper&lt;*&gt;">
230228
<DisplayString>{*_Ptr}</DisplayString>
231229
<Expand>
232230
<Item Name="[ptr]">_Ptr</Item>
@@ -237,7 +235,7 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
237235
#### <a name="BKMK_Versioning"></a> Version element
238236
Use the `Version` element to scope visualizations to specific modules and their versions so that name collisions can be minimized and different visualizations can be used for different versions of the types. For example:
239237

240-
```xml
238+
```xml
241239
<Type Name="DirectUI::Border">
242240
<Version Name="Windows.UI.Xaml.dll" Min="1.0" Max="1.5"/>
243241
<DisplayString>{{Name = {*(m_pDO->m_pstrName)}}}</DisplayString>
@@ -252,7 +250,7 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
252250
#### Optional attribute
253251
The `Optional` attribute can appear on any node. If any sub-expression inside an optional node fails to parse, that node is ignored, but the rest of the Type element is still valid. In the following type, `[State]` is non-optional, but `[Exception]` is optional. This means that if `MyNamespace::MyClass` contains a field named _`M_exceptionHolder`, you will still both `[State]` node and the `[Exception]` node, but if the `_M_exceptionHolder` is missing, you will see only the `[State]` node.
254252

255-
```xml
253+
```xml
256254
<Type Name="MyNamespace::MyClass">
257255
<Expand>
258256
<Item Name="[State]">_M_State</Item>
@@ -264,8 +262,8 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
264262
### <a name="BKMK_Condition_attribute"></a> Condition attribute
265263
The optional `Condition` attribute is available for many visualization elements and specifies when a visualization rule should be used. If the expression inside the condition attribute resolves to `false`, then the visualization rule specified by the element is not applied. If it evaluates to true, or if there is no `Condition` attribute, then the visualization rule is applied to the type. You can use this attribute for `if-else` logic in the visualization entries. For example, the visualization below has two `DisplayString` elements for a smart pointer type:
266264

267-
```xml
268-
<Type Name="std::auto_ptr<*>">
265+
```xml
266+
<Type Name="std::auto_ptr&lt;*&gt;">
269267
<DisplayString Condition="_Myptr == 0">empty</DisplayString>
270268
<DisplayString>auto_ptr {*_Myptr}</DisplayString>
271269
<Expand>
@@ -280,8 +278,8 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
280278
### IncludeView and ExcludeView attributes
281279
These attributes specify elements that are to be displayed or not displayed in different views. For example, given the Natvis specification of `std::vector`:
282280

283-
```xml
284-
<Type Name="std::vector<*>">
281+
```xml
282+
<Type Name="std::vector&lt;*&gt;">
285283
<DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
286284
<Expand>
287285
<Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item>
@@ -301,7 +299,7 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
301299
### <a name="BKMK_DisplayString"></a> DisplayString
302300
A `DisplayString` element specifies the string to be shown as the value of the variable. It accepts arbitrary strings mixed with expressions. Everything inside curly braces is interpreted as an expression. For instance, a `DisplayString` entry like this:
303301

304-
```xml
302+
```xml
305303
<Type Name="CPoint">
306304
<DisplayString>{{x={x} y={y}}}</DisplayString>
307305
</Type>
@@ -320,11 +318,10 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
320318
### <a name="BKMK_StringView"></a> StringView
321319
The `StringView` element defines the expression whose value is going to be sent to the built-in text visualizer. For example, suppose we have the following visualization for the `ATL::CStringT` type:
322320

323-
```xml
324-
<Type Name="ATL::CStringT<wchar_t,*>">
321+
```xml
322+
<Type Name="ATL::CStringT&lt;wchar_t,*&gt;">
325323
<DisplayString>{m_pszData,su}</DisplayString>
326-
</Type>
327-
324+
</Type>
328325
```
329326

330327
The `CStringT` object looks like:
@@ -335,12 +332,11 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
335332

336333
Adding a `StringView` element will indicate to the debugger that this value can be viewed by a text visualization:
337334

338-
```
339-
<Type Name="ATL::CStringT<wchar_t,*>">
335+
```xml
336+
<Type Name="ATL::CStringT&lt;wchar_t,*&gt;">
340337
<DisplayString>{m_pszData,su}</DisplayString>
341338
<StringView>m_pszData,su</StringView>
342339
</Type>
343-
344340
```
345341

346342
Notice the magnifying glass icon shown next to the value below. Choosing the icon will launch the text visualizer which will display the string that `m_pszData` points to.
@@ -362,7 +358,7 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
362358
#### <a name="BKMK_Item_expansion"></a> Item expansion
363359
The `Item` element is the most basic and the most common element to be used in an `Expand` node. `Item` defines a single child element. For example, suppose that you have a `CRect` class with `top`, `left`, `right`, and `bottom` as its fields and the following visualization entry:
364360

365-
```xml
361+
```xml
366362
<Type Name="CRect">
367363
<DisplayString>{{top={top} bottom={bottom} left={left} right={right}}}</DisplayString>
368364
<Expand>
@@ -385,8 +381,8 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
385381
#### <a name="BKMK_ArrayItems_expansion"></a> ArrayItems expansion
386382
Use the `ArrayItems` node to have the Visual Studio debugger interpret the type as an array and display its individual elements. The visualization for `std::vector` is a good example:
387383

388-
```xml
389-
<Type Name="std::vector<*>">
384+
```xml
385+
<Type Name="std::vector&lt;*&gt;">
390386
<DisplayString>{{size = {_Mylast - _Myfirst}}}</DisplayString>
391387
<Expand>
392388
<Item Name="[size]">_Mylast - _Myfirst</Item>
@@ -397,7 +393,6 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
397393
</ArrayItems>
398394
</Expand>
399395
</Type>
400-
401396
```
402397

403398
A `std::vector` shows its individual elements when expanded in the variable window:
@@ -416,8 +411,8 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
416411

417412
Multi-dimensional arrays can also be specified. The debugger needs just a little bit more information to properly display child elements in that case:
418413

419-
```xml
420-
<Type Name="Concurrency::array<*,*>">
414+
```xml
415+
<Type Name="Concurrency::array&lt;*,*&gt;">
421416
<DisplayString>extent = {_M_extent}</DisplayString>
422417
<Expand>
423418
<Item Name="extent">_M_extent</Item>
@@ -429,7 +424,6 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
429424
</ArrayItems>
430425
</Expand>
431426
</Type>
432-
433427
```
434428

435429
`Direction` specifies whether the array is row-major or column-major order. `Rank` specifies the rank of the array. The `Size` element accepts the implicit `$i` parameter which it substitutes with the dimension index to find the length of the array in that dimension. For example, in the previous example, above the expression `_M_extent.M_base[0]` should give the length of the 0th dimension, `_M_extent._M_base[1]` the 1st and so on.
@@ -441,8 +435,8 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
441435
#### <a name="BKMK_IndexListItems_expansion"></a> IndexListItems expansion
442436
You can use the `ArrayItems` expansion, only if the array elements are laid out contiguously in memory. The debugger gets to the next element by simply incrementing its pointer to the current element. To support cases where you need to manipulate the index to the value node, `IndexListItems` nodes can be used. Here’s a visualization using `IndexListItems` node:
443437

444-
```xml
445-
<Type Name="Concurrency::multi_link_registry<*>">
438+
```xml
439+
<Type Name="Concurrency::multi_link_registry&lt;*&gt;">
446440
<DisplayString>{{size = {_M_vector._M_index}}}</DisplayString>
447441
<Expand>
448442
<Item Name="[size]">_M_vector._M_index</Item>
@@ -452,7 +446,6 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
452446
</IndexListItems>
453447
</Expand>
454448
</Type>
455-
456449
```
457450

458451
You can now use the `[]` operator with an `IndexListItems` expansion, for example `vector[i]`. The `[]` operator can be used with any visualization of a single-dimensional array that uses `ArrayItems` or `IndexListItems`, even if the type itself does not allow this operator (for example `CATLArray`).
@@ -462,8 +455,8 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
462455
#### <a name="BKMK_LinkedListItems_expansion"></a> LinkedListItems expansion
463456
If the visualized type represents a linked list, the debugger can display its children by using a `LinkedListItems` node. Here’s the visualization for the `CAtlList` type using this feature:
464457

465-
```xml
466-
<Type Name="ATL::CAtlList<*,*>">
458+
```xml
459+
<Type Name="ATL::CAtlList&lt;*,*&gt;">
467460
<DisplayString>{{Count = {m_nElements}}}</DisplayString>
468461
<Expand>
469462
<Item Name="Count">m_nElements</Item>
@@ -475,7 +468,6 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
475468
</LinkedListItems>
476469
</Expand>
477470
</Type>
478-
479471
```
480472

481473
The `Size` element refers to the length of the list. `HeadPointer` points to the first element, `NextPointer` refers to the next element, and `ValueNode` refers to the value of the item.
@@ -489,10 +481,10 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
489481

490482
The visualizer for CAtlMap is an excellent example of where `CustomListItems` is appropriate.
491483

492-
```xml
493-
<Type Name="ATL::CAtlMap<*,*,*,*>">
494-
<AlternativeType Name="ATL::CMapToInterface<*,*,*>"/>
495-
<AlternativeType Name="ATL::CMapToAutoPtr<*,*,*>"/>
484+
```xml
485+
<Type Name="ATL::CAtlMap&lt;*,*,*,*&gt;">
486+
<AlternativeType Name="ATL::CMapToInterface&lt;*,*,*&gt;"/>
487+
<AlternativeType Name="ATL::CMapToAutoPtr&lt;*,*,*&gt;"/>
496488
<DisplayString>{{Count = {m_nElements}}}</DisplayString>
497489
<Expand>
498490
<CustomListItems MaxItemsPerView="5000" ExcludeView="Test">
@@ -521,8 +513,8 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
521513
#### <a name="BKMK_TreeItems_expansion"></a> TreeItems expansion
522514
If the visualized type represents a tree, the debugger can walk the tree and display its children by using a `TreeItems` node. Here’s the visualization for the `std::map` type using this feature:
523515

524-
```xml
525-
<Type Name="std::map<*>">
516+
```xml
517+
<Type Name="std::map&lt;*&gt;">
526518
<DisplayString>{{size = {_Mysize}}}</DisplayString>
527519
<Expand>
528520
<Item Name="[size]">_Mysize</Item>
@@ -536,7 +528,6 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
536528
</TreeItems>
537529
</Expand>
538530
</Type>
539-
540531
```
541532

542533
The syntax is very similar to the `LinkedListItems` node. `LeftPointer`, `RightPointer`, and `ValueNode` are evaluated under the context of the tree node class, and `ValueNode` can be left empty or have `this` to refer to the tree node itself.
@@ -548,36 +539,34 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
548539

549540
To see the values of the vector, you have to drill down two levels in the variable window passing through _Myptr member. By adding an `ExpandedItem` element, you can eliminate the `_Myptr` variable from the hierarchy and directly view the vector elements::
550541

551-
```xml
552-
<Type Name="std::auto_ptr<*>">
542+
```xml
543+
<Type Name="std::auto_ptr&lt;*&gt;">
553544
<DisplayString>auto_ptr {*_Myptr}</DisplayString>
554545
<Expand>
555546
<ExpandedItem>_Myptr</ExpandedItem>
556547
</Expand>
557548
</Type>
558-
559549
```
560550

561551
![auto&#95;ptr&#60;vector&#60;int&#62;&#62; ExpandedItem expansion](../debugger/media/dbg_natvis_expand_expandeditem_visualized.png "DBG_NATVIS_Expand_ExpandedItem_Visualized")
562552

563553
The example below shows how to aggregate properties from the base class in a derived class. Suppose the `CPanel` class derives from `CFrameworkElement`. Instead of repeating the properties that come from the base `CFrameworkElement` class, the `ExpandedItem` node allows those properties to be appended to the child list of the `CPanel` class. The **nd** format specifier which turns off visualization matching for the derived class is necessary here. Otherwise, the expression `*(CFrameworkElement*)this` will cause the `CPanel` visualization to be applied again because the default visualization type matching rules consider it the most appropriate one. Using the **nd** format specifier instructs the debugger to use the base class visualization or the base class default expansion if the base class doesn’t have a visualization.
564554

565-
```xml
555+
```xml
566556
<Type Name="CPanel">
567557
<DisplayString>{{Name = {*(m_pstrName)}}}</DisplayString>
568558
<Expand>
569559
<Item Name="IsItemsHost">(bool)m_bItemsHost</Item>
570560
<ExpandedItem>*(CFrameworkElement*)this,nd</ExpandedItem>
571561
</Expand>
572562
</Type>
573-
574563
```
575564

576565
#### <a name="BKMK_Synthetic_Item_expansion"></a> Synthetic Item expansion
577566
Where the `ExpandedItem` element provides a flatter view of data by eliminating hierarchies, the `Synthetic` node does the opposite. It allows you to create an artificial child element (that is, a child element that is not a result of an expression). This child element can contain children elements of its own. In the following example, the visualization for the `Concurrency::array` type uses a `Synthetic` node to show a diagnostic message to the user:
578567

579-
```xml
580-
<Type Name="Concurrency::array<*,*>">
568+
```xml
569+
<Type Name="Concurrency::array&lt;*,*&gt;">
581570
<DisplayString>extent = {_M_extent}</DisplayString>
582571
<Expand>
583572
<Item Name="extent" Condition="_M_buffer_descriptor._M_data_ptr == 0">_M_extent</Item>
@@ -612,8 +601,7 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
612601

613602
Here's an example of a UIVisualizer element:
614603

615-
```xml
616-
604+
```xml
617605
<?xml version="1.0" encoding="utf-8"?>
618606
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
619607
<UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}"
@@ -633,9 +621,8 @@ The Visual Studio Natvis framework lets you customize the way Visual Studio disp
633621

634622
Each type defined in the .natvis file must explicitly list the UI visualizers that can display them. The debugger matches the visualizer references in the type entries to match types with the registered visualizers. For example, the following type entry for `std::vector` references the UIVisualizer in our example above.
635623

636-
```
637-
638-
<Type Name="std::vector<int,*>">
624+
```xml
625+
<Type Name="std::vector&lt;int,*&gt;">
639626
<UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />
640627
</Type>
641628
```

0 commit comments

Comments
 (0)