Erstellen benutzerdefinierter Ansichten von C++-Objekten im Debugger mit dem Natvis-FrameworkCreate custom views of C++ objects in the debugger using the Natvis framework

Das Visual Studio Natvis-Framework passt die Art und Weise an, wie native Typen in Variablenfenstern des Debuggers, z. B. in den Fenstern Lokal und Überwachen sowie in DataTips, angezeigt werden.The Visual Studio Natvis framework customizes the way native types appear in debugger variable windows, such as the Locals and Watch windows, and in DataTips. Natvis-Visualisierungen können dazu beitragen, die von Ihnen erstellten Typen während des Debuggens besser sichtbar zu gestalten.Natvis visualizations can help make the types you create more visible during debugging.

Natvis ersetzt die Datei autoexp.dat, die in früheren Versionen von Visual Studio verwendet wurde, durch XML-Syntax, bessere Diagnosefunktionen, eine bessere Versionskontrolle und Unterstützung mehrerer Dateien.Natvis replaces the autoexp.dat file in earlier versions of Visual Studio with XML syntax, better diagnostics, versioning, and multiple file support.

Hinweis

Natvis-Anpassungen arbeiten mit Klassen und Strukturen, jedoch nicht mit Typedefs.Natvis customizations work with classes and structs, but not typedefs.

Natvis-VisualisierungenNatvis visualizations

Sie verwenden das Natvis-Framework zum Erstellen von Visualisierungsregeln für Typen, die Sie erstellen, damit sie von Entwicklern beim Debuggen einfacher angezeigt werden können.You use the Natvis framework to create visualization rules for the types you create, so that developers can see them more easily during debugging.

Die folgende Abbildung zeigt z. B. eine Variable vom Typ Windows::UI::Xaml::Controls::TextBox in einem Debuggerfenster ohne angewandte benutzerdefinierte Visualisierungen.For example, the following illustration shows a variable of type Windows::UI::Xaml::Controls::TextBox in a debugger window without any custom visualizations applied.

TextBox-StandardvisualisierungTextBox default visualization

Die hervorgehobene Zeile zeigt die Text -Eigenschaft der TextBox -Klasse.The highlighted row shows the Text property of the TextBox class. Die komplexe Klassenhierarchie gestaltet es schwierig, diese Eigenschaft zu finden.The complex class hierarchy makes it difficult to find this property. Der Debugger weiß nicht, wie der benutzerdefinierte Zeichenfolgentyp zu interpretieren ist, sodass Sie die im Textfeld enthaltene Zeichenfolge nicht sehen können.The debugger doesn't know how to interpret the custom string type, so you can't see the string held inside the textbox.

Das gleiche TextBox-Objekt sieht im Variablenfenster viel einfacher aus, wenn die benutzerdefinierten Natvis-Visualisierungsregeln angewendet werden.The same TextBox looks much simpler in the variable window when Natvis custom visualizer rules are applied. Die wichtigen Member der Klasse werden gemeinsam angezeigt, und der Debugger zeigt den zugrunde liegenden Zeichenfolgenwert des benutzerdefinierten Zeichenfolgentyps an.The important members of the class appear together, and the debugger shows the underlying string value of the custom string type.

TextBox-Daten mit SchnellansichtTextBox data using visualizer

Verwenden von NATVIS-Dateien in C++-ProjektenUse .natvis files in C++ projects

Natvis verwendet NATVIS-Dateien zur Angabe von Visualisierungsregeln.Natvis uses .natvis files to specify visualization rules. Eine NATVIS-Datei ist einfach eine XML-Datei mit der NATVIS-Erweiterung.A .natvis file is an XML file with a .natvis extension. Das Natvis-Schema wird in %VSINSTALLDIR%\Xml\Schemas\natvis.xsd definiert.The Natvis schema is defined in %VSINSTALLDIR%\Xml\Schemas\natvis.xsd.

Die grundlegende Struktur einer NATVIS-Datei besteht aus einem oder mehreren Type-Elementen, die Visualisierungseinträge darstellen.The basic structure of a .natvis file is one or more Type elements representing visualization entries. Der vollqualifizierte Name der einzelnen Type-Elemente wird in Ihrem Name-Attribut angegeben.The fully qualified name of each Type element is specified in its Name attribute.

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
  <Type Name="MyNamespace::CFoo">
    .
    .
  </Type>

  <Type Name="...">
    .
    .
  </Type>
</AutoVisualizer>

Visual Studio stellt im Ordner %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers einige NATVIS-Dateien bereit.Visual Studio provides some .natvis files in the %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers folder. Diese Dateien enthalten Visualisierungsregeln für viele allgemeine Typen und können als Beispiele für das Schreiben von Visualisierungen für neue Typen dienen.These files have visualization rules for many common types, and can serve as examples for writing visualizations for new types.

Hinzufügen einer NATVIS-Datei zu einem C++-ProjektAdd a .natvis file to a C++ project

Sie können NATVIS-Dateien zu jedem C++-Projekt hinzufügen.You can add a .natvis file to any C++ project.

So fügen Sie eine neue NATVIS-Datei hinzuTo add a new .natvis file:

  1. Wählen Sie den C++-Projektknoten im Projektmappen-Explorer und dann Projekt > Neues Element hinzufügen aus, oder klicken Sie mit der rechten Maustaste auf das Projekt, und wählen Sie Hinzufügen > Neues Element aus.Select the C++ project node in Solution Explorer, and select Project > Add new item, or right-click the project and select Add > New item.

  2. Wählen Sie im Dialogfeld Neues Element hinzufügen die Option Visual C++ > Dienstprogramm > Debugger-Visualisierungsdatei (.natvis) aus.In the Add New Item dialog, select Visual C++ > Utility > Debugger visualization file (.natvis).

  3. Benennen Sie die Datei, und wählen Sie Hinzufügen aus.Name the file, and select Add.

    Die neue Datei wird im Projektmappen-Explorer hinzugefügt und im Dokumentbereich von Visual Studio geöffnet.The new file is added to Solution Explorer, and opens in the Visual Studio document pane.

Der Visual Studio-Debugger lädt NATVIS-Dateien in C++-Projekte automatisch und schließt sie standardmäßig auch in die PDB-Datei ein, wenn das Projekt erstellt wird.The Visual Studio debugger loads .natvis files in C++ projects automatically, and by default, also includes them in the .pdb file when the project builds. Wenn Sie die erstellte App debuggen, lädt der Debugger die NATVIS-Datei aus der PDB-Datei, auch wenn Sie das Projekt nicht geöffnet haben.If you debug the built app, the debugger loads the .natvis file from the .pdb file, even if you don't have the project open. Wenn Sie nicht möchten, dass die NATVIS-Datei in der PDB enthalten ist, können Sie sie aus der erstellten PDB-Datei ausschließen.If you don't want the .natvis file included in the .pdb, you can exclude it from the built .pdb file.

So schließen Sie eine NATVIS-Datei aus einer PDB-Datei ausTo exclude a .natvis file from a .pdb:

  1. Wählen Sie die NATVIS-Datei im Projektmappen-Explorer und dann das Symbol Eigenschaften aus, oder klicken Sie mit der rechten Maustaste auf die Datei, und wählen Sie anschließend Eigenschaften aus.Select the .natvis file in Solution Explorer, and select the Properties icon, or right-click the file and select Properties.

  2. Verwenden Sie den Dropdownpfeil neben Vom Build ausgeschlossen, und wählen Sie dann Ja und anschließend OK aus.Drop down the arrow next to Excluded From Build and select Yes, and then select OK.

Hinweis

Verwenden Sie zum Debuggen von ausführbaren Projekten die Projektmappenelemente, um alle NATVIS-Dateien hinzuzufügen, die sich nicht in der PDB-Datei befinden, da kein C++-Projekt verfügbar ist.For debugging executable projects, use the solution items to add any .natvis files that are not in the .pdb, since there is no C++ project available.

Hinweis

Natvis-Regeln, die aus einer PDB-Datei geladen werden, gelten nur für die Typen in den Modulen, auf die sich die PDB-Datei bezieht.Natvis rules loaded from a .pdb apply only to the types in the modules that the .pdb refers to. Wenn z. B. Module1.pdb einen Natvis-Eintrag für einen Typ namens Test enthält, gilt er nur für die Klasse Test in Module1.dll.For example, if Module1.pdb has a Natvis entry for a type named Test, it only applies to the Test class in Module1.dll. Wenn ein anderes Modul ebenfalls eine Klasse mit dem Namen Test definiert, gilt der Natvis-Eintrag in der Datei Module1.pdb hierfür nicht.If another module also defines a class named Test, the Module1.pdb Natvis entry does not apply to it.

So installieren und registrieren Sie eine NATVIS-Datei über ein VSIX-PaketTo install and register a .natvis file via a VSIX package:

Mit einem VSIX-Paket können NATVIS-Dateien installiert und registriert werden.A VSIX package can install and register .natvis files. Unabhängig davon, wo Sie installiert sind, werden alle registrierten NATVIS-Dateien beim Debuggen automatisch abgeholt.No matter where are they installed, all registered .natvis files are automatically picked up during debugging.

  1. Schließen Sie die NATVIS-Datei in das VSIX-Paket ein.Include the .natvis file in the VSIX package. Beispielsweise für die folgende Projektdatei:For example, for the following project file:

    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
      <ItemGroup>
        <VSIXSourceItem Include="Visualizer.natvis" />
      </ItemGroup>
    </Project>
    
  2. Registrieren Sie die NATVIS-Datei in der Datei source.extension.vsixmanifest:Register the .natvis file in the source.extension.vsixmanifest file:

    <?xml version="1.0" encoding="utf-8"?>
    <PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
      <Assets>
        <Asset Type="NativeVisualizer" Path="Visualizer.natvis"  />
      </Assets>
    </PackageManifest>
    

Speicherorte der NATVIS-DateiNatvis file locations

Sie können NATVIS-Dateien zu Ihrem Benutzerverzeichnis oder einem Systemverzeichnis hinzufügen, wenn sie für mehrere Projekte gelten sollen.You can add .natvis files to your user directory or to a system directory, if you want them to apply to multiple projects.

Die NATVIS-Dateien werden in der folgenden Reihenfolge ausgewertet:The .natvis files are evaluated in the following order:

  1. Jede NATVIS-Datei, die in eine PDB-Datei eingebettet ist, die Sie debuggen, sofern keine Datei mit demselben Namen in dem geladenen Projekt vorhanden ist.Any .natvis files that are embedded in a .pdb you're debugging, unless a file of the same name exists in the loaded project.

  2. Alle NATVIS-Dateien, die sich in einem geladenen C++-Projekt oder in einer Projektmappe der obersten Ebene befinden.Any .natvis files that are in a loaded C++ project or top-level solution. Diese Gruppe enthält alle geladenen C++-Projekte, einschließlich Klassenbibliotheken, aber keine Projekte in anderen Sprachen.This group includes all loaded C++ projects, including class libraries, but not projects in other languages.

  3. Alle NATVIS-Dateien, die über ein VSIX-Paket installiert und registriert werden.Any .natvis files installed and registered via a VSIX package.

  1. Das benutzerspezifische Natvis-Verzeichnis (z. B. %USERPROFILE%\Documents\Visual Studio 2017\Visualizers).The user-specific Natvis directory (for example, %USERPROFILE%\Documents\Visual Studio 2017\Visualizers).
  1. Das benutzerspezifische Natvis-Verzeichnis (z. B. %USERPROFILE%\Documents\Visual Studio 2019\Visualizers).The user-specific Natvis directory (for example, %USERPROFILE%\Documents\Visual Studio 2019\Visualizers).
  1. Das systemweite Natvis-Verzeichnis ( %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers).The system-wide Natvis directory (%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers). Dieses Verzeichnis enthält die NATVIS-Dateien, die mit Visual Studio installiert werden.This directory has the .natvis files that are installed with Visual Studio. Wenn Sie über Administratorrechte verfügen, können Sie Dateien zu diesem Verzeichnis hinzufügen.If you have administrator permissions, you can add files to this directory.

Ändern von NATVIS-Dateien beim DebuggenModify .natvis files while debugging

Sie können eine NATVIS-Datei in der integrierten Entwicklungsumgebung (IDE) ändern, während Sie ihr Projekt debuggen.You can modify a .natvis file in the IDE while debugging its project. Öffnen Sie die Datei in derselben Instanz von Visual Studio, mit der Sie debuggen, ändern Sie sie, und speichern Sie sie anschließend.Open the file in the same instance of Visual Studio you're debugging with, modify it, and save it. Nach dem Speichern der Datei werden die Fenster Überwachen und Lokal aktualisiert, um die Änderung zu übernehmen.As soon as the file is saved, the Watch and Locals windows update to reflect the change.

Sie können NATVIS-Dateien zudem in einer Projektmappe, die Sie debuggen, hinzufügen oder aus ihr löschen. Visual Studio fügt die relevanten Visualisierungen hinzu bzw. entfernt sie.You can also add or delete .natvis files in a solution that you're debugging, and Visual Studio adds or removes the relevant visualizations.

Sie können NATVIS-Dateien, die in PDB-Dateien eingebettet sind, während des Debuggens nicht aktualisieren.You can't update .natvis files that are embedded in .pdb files while you're debugging.

Wenn Sie die NATVIS-Datei außerhalb von Visual Studio ändern, werden die Änderungen nicht automatisch wirksam.If you modify the .natvis file outside of Visual Studio, the changes don't take effect automatically. Zum Aktualisieren der Debuggerfenster können Sie den Befehl .natvisreload im Fenster Direkt neu auswerten.To update the debugger windows, you can reevaluate the .natvisreload command in the Immediate window. Dann treten die Änderungen in Kraft, ohne dass die Debugsitzung neu gestartet werden muss.Then the changes take effect without restarting the debugging session.

Verwenden Sie auch den Befehl .natvisreload, um ein Upgrade der NATVIS-Datei auf eine neuere Version durchzuführen.Also use the .natvisreload command to upgrade the .natvis file to a newer version. Die NATVIS-Datei kann z. B. in die Quellcodeverwaltung eingecheckt werden, und Sie möchten die letzten Änderungen übernehmen, die jemand anderes vorgenommen hat.For example, the .natvis file may be checked into source control, and you want to pick up recent changes that somebody else made.

Ausdrücke und FormatierungExpressions and formatting

Natvis-Visualisierungen verwenden C++-Ausdrücke, um anzuzeigende Datenelementen anzugeben.Natvis visualizations use C++ expressions to specify the data items to display. Zusätzlich zu den Erweiterungen und Einschränkungen von C++-Ausdrücken im Debugger, die in Kontextoperator (C++) beschrieben sind, sollten Sie Folgendes beachten:In addition to the enhancements and limitations of C++ expressions in the debugger, which are described in Context operator (C++), be aware of the following:

  • Natvis-Ausdrücke werden im Kontext des Objekts ausgewertet, das in der Schnellansicht und nicht im aktuellen Stapelrahmen angezeigt wird.Natvis expressions are evaluated in the context of the object being visualized, not the current stack frame. So bezieht sich x in einem Natvis-Ausdruck z. B. auf das Feld namens x in dem zu visualisierenden Objekt, nicht auf eine lokale Variable namens x in der aktuellen Funktion.For example, x in a Natvis expression refers to the field named x in the object being visualized, not to a local variable named x in the current function. Sie können nicht auf lokale Variablen in Natvis-Ausdrücken zugreifen, obwohl Sie auf globale Variablen zugreifen können.You can't access local variables in Natvis expressions, although you can access global variables.

  • Natvis-Ausdrücke lassen keine Funktionsauswertung oder Nebeneffekte zu.Natvis expressions don't allow function evaluation or side effects. Funktionsaufrufe und Zuweisungsoperatoren werden ignoriert.Function calls and assignment operators are ignored. Da systeminterne Debuggerfunktionen keine Nebeneffekte haben, können sie beliebig von jedem Natvis-Ausdruck aufgerufen werden, obwohl andere Funktionsaufrufe nicht zulässig sind.Because debugger intrinsic functions are side-effect free, they may be freely called from any Natvis expression, even though other function calls are disallowed.

  • Sie können die Anzeige eines Ausdrucks steuern, indem Sie einen der unter Formatbezeichner in C++ beschriebenen Formatbezeichner verwenden.To control how an expression displays, you can use any of the format specifiers described in Format specifiers in C++. Formatbezeichner werden ignoriert, wenn der Eintrag intern von Natvis verwendet wird, z. B. der Size-Ausdruck in einer ArrayItems-Erweiterung.Format specifiers are ignored when the entry is used internally by Natvis, such as the Size expression in a ArrayItems expansion.

Hinweis

Da es sich bei dem NATVIS-Dokument um ein XML-Dokument handelt, können Sie in Ihren Ausdrücken die Operatoren kaufmännisches Und, Größer-als-Zeichen, Kleiner-als-Zeichen und Schiebeoperatoren nicht direkt verwenden.Because the natvis document is XML, your expressions cannot directly use the ampersand, greater than, less than, or shift operators. Sie müssen für diese Zeichen sowohl im Elementtext als auch in den Bedingungsanweisungen Escapezeichen verwenden.You must escape these characters in both the item body and the condition statements. Beispiel:For example:
<Item Name="HiByte">(byte)(_flags &gt;&gt; 24),x</Item><Item Name="HiByte">(byte)(_flags &gt;&gt; 24),x</Item>
<Item Name="HiByteStatus" Condition="(_flags &amp; 0xFF000000) == 0">"None"</Item><Item Name="HiByteStatus" Condition="(_flags &amp; 0xFF000000) == 0">"None"</Item>
<Item Name="HiByteStatus" Condition="(_flags &amp; 0xFF000000) != 0">"Some"</Item><Item Name="HiByteStatus" Condition="(_flags &amp; 0xFF000000) != 0">"Some"</Item>

Natvis-AnsichtenNatvis views

Sie können verschiedene Natvis-Ansichten definieren, um Typen auf unterschiedliche Weise anzuzeigen.You can define different Natvis views to display types in different ways. Hier ist z. B. eine Visualisierung von std::vector, die eine vereinfachte Ansicht namens simple definiert.For example, here is a visualization of std::vector that defines a simplified view named simple. Die DisplayString- und ArrayItems-Elemente werden in der Standardansicht und der simple-Ansicht angezeigt, während die [size]- und [capacity]-Elemente in der simple-Ansicht nicht angezeigt werden.The DisplayString and the ArrayItems elements show in the default view and the simple view, while the [size] and [capacity] items don't show in the simple view.

<Type Name="std::vector&lt;*&gt;">
    <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
    <Expand>
        <Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item>
        <Item Name="[capacity]" ExcludeView="simple">_Myend - _Myfirst</Item>
        <ArrayItems>
            <Size>_Mylast - _Myfirst</Size>
            <ValuePointer>_Myfirst</ValuePointer>
        </ArrayItems>
    </Expand>
</Type>

Verwenden Sie im Fenster Überwachen den Formatbezeichner ,view, um eine alternative Ansicht anzugeben.In the Watch window, use the ,view format specifier to specify an alternate view. Die einfache Ansicht wird als vec,view(simple) angezeigt:The simple view appears as vec,view(simple):

Überwachungsfenster mit einfacher AnsichtWatch window with simple view

Natvis-FehlerNatvis errors

Wenn der Debugger Fehler in einem Visualisierungseintrag erkennt, werden diese ignoriert.When the debugger encounters errors in a visualization entry, it ignores them. Der Typ wird entweder in der unformatierter Form angezeigt, oder es wird eine andere geeignete Visualisierung ausgewählt.It either displays the type in its raw form, or picks another suitable visualization. Sie können die Natvis-Diagnose verwenden, um zu verstehen, warum der Debugger einen Visualisierungseintrag ignoriert hat, und um zugrunde liegende Syntax- und Analysefehler anzuzeigen.You can use Natvis diagnostics to understand why the debugger ignored a visualization entry, and to see underlying syntax and parse errors.

So aktivieren Sie die Natvis-DiagnoseTo turn on Natvis diagnostics:

  • Legen Sie unter Extras > Optionen (oder Debuggen > Optionen) > Debugging > Ausgabefenster die Natvis-Diagnosemeldungen (nur C++) auf Fehler, Warnung oder Ausführlich fest, und wählen Sie dann OK aus.Under Tools > Options (or Debug > Options) > Debugging > Output Window, set Natvis diagnostic messages (C++ only) to Error, Warning, or Verbose, and then select OK.

Die Fehler werden im Fenster Ausgabe angezeigt.The errors appear in the Output window.

Natvis-SyntaxverweisNatvis syntax reference

AutoVisualizer-ElementAutoVisualizer element

Bei dem AutoVisualizer-Element handelt es sich um den Stammknoten der NATVIS-Datei, der das xmlns:-Attribut für den Namespace enthält.The AutoVisualizer element is the root node of the .natvis file, and contains the namespace xmlns: attribute.

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
.
.
</AutoVisualizer>

Das AutoVisualizer-Element kann folgende untergeordnete Elemente aufweisen: Typ, HResult, UIVisualizer und CustomVisualizer.The AutoVisualizer element can have Type, HResult, UIVisualizer, and CustomVisualizer children.

Type-ElementType element

Ein grundlegender Type sieht wie dieses Beispiel aus:A basic Type looks like this example:

<Type Name="[fully qualified type name]">
  <DisplayString Condition="[Boolean expression]">[Display value]</DisplayString>
  <Expand>
    ...
  </Expand>
</Type>

Das Type-Element gibt Folgendes an:The Type element specifies:

  1. Für welchen Typ die Visualisierung verwendet werden soll (das Name-Attribut).What type the visualization should be used for (the Name attribute).

  2. Wie der Wert eines Objekts dieses Typs aussehen soll (das DisplayString -Element).What the value of an object of that type should look like (the DisplayString element).

  3. Wie die Member des Typs aussehen sollen, wenn der Benutzer den Typ in einem variablen Fenster erweitert (der Expand-Knoten).What the members of the type should look like when the user expands the type in a variable window (the Expand node).

Auf Vorlagen basierende KlassenTemplated classes

Für das Name-Attribut des Type-Elements kann ein Sternchen (*) als Platzhalterzeichen für vorlagenbasierte Klassennamen verwendet werden.The Name attribute of the Type element accepts an asterisk * as a wildcard character that can be used for templated class names.

Im folgenden Beispiel wird die gleiche Visualisierung verwendet, unabhängig davon, ob das Objekt CAtlArray<int> oder CAtlArray<float> ist.In the following example, the same visualization is used whether the object is a CAtlArray<int> or a CAtlArray<float>. Wenn es einen bestimmten Visualisierungseintrag für CAtlArray<float> gibt, hat er Vorrang vor dem generischen Objekt.If there's a specific visualization entry for a CAtlArray<float>, then it takes precedence over the generic one.

<Type Name="ATL::CAtlArray&lt;*&gt;">
    <DisplayString>{{Count = {m_nSize}}}</DisplayString>
</Type>

Sie können auf Vorlagenparameter im Visualisierungseintrag verweisen, indem Sie die Makros „$T1“, „$T2“ usw. verwenden.You can reference template parameters in the visualization entry by using macros $T1, $T2, and so forth. Beispiele zu diesen Makros finden Sie in den NATVIS-Dateien, die in Visual Studio bereitgestellt werden.To find examples of these macros, see the .natvis files shipped with Visual Studio.

Typenabgleich in der SchnellansichtVisualizer type matching

Wenn ein Visualisierungseintrag nicht überprüft werden kann, wird die nächste verfügbare Visualisierung verwendet.If a visualization entry fails to validate, the next available visualization is used.

Inheritable-AttributInheritable attribute

Mit dem optionalen Attribut Inheritable wird angegeben, ob eine Visualisierung nur auf einen Basistyp oder auf einen Basistyp und alle abgeleiteten Typen angewendet werden soll.The optional Inheritable attribute specifies whether a visualization applies only to a base type, or to a base type and all derived types. Der Standardwert von Inheritable ist true.The default value of Inheritable is true.

Im folgenden Beispiel wird die Visualisierung nur auf den BaseClass-Typ angewendet:In the following example, the visualization applies only to the BaseClass type:

<Type Name="Namespace::BaseClass" Inheritable="false">
    <DisplayString>{{Count = {m_nSize}}}</DisplayString>
</Type>

Priority-AttributPriority attribute

Das optionale Attribut Priority gibt die Reihenfolge an, in der alternative Definitionen verwendet werden, wenn beim Analysieren einer Definition Fehler auftreten.The optional Priority attribute specifies the order in which to use alternate definitions, if a definition fails to parse. Die möglichen Werte von Priority sind: Low, MediumLow, Medium, MediumHigh und High.The possible values of Priority are: Low, MediumLow,Medium, MediumHigh, and High. Der Standardwert ist Medium.The default value is Medium. Das Priority-Attribut unterscheidet nur zwischen Prioritäten innerhalb derselben NATVIS-Datei.The Priority attribute distinguishes only among priorities within the same .natvis file.

Im folgenden Beispiel wird zunächst der Eintrag analysiert, der mit der 2015 STL übereinstimmt.The following example first parses the entry that matches the 2015 STL. Wenn beim Analysieren Fehler auftreten, wird der alternative Eintrag für die Version 2013 der STL verwendet:If that fails to parse, it uses the alternate entry for the 2013 version of the STL:

<!-- VC 2013 -->
<Type Name="std::reference_wrapper&lt;*&gt;" Priority="MediumLow">
     <DisplayString>{_Callee}</DisplayString>
    <Expand>
        <ExpandedItem>_Callee</ExpandedItem>
    </Expand>
</Type>

<!-- VC 2015 -->
<Type Name="std::reference_wrapper&lt;*&gt;">
    <DisplayString>{*_Ptr}</DisplayString>
    <Expand>
        <Item Name="[ptr]">_Ptr</Item>
    </Expand>
</Type>

Optional-AttributOptional attribute

Sie können ein Optional-Attribut für jeden beliebigen Knoten festlegen.You can put an Optional attribute on any node. Wenn ein Teilausdruck innerhalb eines optionalen Knotens nicht analysiert werden kann, ignoriert der Debugger diesen Knoten, wendet aber die restlichen Type-Regeln an.If a subexpression inside an optional node fails to parse, the debugger ignores that node, but applies the rest of the Type rules. Im folgenden Typ ist [State] nicht optional, während [Exception] jedoch optional ist.In the following type, [State] is non-optional, but [Exception] is optional. Wenn MyNamespace::MyClass ein Feld namens _M_exceptionHolder aufweist, werden sowohl der [State]-Knoten als auch der [Exception]-Knoten angezeigt, aber wenn es kein _M_exceptionHolder-Feld gibt, wird nur der [State]-Knoten angezeigt.If MyNamespace::MyClass has a field named _M_exceptionHolder, both the [State] node and the [Exception] node appear, but if there's no _M_exceptionHolder field, only the [State] node appears.

<Type Name="MyNamespace::MyClass">
    <Expand>
      <Item Name="[State]">_M_State</Item>
      <Item Name="[Exception]" Optional="true">_M_exceptionHolder</Item>
    </Expand>
</Type>

Condition-AttributCondition attribute

Das optionale Condition -Attribut ist für viele Visualisierungselemente verfügbar und gibt an, wann eine Visualisierungsregel verwendet werden soll.The optional Condition attribute is available for many visualization elements, and specifies when to use a visualization rule. Wenn der Ausdruck innerhalb des Condition-Attributs in false aufgelöst wird, wird die Visualisierungsregel nicht angewendet.If the expression inside the condition attribute resolves to false, the visualization rule doesn't apply. Wenn er zu true ausgewertet wird oder kein Condition-Attribut vorhanden ist, wird die Visualisierung angewendet.If it evaluates to true, or there is no Condition attribute, the visualization applies. Sie können dieses Attribut für die „if-else“-Logik in den Visualisierungseinträgen verwenden.You can use this attribute for if-else logic in the visualization entries.

Beispielsweise weist die folgende Visualisierung zwei DisplayString-Elemente für einen intelligenten Zeigertyp auf.For example, the following visualization has two DisplayString elements for a smart pointer type. Wenn der _Myptr-Member leer ist, wird die Bedingung des ersten DisplayString-Elements in true aufgelöst, wodurch diese Form angezeigt wird.When the _Myptr member is empty, the condition of the first DisplayString element resolves to true, so that form displays. Wenn der _Myptr-Member nicht leer ist, wird die Bedingung als false ausgewertet, und das zweite DisplayString-Element wird angezeigt.When the _Myptr member is not empty, the condition evaluates to false, and the second DisplayString element displays.

<Type Name="std::auto_ptr&lt;*&gt;">
  <DisplayString Condition="_Myptr == 0">empty</DisplayString>
  <DisplayString>auto_ptr {*_Myptr}</DisplayString>
  <Expand>
    <ExpandedItem>_Myptr</ExpandedItem>
  </Expand>
</Type>

IncludeView- und ExcludeView-AttributeIncludeView and ExcludeView attributes

Die Attribute IncludeView und ExcludeView geben Elemente an, die in bestimmten Ansichten angezeigt oder nicht angezeigt werden sollen.The IncludeView and ExcludeView attributes specify elements to display or not display in specific views. In der folgenden Natvis-Spezifikation von std::vector werden in der simple-Ansicht die Elemente [size] und [capacity] nicht angezeigt.For example, in the following Natvis specification of std::vector, the simple view doesn't display the [size] and [capacity] items.

<Type Name="std::vector&lt;*&gt;">
    <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
    <Expand>
        <Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item>
        <Item Name="[capacity]" ExcludeView="simple">_Myend - _Myfirst</Item>
        <ArrayItems>
            <Size>_Mylast - _Myfirst</Size>
            <ValuePointer>_Myfirst</ValuePointer>
        </ArrayItems>
    </Expand>
</Type>

Sie können die Attribute IncludeView und ExcludeView für Typen und einzelne Member verwenden.You can use the IncludeView and ExcludeView attributes on types and on individual members.

Version-ElementVersion element

Das Version-Element umfasst einen Visualisierungseintrag zu einem bestimmten Modul und einer bestimmten Version.The Version element scopes a visualization entry to a specific module and version. Das Version-Element trägt dazu bei, Namenskonflikte zu vermeiden, reduziert unbeabsichtigte Übereinstimmungen und ermöglicht unterschiedliche Visualisierungen für verschiedene Typversionen.The Version element helps avoid name collisions, reduces inadvertent mismatches, and allows different visualizations for different type versions.

Wenn eine gemeinsame Headerdatei, die von verschiedenen Modulen verwendet wird, einen Typ definiert, wird die versionierte Visualisierung nur angezeigt, wenn der Typ in der angegebenen Modulversion vorliegt.If a common header file that is used by different modules defines a type, the versioned visualization appears only when the type is in the specified module version.

Im folgenden Beispiel gilt die Visualisierung nur für den DirectUI::Border-Typ, der sich in Windows.UI.Xaml.dll von Version 1.0 bis 1.5 befindet.In the following example, the visualization is applicable only for the DirectUI::Border type found in the Windows.UI.Xaml.dll from version 1.0 to 1.5.

<Type Name="DirectUI::Border">
  <Version Name="Windows.UI.Xaml.dll" Min="1.0" Max="1.5"/>
  <DisplayString>{{Name = {*(m_pDO->m_pstrName)}}}</DisplayString>
  <Expand>
    <ExpandedItem>*(CBorder*)(m_pDO)</ExpandedItem>
  </Expand>
</Type>

Sie benötigen nicht sowohl Min als auch Max.You don't need both Min and Max. Sie sind optionale Attribute.They are optional attributes. Platzhalterzeichen werden nicht unterstützt.No wildcard characters are supported.

Das Attribut Name hat das Format filename.ext, z. B. hello.exe oder some.dll.The Name attribute is in the format filename.ext, such as hello.exe or some.dll. Es sind keine Pfadnamen zulässig.No path names are allowed.

DisplayString-ElementDisplayString element

Das DisplayString-Element gibt eine Zeichenfolge an, die als Wert einer Variablen angezeigt werden soll.The DisplayString element specifies a string to show as the value of a variable. Beliebige Zeichenfolgen können mit Ausdrücken gemischt werden.It accepts arbitrary strings mixed with expressions. Sämtliche Inhalte innerhalb von geschweiften Klammern werden als ein Ausdruck interpretiert.Everything inside curly braces is interpreted as an expression. Beispielsweise der folgende DisplayString-Eintrag:For instance, the following DisplayString entry:

<Type Name="CPoint">
  <DisplayString>{{x={x} y={y}}}</DisplayString>
</Type>

Bedeutet, dass Variablen vom Typ CPoint wie in dieser Abbildung angezeigt werden:Means that variables of type CPoint display as in this illustration:

Verwenden eines DisplayString-ElementsUse a DisplayString element

Im DisplayString-Ausdruck befinden sich x und y, die Member von CPoint sind, in geschweiften Klammern, sodass ihre Werte ausgewertet werden.In the DisplayString expression, x and y, which are members of CPoint, are inside curly braces, so their values are evaluated. Das Beispiel zeigt auch, wie eine geschweifte Klammer mit doppelten geschweiften Klammern ({{ oder }}) mit Escapezeichen versehen werden kann.The example also shows how you can escape a curly brace by using double curly braces ( {{ or }} ).

Hinweis

Das DisplayString -Element ist das einzige Element, das beliebige Zeichenfolgen und die Syntax mit geschweiften Klammern akzeptiert.The DisplayString element is the only element that accepts arbitrary strings and curly brace syntax. Alle anderen Visualisierungselemente akzeptieren nur Ausdrücke, die vom Debugger ausgewertet werden können.All other visualization elements accept only expressions that the debugger can evaluate.

StringView-ElementStringView element

Das StringView-Element definiert einen Wert, den der Debugger an die integrierte Text-Schnellansicht senden kann.The StringView element defines a value that the debugger can send to the built-in text visualizer. Angenommen, es gibt z. B. die folgende Visualisierung für den ATL::CStringT-Typ:For example, given the following visualization for the ATL::CStringT type:

<Type Name="ATL::CStringT&lt;wchar_t,*&gt;">
  <DisplayString>{m_pszData,su}</DisplayString>
</Type>

Das CStringT-Objekt wird in einem Variablenfenster wie im folgenden Beispiel angezeigt:The CStringT object displays in a variable window like this example:

CStringT-DisplayString-ElementCStringT DisplayString element

Wenn Sie ein StringView-Element hinzufügen, wird dem Debugger mitgeteilt, dass der Wert als Textvisualisierung angezeigt werden kann.Adding a StringView element tells the debugger it can display the value as a text visualization.

<Type Name="ATL::CStringT&lt;wchar_t,*&gt;">
  <DisplayString>{m_pszData,su}</DisplayString>
  <StringView>m_pszData,su</StringView>
</Type>

Während des Debuggens können Sie das Lupensymbol neben der Variablen und dann die Option Text-Schnellansicht auswählen, um die Zeichenfolge anzuzeigen, auf die m_pszData verweist.During debugging, you can select the magnifying glass icon next to the variable, and then select Text Visualizer to display the string that m_pszData points to.

CStringT-Daten mit StringView-SchnellansichtCStringT data with StringView visualizer

Der {m_pszData,su}-Ausdruck enthält den C++-Formatbezeichner su, um den Wert als Unicode-Zeichenfolge anzuzeigen.The expression {m_pszData,su} includes a C++ format specifier su, to display the value as a Unicode string. Weitere Informationen finden Sie unter Formatbezeichner in C++.For more information, see Format specifiers in C++.

Erweitern eines ElementsExpand element

Der optionale Knoten Expand passt die untergeordneten Elemente eines visualisierten Typs an, wenn Sie den Typ in einem Variablenfenster erweitern.The optional Expand node customizes the children of a visualized type when you expand the type in a variable window. Der Knoten Expand akzeptiert eine Liste untergeordneter Knoten, die die untergeordneten Elemente definieren.The Expand node accepts a list of child nodes that define the child elements.

  • Wenn ein Expand-Knoten nicht in einem Visualisierungseintrag angegeben ist, verwenden die untergeordneten Knoten die standardmäßigen Erweiterungsregeln.If an Expand node isn't specified in a visualization entry, the children use the default expansion rules.

  • Wenn ein Expand-Knoten ohne untergeordnete Knoten angegeben wird, kann der Typ in den Debuggerfenstern nicht erweitert werden.If an Expand node is specified with no child nodes under it, the type isn't expandable in the debugger windows.

Item-ErweiterungItem expansion

Das Item-Element ist das grundlegendste und häufigste Element in einem Expand-Knoten.The Item element is the most basic and common element in an Expand node. DasItem -Element definiert ein einzelnes untergeordnetes Element.Item defines a single child element. Eine CRect-Klasse mit den Feldern top, left, right und bottom verfügt z. B. über den folgenden Visualisierungseintrag:For example, a CRect class with fields top, left, right, and bottom has the following visualization entry:

<Type Name="CRect">
  <DisplayString>{{top={top} bottom={bottom} left={left} right={right}}}</DisplayString>
  <Expand>
    <Item Name="Width">right - left</Item>
    <Item Name="Height">bottom - top</Item>
  </Expand>
</Type>

Im Debuggerfenster sieht der CRect-Typ wie im folgenden Beispiel aus:In the debugger window, the CRect type looks like this example:

CRect mit Item-Element-ErweiterungCRect with Item element expansion

Der Debugger wertet die in den Width- und Height-Elementen angegebenen Ausdrücke aus und zeigt die Werte in der Spalte Wert des Variablenfensters an.The debugger evaluates the expressions specified in the Width and Height elements, and shows the values in the Value column of the variable window.

Der Debugger erstellt für jede benutzerdefinierte Erweiterung automatisch den [Raw View] -Knoten.The debugger automatically creates the [Raw View] node for every custom expansion. Der vorhergehende Screenshot zeigt den Knoten [Raw View] erweitert an, um zu veranschaulichen, wie sich die standardmäßige Rohdatenansicht des Objekts von seiner Natvis-Visualisierung unterscheidet.The preceding screenshot displays the [Raw View] node expanded, to show how the default raw view of the object differs from its Natvis visualization. Mit der Standarderweiterung werden eine Teilstruktur für die Basisklasse erstellt und alle Datenmember der Basisklasse als untergeordnete Elemente aufgeführt.The default expansion creates a subtree for the base class, and lists all the data members of the base class as children.

Hinweis

Wenn der Ausdruck des Item-Elements auf einen komplexen Typ weist, ist der Item -Knoten selbst erweiterbar.If the expression of the item element points to a complex type, the Item node itself is expandable.

ArrayItems expansionArrayItems expansion

Verwenden Sie den ArrayItems -Knoten, damit der Visual Studio-Debugger den Typ als Array interpretieren und die einzelnen Elemente anzeigen kann.Use the ArrayItems node to have the Visual Studio debugger interpret the type as an array and display its individual elements. Die Visualisierung für std::vector ist ein gutes Beispiel:The visualization for std::vector is a good example:

<Type Name="std::vector&lt;*&gt;">
  <DisplayString>{{size = {_Mylast - _Myfirst}}}</DisplayString>
  <Expand>
    <Item Name="[size]">_Mylast - _Myfirst</Item>
    <Item Name="[capacity]">(_Myend - _Myfirst)</Item>
    <ArrayItems>
      <Size>_Mylast - _Myfirst</Size>
      <ValuePointer>_Myfirst</ValuePointer>
    </ArrayItems>
  </Expand>
</Type>

Im std::vector -Knoten werden die einzelnen Elemente angezeigt, wenn sie im Variablenfenster erweitert werden:A std::vector shows its individual elements when expanded in the variable window:

std::vector mit ArrayItems-Erweiterungstd::vector using ArrayItems expansion

Der ArrayItems-Knoten muss Folgendes aufweisen:The ArrayItems node must have:

  • Einen Size-Ausdruck (der als ganze Zahl ausgewertet werden muss), damit der Debugger die Länge des Arrays kennt.A Size expression (which must evaluate to an integer) for the debugger to understand the length of the array.
  • Einen ValuePointer-Ausdruck, der auf das erste Element verweist (das ein Zeiger eines Elementtyps sein muss, der nicht void* ist).A ValuePointer expression that points to the first element (which must be a pointer of an element type that is not void*).

Der Standardwert mit der Arrayuntergrenze lautet „0“.The default value of the array lower bound is 0. Verwenden Sie ein LowerBound-Element, um den Wert außer Kraft zu setzen.To override the value, use a LowerBound element. Die mit Visual Studio ausgelieferten NATVIS-Dateien enthalten Beispiele.The .natvis files shipped with Visual Studio have examples.

Hinweis

Sie können den Operator [], z. B. vector[i], mit jeder eindimensionalen Arrayvisualisierung verwenden, die ArrayItems verwendet, auch wenn der Typ selbst (z. B. CATLArray) diesen Operator nicht zulässt.You can use the [] operator, for example vector[i], with any single-dimensional array visualization that uses ArrayItems, even if the type itself (for example CATLArray) does not allow this operator.

Sie können auch mehrdimensionale Arrays angeben.You can also specify multi-dimensional arrays. In diesem Fall benötigt der Debugger etwas mehr Informationen, um untergeordnete Elemente ordnungsgemäß anzuzeigen:In that case, the debugger needs slightly more information to properly display child elements:

<Type Name="Concurrency::array&lt;*,*&gt;">
  <DisplayString>extent = {_M_extent}</DisplayString>
  <Expand>
    <Item Name="extent">_M_extent</Item>
    <ArrayItems Condition="_M_buffer_descriptor._M_data_ptr != 0">
      <Direction>Forward</Direction>
      <Rank>$T2</Rank>
      <Size>_M_extent._M_base[$i]</Size>
      <ValuePointer>($T1*) _M_buffer_descriptor._M_data_ptr</ValuePointer>
    </ArrayItems>
  </Expand>
</Type>
  • Direction gibt an, ob das Array in zeilengerichteter oder spaltengerichteter Reihenfolge angegeben ist.Direction specifies whether the array is in row-major or column-major order.
  • Rank gibt den Rang des Arrays an.Rank specifies the rank of the array.
  • Das Size-Element akzeptiert den impliziten $i-Parameter, der durch den Dimensionsindex ersetzt wird, um die Länge des Arrays in dieser Dimension festzustellen.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. Im vorherigen Beispiel sollte über den _M_extent.M_base[0]-Ausdruck die Länge der nullten Dimension, über _M_extent._M_base[1] die Länge der ersten Dimension usw. angegeben werden.In the previous example, 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.

Im Folgenden wird gezeigt, wie ein zweidimensionales Concurrency::array-Objekt im Debuggerfenster dargestellt wird:Here's how a two-dimensional Concurrency::array object looks in the debugger window:

Zweidimensionales Array mit ArrayItems-ErweiterungTwo-dimensional array with ArrayItems expansion

IndexListItems-ErweiterungIndexListItems expansion

Sie können die ArrayItems-Erweiterung nur dann verwenden, wenn die Arrayelemente im Arbeitsspeicher zusammenhängend angeordnet sind.You can use ArrayItems expansion only if the array elements are laid out contiguously in memory. Der Debugger erreicht das nächste Element, indem einfach der Zeiger erhöht wird.The debugger gets to the next element by simply incrementing its pointer. Wenn Sie den Index für den Wertknoten ändern müssen, verwenden Sie IndexListItems-Knoten.If you need to manipulate the index to the value node, use IndexListItems nodes. Hier finden Sie eine Visualisierung mit einem IndexListItems-Knoten:Here's a visualization with an IndexListItems node:

<Type Name="Concurrency::multi_link_registry&lt;*&gt;">
  <DisplayString>{{size = {_M_vector._M_index}}}</DisplayString>
  <Expand>
    <Item Name="[size]">_M_vector._M_index</Item>
    <IndexListItems>
      <Size>_M_vector._M_index</Size>
      <ValueNode>*(_M_vector._M_array[$i])</ValueNode>
    </IndexListItems>
  </Expand>
</Type>

Der einzige Unterschied zwischen ArrayItems und IndexListItems ist ValueNode, das den vollständigen Ausdruck für das ite-Element mit dem impliziten $i-Parameter erwartet.The only difference between ArrayItems and IndexListItems is the ValueNode, which expects the full expression to the ith element with the implicit $i parameter.

Hinweis

Sie können den Operator [], z. B. vector[i], mit jeder eindimensionalen Arrayvisualisierung verwenden, die IndexListItems verwendet, auch wenn der Typ selbst (z. B. CATLArray) diesen Operator nicht zulässt.You can use the [] operator, for example vector[i], with any single-dimensional array visualization that uses IndexListItems, even if the type itself (for example CATLArray) does not allow this operator.

LinkedListItems-ErweiterungLinkedListItems expansion

Wenn der Schnellansichtstyp eine verknüpfte Liste darstellt, kann der Debugger die untergeordneten Elemente mithilfe eines LinkedListItems -Knotens anzeigen.If the visualized type represents a linked list, the debugger can display its children by using a LinkedListItems node. Die folgende Visualisierung für den CAtlList-Typ verwendet LinkedListItems:The following visualization for the CAtlList type uses LinkedListItems:

<Type Name="ATL::CAtlList&lt;*,*&gt;">
  <DisplayString>{{Count = {m_nElements}}}</DisplayString>
  <Expand>
    <Item Name="Count">m_nElements</Item>
    <LinkedListItems>
      <Size>m_nElements</Size>
      <HeadPointer>m_pHead</HeadPointer>
      <NextPointer>m_pNext</NextPointer>
      <ValueNode>m_element</ValueNode>
    </LinkedListItems>
  </Expand>
</Type>

Das Size -Element bezieht sich auf die Länge der Liste.The Size element refers to the length of the list. HeadPointer zeigt auf das erste Element, NextPointer bezieht sich auf das nächste Element, und ValueNode verweist auf den Wert des Elements.HeadPointer points to the first element, NextPointer refers to the next element, and ValueNode refers to the value of the item.

Der Debugger wertet die Ausdrücke NextPointer und ValueNode im Kontext des LinkedListItems-Knotenelements und nicht im Kontext des übergeordneten Listentyps aus.The debugger evaluates the NextPointer and ValueNode expressions in the context of the LinkedListItems node element, not the parent list type. Im vorhergehenden Beispiel besitzt CAtlList die CNode-Klasse (gefunden in atlcoll.h), die ein Knoten der verknüpften Liste ist.In the preceding example, CAtlList has a CNode class (found in atlcoll.h) that is a node of the linked list. m_pNext und m_element sind Felder dieser CNode-Klasse und nicht der CAtlList-Klasse.m_pNext and m_element are fields of that CNode class, not of the CAtlList class.

ValueNode kann leer gelassen werden, oder verwenden Sie this, um auf den LinkedListItems-Knoten selbst zu verweisen.ValueNode can be left empty, or use this to refer to the LinkedListItems node itself.

CustomListItems-ErweiterungCustomListItems expansion

Die CustomListItems -Erweiterung ermöglicht Ihnen das Schreiben von benutzerdefinierter Logik für das Traversieren einer Datenstruktur, beispielsweise einer Hashtabelle.The CustomListItems expansion allows you to write custom logic for traversing a data structure such as a hashtable. Verwenden Sie CustomListItems, um Datenstrukturen zu visualisieren, die C++-Ausdrücke für alles verwenden können, was Sie zur Auswertung benötigen, die aber nicht ganz in die Form für ArrayItems, IndexListItems oder LinkedListItems passen.Use CustomListItems to visualize data structures that can use C++ expressions for everything you need to evaluate, but don't quite fit the mold for ArrayItems, IndexListItems, or LinkedListItems.

Sie können Exec verwenden, um Code innerhalb einer CustomListItems-Erweiterung unter Verwendung der in der Erweiterung definierten Variablen und Objekte auszuführen.You can use Exec to execute code inside of a CustomListItems expansion, using the variables and objects defined in the expansion. Sie können logische Operatoren, arithmetische Operatoren und Zuweisungsoperatoren mit Exec verwenden.You can use logical operators, arithmetic operators, and assignment operators with Exec. Sie können Exec nicht zum Auswerten von Funktionen verwenden, außer für systeminterne Debuggerfunktionen, die von der C++-Ausdrucksauswertung unterstützt werden.You can't use Exec to evaluate functions, except for debugger intrinsic functions supported by the C++ expression evaluator.

Die folgende Schnellansicht für CAtlMap ist ein tolles Beispiel dafür, in welchen Fällen CustomListItems angemessen ist.The following visualizer for CAtlMap is an excellent example where CustomListItems is appropriate.

<Type Name="ATL::CAtlMap&lt;*,*,*,*&gt;">
    <AlternativeType Name="ATL::CMapToInterface&lt;*,*,*&gt;"/>
    <AlternativeType Name="ATL::CMapToAutoPtr&lt;*,*,*&gt;"/>
    <DisplayString>{{Count = {m_nElements}}}</DisplayString>
    <Expand>
      <CustomListItems MaxItemsPerView="5000" ExcludeView="Test">
        <Variable Name="iBucket" InitialValue="-1" />
        <Variable Name="pBucket" InitialValue="m_ppBins == nullptr ? nullptr : *m_ppBins" />
        <Variable Name="iBucketIncrement" InitialValue="-1" />

        <Size>m_nElements</Size>
        <Exec>pBucket = nullptr</Exec>
        <Loop>
          <If Condition="pBucket == nullptr">
            <Exec>iBucket++</Exec>
            <Exec>iBucketIncrement = __findnonnull(m_ppBins + iBucket, m_nBins - iBucket)</Exec>
            <Break Condition="iBucketIncrement == -1" />
            <Exec>iBucket += iBucketIncrement</Exec>
            <Exec>pBucket = m_ppBins[iBucket]</Exec>
          </If>
          <Item>pBucket,na</Item>
          <Exec>pBucket = pBucket->m_pNext</Exec>
        </Loop>
      </CustomListItems>
    </Expand>
</Type>

TreeItems-ErweiterungTreeItems expansion

Wenn der Schnellansichtstyp eine Struktur darstellt, kann der Debugger die Struktur durchlaufen und seine untergeordneten Elemente mithilfe eines TreeItems -Knotens anzeigen.If the visualized type represents a tree, the debugger can walk the tree and display its children by using a TreeItems node. Im Folgenden ist die Visualisierung für den std::map-Typ angegeben, wobei ein TreeItems-Knoten verwendet wird:Here's the visualization for the std::map type using a TreeItems node:

<Type Name="std::map&lt;*&gt;">
  <DisplayString>{{size = {_Mysize}}}</DisplayString>
  <Expand>
    <Item Name="[size]">_Mysize</Item>
    <Item Name="[comp]">comp</Item>
    <TreeItems>
      <Size>_Mysize</Size>
      <HeadPointer>_Myhead->_Parent</HeadPointer>
      <LeftPointer>_Left</LeftPointer>
      <RightPointer>_Right</RightPointer>
      <ValueNode Condition="!((bool)_Isnil)">_Myval</ValueNode>
    </TreeItems>
  </Expand>
</Type>

Die Syntax ist dem LinkedListItems-Knoten ähnlich.The syntax is similar to the LinkedListItems node. LeftPointer, RightPointer und ValueNode werden unter dem Kontext der Strukturknotenklasse ausgewertet.LeftPointer, RightPointer, and ValueNode are evaluated under the context of the tree node class. ValueNode kann leer gelassen werden, oder verwenden Sie this, um auf den TreeItems-Knoten selbst zu verweisen.ValueNode can be left empty or use this to refer to the TreeItems node itself.

ExpandedItem-ErweiterungExpandedItem expansion

Das ExpandedItem-Element generiert eine aggregierte untergeordnete Ansicht, indem die Eigenschaften von Basisklassen oder Datenmembern so angezeigt werden, als ob sie untergeordnete Elemente des Schnellansichtstyps wären.The ExpandedItem element generates an aggregated child view by displaying properties of base classes or data members as if they were children of the visualized type. Der Debugger wertet den angegebenen Ausdruck aus und fügt die untergeordneten Knoten des Ergebnisses an die untergeordnete Liste des visualisierten Typs an.The debugger evaluates the specified expression, and appends the child nodes of the result to the child list of the visualized type.

Der intelligente Zeigertyp auto_ptr<vector<int>> wird z. B. in der Regel wie folgt angezeigt:For example, the smart pointer type auto_ptr<vector<int>> typically displays as:

auto_ptr<vector<int>> Standarderweiterungauto_ptr<vector<int>> default expansion

Um die Werte des Vektors anzuzeigen, müssen Sie im Variablenfenster einen Drilldown über zwei Ebenen durch den _Myptr-Member ausführen.To see the values of the vector, you have to drill down two levels in the variable window, passing through the _Myptr member. Durch Hinzufügen eines ExpandedItem-Elements können Sie die _Myptr-Variable aus der Hierarchie ausschließen und die Vektorelemente direkt anzeigen:By adding an ExpandedItem element, you can eliminate the _Myptr variable from the hierarchy and directly view the vector elements:

<Type Name="std::auto_ptr&lt;*&gt;">
  <DisplayString>auto_ptr {*_Myptr}</DisplayString>
  <Expand>
    <ExpandedItem>_Myptr</ExpandedItem>
  </Expand>
</Type>

auto_ptr<vector<int>> ExpandedItem-Erweiterungauto_ptr<vector<int>> ExpandedItem expansion

Im folgenden Beispiel wird dargestellt, wie Eigenschaften der Basisklasse in einer abgeleiteten Klasse zusammengefasst werden.The following example shows how to aggregate properties from the base class in a derived class. Angenommen, die CPanel -Klasse wird von CFrameworkElementabgeleitet.Suppose the CPanel class derives from CFrameworkElement. Anstatt die Eigenschaften zu wiederholen, die von der CFrameworkElement-Basisklasse stammen, fügt die ExpandedItem-Knotenvisualisierung diese Eigenschaften an die untergeordnete Liste der CPanel-Klasse an.Instead of repeating the properties that come from the base CFrameworkElement class, the ExpandedItem node visualization appends those properties to the child list of the CPanel class.

<Type Name="CPanel">
  <DisplayString>{{Name = {*(m_pstrName)}}}</DisplayString>
  <Expand>
    <Item Name="IsItemsHost">(bool)m_bItemsHost</Item>
    <ExpandedItem>*(CFrameworkElement*)this,nd</ExpandedItem>
  </Expand>
</Type>

Der nd-Formatbezeichner, mit dem die Visualisierungsabstimmung für die abgeleitete Klasse deaktiviert wird, ist hier erforderlich.The nd format specifier, which turns off visualization matching for the derived class, is necessary here. Andernfalls würde der *(CFrameworkElement*)this-Ausdruck dazu führen, dass die CPanel-Visualisierung erneut angewendet wird, da sie von den Standardregeln für die Visualisierungstypenabstimmung als geeignetste angesehen wird.Otherwise, the expression *(CFrameworkElement*)this would cause the CPanel visualization to be applied again, because the default visualization type matching rules consider it the most appropriate one. Weisen Sie den Debugger mit dem nd-Formatbezeichner an, die Basisklassenvisualisierung oder aber die Standarderweiterung zu verwenden, wenn die Basisklasse keine Visualisierung aufweist.Use the nd format specifier to instruct the debugger to use the base class visualization, or the default expansion if the base class has no visualization.

Synthetische ElementerweiterungSynthetic item expansion

Während das ExpandedItem-Element eine flachere Datenansicht durch die Beseitigung von Hierarchien bereitstellt, bewirkt der Synthetic-Knoten das Gegenteil.While the ExpandedItem element provides a flatter view of data by eliminating hierarchies, the Synthetic node does the opposite. Es ermöglicht Ihnen, ein künstliches untergeordnetes Element zu erstellen, das nicht das Ergebnis eines Ausdrucks ist.It allows you to create an artificial child element that isn't a result of an expression. Das künstliche Element kann eigene untergeordnete Elemente aufweisen.The artificial element can have child elements of its own. Im folgenden Beispiel verwendet die Visualisierung für den Concurrency::array -Typ einen Synthetic -Knoten, um dem Benutzer eine Diagnosemeldung anzuzeigen:In the following example, the visualization for the Concurrency::array type uses a Synthetic node to show a diagnostic message to the user:

<Type Name="Concurrency::array&lt;*,*&gt;">
  <DisplayString>extent = {_M_extent}</DisplayString>
  <Expand>
    <Item Name="extent" Condition="_M_buffer_descriptor._M_data_ptr == 0">_M_extent</Item>
    <ArrayItems Condition="_M_buffer_descriptor._M_data_ptr != 0">
      <Rank>$T2</Rank>
      <Size>_M_extent._M_base[$i]</Size>
      <ValuePointer>($T1*) _M_buffer_descriptor._M_data_ptr</ValuePointer>
    </ArrayItems>
    <Synthetic Name="Array" Condition="_M_buffer_descriptor._M_data_ptr == 0">
      <DisplayString>Array members can be viewed only under the GPU debugger</DisplayString>
    </Synthetic>
  </Expand>
</Type>

Concurrency::Array mit Synthetic-ElementerweiterungConcurrency::Array with Synthetic element expansion

HResult-ElementHResult element

Mit dem HResult-Element können Sie die für ein HRESULT in Debuggerfenstern angezeigten Informationen anpassen.The HResult element lets you customize the information shown for an HRESULT in debugger windows. Das HRValue-Element muss den 32-Bit-Wert des anzupassenden HRESULT-Elements enthalten.The HRValue element must contain the 32-bit value of the HRESULT that is to be customized. Das HRDescription-Element enthält die Informationen, die im Debuggerfenster angezeigt werden sollen.The HRDescription element contains the information to show in the debugger window.


<HResult Name="MY_E_COLLECTION_NOELEMENTS">
  <HRValue>0xABC0123</HRValue>
  <HRDescription>No elements in the collection.</HRDescription>
</HResult>

UIVisualizer-ElementUIVisualizer element

Ein UIVisualizer -Element registriert ein grafisches Schnellansichts-Plug-In mit dem Debugger.A UIVisualizer element registers a graphical visualizer plug-in with the debugger. Eine grafische Schnellansicht erstellt ein Dialogfeld oder eine andere Schnittstelle, die eine Variable oder ein Objekt in einer Weise anzeigt, die mit ihrem Datentyp konsistent ist.A graphical visualizer creates a dialog box or other interface that shows a variable or object in a way consistent with its data type. Das Schnellansichts-Plug-In muss als VSPackage erstellt sein und einen Dienst bereitstellen, den der Debugger nutzen kann.The visualizer plug-in must be authored as a VSPackage, and must expose a service that the debugger can consume. Die NATVIS-Datei enthält Registrierungsinformationen für das Plug-In, z. B. den Namen, die GUID des verfügbar gemachten Diensts und die Typen, die sie visualisieren kann.The .natvis file contains registration information for the plug-in, such as its name, the GUID of the exposed service, and the types it can visualize.

Im Folgenden ist ein Beispiel eines UIVisualizer-Elements angegeben:Here's an example of a UIVisualizer element:

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
    <UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}"
        Id="1" MenuName="Vector Visualizer"/>
    <UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}"
        Id="2" MenuName="List Visualizer"/>
.
.
</AutoVisualizer>
  • Ein ServiceId - Id-Attributpaar identifiziert ein UIVisualizer.A ServiceId - Id attribute pair identifies a UIVisualizer. Die ServiceId ist die GUID des Diensts, den das Schnellansichtspaket verfügbar macht.The ServiceId is the GUID of the service the visualizer package exposes. Id ist ein eindeutiger Bezeichner, der Schnellansichten unterscheidet, wenn von einem Dienst mehrere bereitgestellt werden.Id is a unique identifier that differentiates visualizers, if a service provides more than one. Im vorhergehenden Beispiel stellt derselbe Schnellansichtsdienst zwei Schnellansichten zur Verfügung.In the preceding example, the same visualizer service provides two visualizers.

  • Das Attribut MenuName definiert einen Schnellansichtsnamen, der im Debugger in der Dropdownliste neben dem Lupensymbol angezeigt wird.The MenuName attribute defines a visualizer name to display in the drop-down next to the magnifying glass icon in the debugger. Zum Beispiel:For example:

    Kontextmenü des UIVisualizer-MenüsUIVisualizer menu shortcut menu

Alle Typen, die in der NATVIS-Datei definiert sind, müssen explizit alle Benutzeroberflächenschnellansichten auflisten, die sie anzeigen können.Each type defined in the .natvis file must explicitly list any UI visualizers that can display it. Der Debugger passt die Schnellansichtsverweise in den Typeinträgen mit den registrierten Schnellansichten an.The debugger matches the visualizer references in the type entries with the registered visualizers. Der folgende Typeintrag für std::vector verweist z. B. auf das UIVisualizer im vorherigen Beispiel.For example, the following type entry for std::vector references the UIVisualizer in the preceding example.

<Type Name="std::vector&lt;int,*&gt;">
  <UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />
</Type>

Ein Beispiel für ein UIVisualizer finden Sie in der Image Watch-Erweiterung, die zum Anzeigen von In-Memory-Bitmaps verwendet wird.You can see an example of a UIVisualizer in the Image Watch extension used to view in-memory bitmaps.

CustomVisualizer-ElementCustomVisualizer element

CustomVisualizer ist ein Erweiterungspunkt. Er gibt eine VSIX-Erweiterung an, die Sie schreiben können, um Visualisierungen in Visual Studio-Code zu steuern.CustomVisualizer is an extensibility point that specifies a VSIX extension that you write to control visualizations in Visual Studio code. Weitere Informationen zum Schreiben von VSIX-Erweiterungen finden Sie im Visual Studio SDK.For more information about writing VSIX extensions, see the Visual Studio SDK.

Es ist viel aufwendiger, eine benutzerdefinierte Visualisierung zu schreiben als eine XML-Natvis-Definition. Sie sind jedoch nicht an Beschränkungen gebunden, wenn es darum geht, was Natvis unterstützt und was nicht.It's a lot more work to write a custom visualizer than an XML Natvis definition, but you're free from constraints about what Natvis does or doesn't support. Benutzerdefinierte Schnellansichten verfügen über Zugriff auf den vollständigen Satz der Debugger-Erweiterbarkeits-APIs. Diese können zum Abfragen und Ändern des debuggenden Prozesses oder zum Kommunizieren mit anderen Bestandteilen von Visual Studio verwendet werden.Custom visualizers have access to the full set of debugger extensibility APIs, which can query and modify the debuggee process or communicate with other parts of Visual Studio.

Sie können die Attribute Condition, IncludeView und ExcludeView für CustomVisualizer-Elemente verwenden.You can use the Condition, IncludeView, and ExcludeView attributes on CustomVisualizer elements.

EinschränkungenLimitations

Natvis-Anpassungen arbeiten mit Klassen und Strukturen, jedoch nicht mit Typedefs.Natvis customizations work with classes and structs, but not typedefs.

Natvis unterstützt keine Schnellansichten für einfache Typen (z. B. int, bool) oder für Zeiger auf einfache Typen.Natvis does not support visualizers for primitive types (for example, int, bool) or for pointers to primitive types. In diesem Szenario besteht eine Möglichkeit darin, den für Ihren Anwendungsfall geeigneten Formatbezeichner zu verwenden.In this scenario, one option is to use the format specifier appropriate to your use case. Wenn Sie z. B. double* mydoublearray in Ihrem Code verwenden, können Sie im Fenster Überwachen des Debuggers einen Arrayformatspezifizierer verwenden, z. B. den Ausdruck mydoublearray, [100], der die ersten 100 Elemente anzeigt.For example, if you use double* mydoublearray in your code, then you can use an array format specifier in the debugger's Watch window, such as the expression mydoublearray, [100], which shows the first 100 elements.