Créer des vues personnalisées d’objets natifs dans le débogueur Visual StudioCreate custom views of native objects in the Visual Studio debugger

L’infrastructure Natvis de Visual Studio vous permet de personnaliser la façon dont Visual Studio affiche les types natifs dans les fenêtres de variables du débogueur (par exemple, le espion fenêtre, variables locales fenêtre, puis, dans Les DataTips.The Visual Studio Natvis framework lets you customize the way Visual Studio displays native types in debugger variable windows (for example, the Watch window, Locals window, and in DataTips.

Natvis remplace le fichier autoexp.dat utilisé dans les versions antérieures de Visual Studio et propose la syntaxe XML, de meilleurs diagnostics, le contrôle de version et la prise en charge de plusieurs fichiers.Natvis supersedes the autoexp.dat file that was used in earlier versions of Visual Studio and offers XML syntax, better diagnostics, versioning, and multiple file support.

Note

Vous ne pouvez pas utiliser l'infrastructure Natvis pour les visualisations dans les cas suivants :You cannot use the Natvis framework for visualizations when:

  • Vous effectuez le débogage d'un projet de bureau Windows C++ avec le type de débogueur mixte.You are debugging a C++ Windows desktop project with debugger type set to mixed.
    • Vous effectuez un débogage en mode mixte dans une application de bureau Windows en mode de compatibilité managé (Outils > Options > Débogage > Général > utiliser le Mode compatibilité managé).You are doing mixed mode debugging in a Windows desktop application in managed compatibility mode (Tools > Options > Debugging > General > Use Managed Compatibility Mode).
    • Vous effectuez un débogage dans une application de bureau Windows en mode de compatibilité native (Outils > Options > Débogage > Général > utiliser le Mode de compatibilité Native).You are debugging in a Windows desktop application in native compatibility mode (Tools > Options > Debugging > General > Use Native Compatibility Mode).

Pourquoi créer des visualisations Natvis ?Why create Natvis visualizations?

Vous pouvez utiliser l'infrastructure Natvis pour créer des règles de visualisation pour les types que vous créez, afin que les développeurs puissent les voir facilement en phase de débogage.You can use the Natvis framework to create visualization rules for the types you create so developers can see them easily during debugging.

Par exemple, l’illustration suivante montre une variable de type Windows::UI::Xaml::Controls::TextBox qui s’affiche dans le débogueur sans aucune visualisation personnalisée appliquée.For example, the following illustration shows a variable of type Windows::UI::Xaml::Controls::TextBox that is displayed in the debugger without any custom visualizations applied.

Visualisation TextBox par défautTextBox default visualization

La ligne en surbrillance montre la propriété Text de la classe TextBox .The highlighted row shows the Text property of the TextBox class. La hiérarchie de classes complexe rend difficile de trouver cette valeur ; en outre, le débogueur ne sait pas comment interpréter le type de chaîne personnalisé utilisé par l’objet, donc vous ne voyez pas la chaîne figurant dans la zone de texte.The complex class hierarchy makes it difficult to find this value; moreover, the debugger doesn't know how to interpret the custom string type used by the object, so you cannot see the string held inside the textbox.

Le même TextBox ressemble beaucoup plus simple dans la fenêtre de variables lorsque les règles de visualisation personnalisées sont appliquées.The same TextBox looks much simpler in the variable window when custom visualization rules are applied. Il est possible d'afficher ensemble les membres importants de la classe, et le débogueur montre la valeur de chaîne sous-jacente du type de chaîne personnalisé.The important members of the class can be viewed together, and the debugger shows the underlying string value of the custom string type.

Les données de zone de texte à l’aide de visualiseurTextBox data using visualizer

Utilisation de fichiers NatvisUsing Natvis files

Les fichiers .natvis sont des fichiers XML avec une extension .natvis..natvis files are XML files with a .natvis extension. Le schéma est défini dans %VSINSTALLDIR%\Xml\Schemas\natvis.xsd.The schema is defined in %VSINSTALLDIR%\Xml\Schemas\natvis.xsd.

La structure de base d’un fichier .natvis est constituée d’un ou de plusieurs éléments Type , où chaque élément Type représente une entrée de visualisation pour un type dont le nom qualifié complet est spécifié dans l’attribut Name .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.

<?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 fournit certains fichiers .natvis dans le dossier %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers .Visual Studio provides some .natvis files in %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers folder. Ces fichiers contiennent des règles de visualisation pour de nombreux types communs et ils peuvent servir d'exemples pour écrire des visualisations pour de nouveaux types.These files contain visualization rules for many common types and can serve as examples when you are writing visualizations for new types.

Ajout de fichiers .natvis à vos projetsAdding .natvis files to your projects

Vous pouvez ajouter des fichiers .natvis à tout projet C++.You can add .natvis files to any C++ project.

Pour ajouter un nouveau fichier .natvis, avec un projet C++ ouvert, sélectionnez le nœud du projet dans le l’Explorateur de solutions, puis cliquez sur Ajouter > nouvel élément > Visual C++ > utilitaire > fichier de visualisation du débogueur (.natvis).To add a new .natvis file, with an open C++ project, select the project node in the Solution Explorer, and click Add > New item > Visual C++ > Utility > Debugger visualization file (.natvis). Le débogueur charge automatiquement les fichiers Natvis des projets C++.The debugger will load Natvis files from C++ projects automatically. Par défaut, les fichiers Natvis de votre projet sont également insérés dans le fichier .pdb généré par le projet.By default, Natvis files in your project are also inserted into the .pdb file built by the project. Cela signifie que si vous déboguez le fichier binaire généré par ce projet, le débogueur charge le fichier Natvis à partir du fichier .pdb même si le projet n'est pas ouvert.This means that if you debug the binary built by this project, the debugger loads the Natvis file from the .pdb even if you do not have the project open. Si vous ne voulez pas que le fichier .natvis soit inclus dans le fichier .pdb, cliquez sur le fichier .natvis dans l’ Explorateur de solutionset, dans la fenêtre Propriétés de configuration , définissez Exclu de la génération sur Oui.If you do not want the .natvis file to be included in the .pdb, right-click the .natvis file in the Solution Explorer, and in the Configuration Properties window set Excluded from Build to Yes.

Il est recommandé de modifier les fichiers Natvis à l'aide de Visual Studio. Toutes les modifications que vous apportez pendant le débogage prennent effet automatiquement quand vous enregistrez le fichier.It is recommended that you edit Natvis files using Visual Studio Any changes you make while debugging take effect automatically when you save the file. Vous bénéficiez également d'une meilleure expérience d'édition IntelliSense.You also get an improved editing experience from IntelliSense.

Les fichiers Natvis chargés à partir d'un fichier .pdb s'appliquent uniquement aux types dans le module auquel le fichier .pdb fait référence.Natvis files that are loaded from a .pdb apply only to types in the module to which the pdb refers. Par exemple, si Module1.pdb définit une entrée pour un type nommé Test, cette entrée s’applique seulement à la classe Test dans Module1.dll.For example, if Module1.pdb defines an entry for a type named Test, this entry only applied to the Test class in Module1.dll. Si un autre module définit également une classe nommée Test, entrée de natvis de Module1.pdb ne s’y applique pas.If another module also defines a class named Test, Module1.pdb's natvis entry does not apply to it.

Déploiement de fichiers .natvisDeploying .natvis files

Si votre fichier .natvis s’applique uniquement aux types que vous créez dans un projet Visual Studio, vous n’êtes pas obligé de faire quoi que ce soit ; le .natvis est inclus dans le fichier .pdb.If your .natvis file applies only to the types you are creating in a Visual Studio project, you don't have to do anything; the .natvis is included in the .pdb. Vous pouvez cependant ajouter des fichiers .natvis dans votre répertoire utilisateur ou dans un répertoire système si vous voulez qu’ils s’appliquent à plusieurs projets.You can, however, add .natvis files to your user directory or to a system directory if you want them to apply to multiple projects.

L’ordre dans lequel les fichiers .natvis sont évalués est le suivant :The order in which .natvis files are evaluated is as follows:

  1. fichiers .natvis incorporés dans un fichier .pdb que vous déboguez (sauf si un fichier du même nom existe dans un projet chargé)..natvis files embedded in a .pdb you are debugging (unless a file of the same name exists in a loaded project).

  2. fichiers .natvis qui font partie d’un projet C++ chargé ou un élément de solution de niveau supérieur..natvis files that are part of a loaded C++ project or a top-level solution item. Ce groupe inclut des projets C++ tous chargés, y compris les bibliothèques de classes, mais elle n’inclut pas les projets d’autres langages (par exemple, vous ne pouvez pas charger un fichier .natvis à partir d’un projet c#).This group includes all loaded C++ projects, including class libraries, but it does not include projects of other languages (for example, you can't load a .natvis file from a C# project). Pour les projets exécutables, vous devez utiliser les éléments de solution pour héberger les fichiers .natvis qui ne sont pas déjà présents dans un fichier .pdb, car aucun projet C++ est disponible.For executable projects, you should use the solution items to host any .natvis files that are not already present in a .pdb, since there is no C++ project available.

  3. Le répertoire natvis spécifique à l’utilisateur (par exemple, %USERPROFILE%\Documents\Visual Studio 2017\Visualizers ou %USERPROFILE%\My Documents\Visual Studio 2015\Visualizers).The user-specific natvis directory (for example, %USERPROFILE%\Documents\Visual Studio 2017\Visualizers or %USERPROFILE%\My Documents\Visual Studio 2015\Visualizers).

  4. Le répertoire Natvis à l'échelle du système (%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers).The system-wide Natvis directory (%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers). Ce répertoire est où sont copiés les fichiers .natvis installés avec Visual Studio.This directory is where .natvis files that are installed with Visual Studio are copied. Si vous disposez des autorisations d’administrateur, vous pouvez ajouter les autres fichiers à ce répertoire.If you have administrator permissions, you can add other files to this directory as well.

Modification des fichiers .natvis pendant le débogageModifying .natvis files while debugging

Vous pouvez modifier un fichier .natvis dans l’environnement IDE pendant le débogage du projet dans lequel il est inclus.You can modify a .natvis file in the IDE while debugging the project in which it is included. Ouvrez le fichier dans l'IDE (à l'aide de l'instance de Visual Studio que vous utilisez pour le débogage), modifiez-le et enregistrez-le.Open the file in the IDE (using the same instance of Visual Studio that you are debugging with), modify it, and save it. Dès que le fichier est enregistré, les fenêtres Espion et Variables locales doivent être mises à jour pour refléter la modification.As soon as the file is saved, the Watch and Locals windows should be updated to reflect the change. Si vous modifiez le fichier .natvis en dehors de l’IDE, les modifications ne prennent pas effet automatiquement.If you modify the .natvis file outside the IDE, the changes do not take effect automatically. Pour mettre à jour les fenêtres, vous pouvez évaluer la commande .natvisreload dans la fenêtre Espion .To update the windows, you can evaluate the .natvisreload command in the Watch window. Cette action entraîne les modifications prennent effet sans avoir à redémarrer la session de débogage.This action causes the changes to take effect without restarting the debug session.

Vous pouvez également ajouter ou supprimer des fichiers .natvis à une solution que vous déboguez, Visual Studio ajoute ou supprime les visualisations correspondantes.You can also add or delete .natvis files to a solution that you are debugging, and Visual Studio adds or removes the relevant visualizations.

Si un fichier .natvis est incorporé dans un fichier .pdb, vous ne pouvez pas la modifier pendant le débogage.If a .natvis file is embedded in a .pdb, you cannot modify it while you are debugging.

Utilisez le .natvisreload commande lorsque vous mettez à niveau le fichier .natvis vers une version plus récente (par exemple, si il est archivé dans le contrôle de code source et que vous voulez reprendre les modifications récentes qu’une personne autre apportées au fichier).Use the .natvisreload command when you are upgrading the natvis file to a newer version (for example, if it's checked into source control and you want to pick up recent changes that somebody else made to the file). Il est recommandé de modifier les fichiers natvis à l'aide de l'éditeur XML de Visual Studio.It is recommended that you edit natvis files using the Visual Studio xml editor.

Expressions et mise en formeExpressions and formatting

Les visualisations Natvis utilisent des expressions C++ pour spécifier les éléments de données à afficher.Natvis visualizations use C++ expressions to specify the data items to display. En plus des améliorations et des limitations des expressions C++ dans le débogueur qui sont décrites dans Context Operator (C++), vous devez être conscient des différences suivantes :In addition to the enhancements and limitations of C++ expressions in the debugger that are described in Context Operator (C++), you should be aware of the following differences:

  • Les expressions Natvis sont évaluées dans le contexte de l'objet qui est visualisé, et non dans le frame de pile actuel.Natvis expressions are evaluated in the context of the object being visualized, not the current stack frame. Par exemple, si vous utilisez x dans une expression Natvis, l’identificateur fait référence au champ nommé x dans l’objet qui est visualisé, pas à une variable locale nommée x dans la fonction en cours d’exécution.For example, if you use x in a Natvis expression, the identifier refers to the field named x in the object being visualized, not to a local variable named x in the currently executing function. Vous ne pouvez pas accéder aux variables locales dans des expressions Natvis, même si vous pouvez accéder aux variables globales.You cannot access local variables in Natvis expressions, although you can access global variables.

  • Les expressions de Natvis n'autorisent pas l'évaluation de fonctions ni les effets secondaires.Natvis expressions do not allow function evaluation or side effects. Cela signifie que les appels de fonction et les opérateurs d'assignation sont ignorés.This means that function calls and assignment operators are ignored. Comme les fonctions intrinsèques du débogueur n'ont pas d'effets secondaires, elles peuvent librement être appelées à partir de toute expression Natvis, même si d'autres appels de fonction sont interdits.Because debugger intrinsic functions are side-effect free, they may be freely called from any Natvis expression, even though other function calls are disallowed.

    Pour contrôler la façon dont une expression s’affiche dans une fenêtre de variable, vous pouvez utiliser un des spécificateurs de format décrits dans le spécificateurs de Format section de la spécificateurs de Format en C++ rubrique.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 section of the Format Specifiers in C++ topic. Notez que les spécificateurs de format sont ignorés lors de l’entrée de la virtualisation est utilisée en interne par Natvis, notamment le Size expression dans une expansion d’ArrayItems.Note that format specifiers are ignored when the virtualization entry is used internally by Natvis, such as the Size expression in a ArrayItems expansion.

Vues NatvisNatvis views

Les vues Natvis vous permettent de voir n'importe quel type de plusieurs façons.Natvis views allow you to see any type in more than one way. Par exemple, vous pouvez définir une vue nommée simple qui vous donne une vue simplifiée d’un type.For example, you can define a view named simple that gives you a simplified view of a type. Par exemple, voici la visualisation de std::vector:For example, here is the visualization of std::vector:

<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>  

Les éléments DisplayString et ArrayItems sont utilisés dans la vue par défaut et la vue simple, tandis que les éléments [size] et [capacity] sont exclus de la vue simple.The DisplayString and the ArrayItems elements are used in the default view and the simple view, while the [size] and [capacity] items are excluded from the simple view. Vous pouvez utiliser le spécificateur de format ,view pour spécifier une autre vue.You can use the ,view format specifier to specify an alternate view. Dans la fenêtre Espion , vous spécifiez la vue simple sous la forme vec,view(simple):In the Watch window, you specify the simple view as vec,view(simple):

Fenêtre Espion avec vue simpleWatch window with simple view

Diagnostic des erreurs NatvisDiagnosing Natvis errors

Vous pouvez utiliser les diagnostics Natvis pour résoudre des erreurs de syntaxe et d'analyse.You can use Natvis diagnostics to troubleshoot syntax and parse errors. Quand le débogueur rencontre des erreurs dans une entrée de visualisation, il ignore les erreurs et affiche le type dans sa forme brute ou reprend une autre visualisation appropriée.When the debugger encounters errors in a visualization entry, it ignores the errors and either displays the type in its raw form or picks another suitable visualization. Pour comprendre pourquoi une certaine entrée de visualisation est ignorée et pour voir quels sont les erreurs sous-jacentes, vous pouvez activer des diagnostics Natvis Outils > Options > Débogage > fenêtre Sortie > messages de diagnostic Natvis (C++ uniquement) option.To understand why a certain visualization entry is ignored and to see what the underlying errors are, you can turn on Natvis diagnostics Tools > Options > Debugging > Output Window > Natvis diagnostic messages (C++ only) option. Les erreurs sont affichées dans la fenêtre Sortie .The errors are displayed in the Output window.

Référence à la syntaxe NatvisNatvis syntax reference

Élément AutoVisualizerAutoVisualizer element

L’élément AutoVisualizer est le nœud racine du fichier .natvis et contient l’attribut xmlns: de l’espace de noms.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>  

Élément TypeType element

Un Type de base ressemble à ceci :A basic Type looks like this:

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

Il spécifie :It specifies:

  1. le type pour lequel elle doit être utilisée (attribut Type Name ) ;What type this visualization should be used for (the Type Name attribute).

  2. la valeur à laquelle doit ressembler un objet de ce type (élément DisplayString ) ;What the value of an object of that type should look like (the DisplayString element).

  3. à quoi les membres du type doivent ressembler quand l'utilisateur le développe dans une fenêtre de variable (nœud Expand ).What the members of the type should look like when the user expands it in a variable window (the Expand node).

    Classes avec modèles L'attribut Name de l'élément Type accepte l'astérisque * en tant que caractère générique dans les noms des classes avec modèles :Templated classes The Name attribute of the Type element accepts an asterisk * as a wildcard character that can be used for templated class names:

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

Dans cet exemple, la même visualisation est utilisée si l’objet est un CAtlArray<int> ou un CAtlArray<float>.In this example, the same visualization is used whether the object is a CAtlArray<int> or a CAtlArray<float>. S’il existe une entrée de visualisation spécifique pour un CAtlArray<float>, puis elle est prioritaire sur la générique.If there is a specific visualization entry for a CAtlArray<float>, then it takes precedence over the generic one.

Notez qu'il est possible de faire référence à des paramètres de modèle dans l'entrée de visualisation à l'aide de macros $T1, $T2, et ainsi de suite.Note that template parameters can be referenced in the visualization entry by using macros $T1, $T2, and so forth. Pour rechercher des exemples de ces macros, consultez les fichiers .natvis fournis avec Visual Studio.To find examples of these macros, see the .natvis files shipped with Visual Studio.

Correspondance des types de visualiseurVisualizer type matching

Si une entrée de visualisation ne parvient pas à être validée, la visualisation disponible suivante est utilisée.If a visualization entry fails to validate, then the next available visualization is used.

Attribut pouvant être héritéInheritable attribute

Vous pouvez spécifier si une visualisation s'applique uniquement à un type de base ou à un type de base et à tous les types dérivés à l'aide de l'attribut facultatif Inheritable .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. Dans le code suivant, la visualisation s'applique uniquement au type BaseClass :In the following, the visualization applies only to the BaseClass type:

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

La valeur par défaut de Inheritable est true.The default value of Inheritable is true.

Attribut de prioritéPriority attribute

L'attribut Priority spécifie l'ordre dans lequel les autres définitions sont utilisées si une définition ne parvient pas à être analysée.The Priority attribute specifies the order in which alternate definitions are used if a definition fails to parse. Les valeurs possibles de Priority sont : Low, MediumLow,Medium, MediumHighet High, et la valeur par défaut est Medium.The possible values of Priority are: Low, MediumLow,Medium, MediumHigh, and High, and the default value is Medium.

L’attribut Priority doit être utilisé seulement pour distinguer les priorités dans un même fichier .natvis, et non pas entre différents fichiers.The priority attribute should only be used to distinguish between priorities within the same .natvis file, not between different files.

Dans l’exemple suivant, nous avons tout d’abord analyser l’entrée qui correspond à la bibliothèque STL 2015 et en cas d’échec d’analyse, nous utilisons l’autre entrée pour la version 2013 de la bibliothèque STL :In the following example, we first parse the entry that matches the 2015 STL, and if that fails to parse, we use 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>  

Élément VersionVersion element

Utilisez l'élément Version pour définir l'étendue des visualisations à des modules spécifiques et à leurs versions afin que les collisions de nom soient réduites et que des visualisations différentes puissent être utilisées pour différentes versions des types.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. Exemple :For example:

<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>  

Dans cet exemple, la visualisation est applicable uniquement pour le type DirectUI::Border qui figure dans Windows.UI.Xaml.dll de la version 1.0 à 1.5.In this 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. Ajout d’éléments de version étendues de l’entrée de visualisation à un module particulier et une version et réduit les correspondances par inadvertance.Adding version elements scopes the visualization entry to a particular module and version and reduces inadvertent mismatches. Toutefois, si un type est défini dans un fichier d’en-tête commun qui est utilisé par différents modules, la visualisation avec version n’est pas appliquée lorsque le type n’est pas dans le module spécifié.However, if a type is defined in a common header file that is used by different modules, the versioned visualization is not applied when the type is not in the specified module.

Attribut OptionalOptional attribute

L'attribut Optional peut apparaître sur n'importe quel nœud.The Optional attribute can appear on any node. Si n’importe quelle sous-expression à l’intérieur d’un nœud facultatif ne parvient pas à analyser, ce nœud est ignoré, mais le reste de l’élément Type est toujours valide.If any subexpression inside an optional node fails to parse, that node is ignored, but the rest of the Type element is still valid. Dans le type suivant, [State] est obligatoire, mais [Exception] est facultatif.In the following type, [State] is non-optional, but [Exception] is optional. Cela signifie que si MyNamespace::MyClass contient un champ nommé M_exceptionHolder, vous voyez toujours pas les deux [State] nœud et le [Exception] nœud, mais si le _M_exceptionHolder est manquant, vous voyez uniquement le [State] nœud.This means that if MyNamespace::MyClass contains a field named M_exceptionHolder, you still see both [State] node and the [Exception] node, but if the _M_exceptionHolder is missing, you see only the [State] node.

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

Attribut ConditionCondition attribute

L'attribut Condition facultatif est disponible pour de nombreux éléments de visualisation. Il indique quand une règle de visualisation doit être utilisée.The optional Condition attribute is available for many visualization elements and specifies when a visualization rule should be used. Si la résolution de l'expression incluse dans l'attribut Condition est false, la règle de visualisation spécifiée par l'élément n'est pas appliquée.If the expression inside the condition attribute resolves to false, then the visualization rule specified by the element is not applied. Si elle prend la valeur true, ou en l'absence d'attribut Condition , la règle de visualisation est appliquée au type.If it evaluates to true, or if there is no Condition attribute, then the visualization rule is applied to the type. Vous pouvez utiliser cet attribut pour inclure une logique if-else dans les entrées de visualisation.You can use this attribute for if-else logic in the visualization entries. Par exemple, la visualisation suivante possède deux DisplayString éléments pour un type pointeur intelligent :For example, the following visualization has two DisplayString elements for a smart pointer type:

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

Quand le membre _Myptr a la valeur null, la condition du premier élément DisplayString prend la valeur true, si bien que ce formulaire s'affiche.When the _Myptr member is null, the condition of the first DisplayString element resolves to true, so that form is displayed. Quand le membre _Myptr n'a pas la valeur null, la condition prend la valeur falseet le second élément DisplayString s'affiche.When the _Myptr member is not null, the condition evaluates to false, and the second DisplayString element is displayed.

Attributs IncludeView et ExcludeViewIncludeView and ExcludeView attributes

Ces attributs spécifient les éléments qui doivent être affichés ou non dans les différentes vues.These attributes specify elements that are to be displayed or not displayed in different views. Par exemple, pour une spécification Natvis de std::vectordonnée :For example, given the Natvis specification of std::vector:

<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>  

La vue simple n'affiche pas les éléments [taille] et [capacité] dans la vue simple.The simple view does not display the [size] and [capacity] items in the simple view. Si vous aviez utilisé IncludeView="simple" à la place de ExcludeView, les éléments [size] et [capacity] seraient affichés dans la vue simple et non pas dans la vue par défaut.If we had used IncludeView="simple" instead of ExcludeView, the [size] and [capacity] items would be shown in the simple view rather than in the default view.

Vous pouvez utiliser les attributs IncludeView et ExcludeView sur des types, ainsi que sur des membres individuels.You can use the IncludeView and ExcludeView attributes on types as well as on individual members.

DisplayStringDisplayString

Un élément DisplayString spécifie la chaîne à afficher comme valeur de la variable.A DisplayString element specifies the string to be shown as the value of the variable. Il accepte les chaînes arbitraires mélangées à des expressions.It accepts arbitrary strings mixed with expressions. Tout ce qui figure entre accolades est interprété comme une expression.Everything inside curly braces is interpreted as an expression. Par exemple, un DisplayString entrée comme suit :For instance, a DisplayString entry like the following:

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

Signifie que les variables de type CPoint sont affichées comme dans cette illustration :Means that variables of type CPoint are displayed as in this illustration:

Utilisation d’un élément DisplayStringUsing a DisplayString element

Dans l'expression DisplayString , x et y, qui sont membres de CPoint, sont entre des accolades, donc leurs valeurs sont évaluées.In the DisplayString expression, x and y, which are members of CPoint, are inside curly braces and so their values are evaluated. L'expression montre également comment échapper une accolade en utilisant des accolades doubles ( {{ ou }} ).The expression also shows how you can escape a curly brace by using double curly braces ( {{ or }} ).

Note

L'élément DisplayString est le seul élément qui accepte des chaînes arbitraires et la syntaxe avec accolades.The DisplayString element is the only element that accepts arbitrary strings and curly brace syntax. Tous les autres éléments de visualisation acceptent uniquement les expressions qui sont évaluées par le débogueur.All other visualization elements accept only expressions that are evaluated by the debugger.

StringViewStringView

L'élément StringView définit l'expression dont la valeur va être envoyée au visualiseur de texte intégré.The StringView element defines the expression whose value is going to be sent to the built-in text visualizer. Supposons, par exemple, que nous avons la visualisation suivante pour le type ATL::CStringT :For example, suppose we have the following visualization for the ATL::CStringT type:

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

La visualisation affiche un objet CStringT dans une fenêtre de variables comme celle-ci :The visualization displays a CStringT object in a variable window like this:

Élément CStringT DisplayStringCStringT DisplayString element

Ajout d’un StringView élément indique au débogueur que cette valeur peut être affichée par une visualisation de texte :Adding a StringView element indicates to the debugger that this value can be viewed by a text visualization:

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

Remarquez l'icône de loupe située en regard de la valeur ci-dessous.Notice the magnifying glass icon shown next to the value below. En choisissant l’icône lance le visualiseur de texte qui affiche la chaîne qui m_pszData pointe vers.Choosing the icon launches the text visualizer which will display the string that m_pszData points to.

Données CStringT avec visualiseur StringViewCStringT data with StringView visualizer

Note

Notez que l'expression {m_pszData,su} inclut un spécificateur de format C++, su , pour afficher la valeur sous forme de chaîne Unicode.Note that the expression {m_pszData,su} includes a C++ format specifier su to display the value as a Unicode string. Pour plus d'informations, voir Format Specifiers in C++ .See Format Specifiers in C++ for more information.

ExpandExpand

Le nœud Expand est utilisé pour personnaliser les enfants du type visualisé quand l'utilisateur le développe dans les fenêtres de variables.The Expand node is used to customize the children of the visualized type when the user expands it in the variable windows. Il accepte la liste des nœuds enfants qui définissent les éléments enfants.It accepts a list of child nodes that define the child elements.

Le nœud Expand est facultatif.The Expand node is optional.

  • Si un Expand nœud n’est pas spécifié dans une entrée de visualisation, les règles d’extension de Visual Studio par défaut sont utilisées.If an Expand node is not specified in a visualization entry, Visual Studio's default expansion rules are used.

  • Si un Expand nœud est spécifié sans nœuds enfants dans cette section, le type ne sont pas être développé dans les fenêtres du débogueur.If an Expand node is specified with no child nodes under it, the type won't be expandable in the debugger windows.

Expansion d'élémentsItem expansion

L'élément Item est le plus basique et le plus courant des éléments utilisés dans un nœud Expand .The Item element is the most basic and the most common element to be used in an Expand node. Item définit un seul élément enfant.Item defines a single child element. Supposons, par exemple, que vous ayez une classe CRect avec des champs top, left, rightet bottom et l'entrée de visualisation suivante :For example, suppose that you have a CRect class with top, left, right, and bottom as its fields and 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>  

Le type CRect se présentera comme suit :The CRect type will look like this:

CRect avec expansion d’élément ItemCRect with Item element expansion

Les expressions spécifiées dans les éléments Width et Height sont évaluées et elles s'affichent dans la colonne Valeur.The expressions specified in Width and Height elements are evaluated and shown in the value column. Le nœud [Raw View] est automatiquement créé par le débogueur chaque fois qu'une expansion personnalisée est utilisée.The [Raw View] node is automatically created by the debugger whenever a custom expansion is used. Il est développé dans la capture d'écran ci-dessus pour montrer comment l'affichage brut de l'objet diffère de sa visualisation.It is expanded in the screenshot above to show how the raw view of the object is different from its visualization. L'expansion par défaut Visual Studio crée une sous-arborescence pour la classe de base et répertorie tous les membres de données de la classe de base en tant qu'enfants.The Visual Studio default expansion creates a subtree for the base class and lists all the data members of the base class as children.

Note

Si l'expression de l'élément item pointe vers un type complexe, le nœud Item lui-même peut être développé.If the expression of the item element points to a complex type, the Item node itself is expandable.

ArrayItems expansionArrayItems expansion

Utilisez le nœud ArrayItems pour que le débogueur Visual Studio interprète le type comme un tableau et en affiche les éléments individuels.Use the ArrayItems node to have the Visual Studio debugger interpret the type as an array and display its individual elements. La visualisation pour std::vector est un bon exemple :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>  

Un std::vector montre ses éléments individuels quand il est développé dans la fenêtre de variables :A std::vector shows its individual elements when expanded in the variable window:

std::Vector utilisant une expansion ArrayItemsstd::vector using ArrayItems expansion

Au minimum, le nœud ArrayItems doit avoir :At a minimum, the ArrayItems node must have:

  1. une expression Size (qui doit prendre la valeur d'un entier) pour que le débogueur comprenne la longueur du tableau ;A Size expression (which must evaluate to an integer) for the debugger to understand the length of the array

  2. une expression ValuePointer qui doit pointer vers le premier élément (qui doit être un pointeur d'un type d'élément autre que void*).A ValuePointer expression that should point to the first element (which must be a pointer of an element type that is not void*).

    La valeur par défaut de la limite inférieure du tableau est 0.The default value of the array lower bound is 0. Elle peut être remplacée en utilisant un élément LowerBound (des exemples sont donnés dans les fichiers .natvis livrés avec Visual Studio).The value can be overridden by using a LowerBound element (examples can be found in the .natvis files shipped with Visual Studio).

    Vous pouvez maintenant utiliser l'opérateur [] avec une expansion ArrayItems , par exemple vector[i].You can now use the [] operator with an ArrayItems expansion, for example vector[i]. L'opérateur [] peut être utilisé avec n'importe quel visualisation d'un tableau unidimensionnel qui utilise ArrayItems ou IndexListItems,même si le type lui-même n'autorise pas cet opérateur (par exemple CATLArray).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).

    Il est également possible de spécifier des tableaux multidimensionnels.Multi-dimensional arrays can also be specified. Le débogueur doit simplement légèrement plus d’informations pour afficher correctement les éléments enfants dans ce cas :The debugger needs just slightly more information to properly display child elements in that case:

<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 indique si l'ordre du tableau est row-major ou column-major.Direction specifies whether the array is row-major or column-major order. Rank spécifie le rang du tableau.Rank specifies the rank of the array. Le Size élément accepte le caractère implicite $i paramètre, qu’il substitue par l’index de dimension pour déterminer la longueur du tableau dans cette dimension.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. Ainsi, dans l'exemple précédent ci-dessus, l'expression _M_extent.M_base[0] doit indiquer la longueur de la dimension 0, _M_extent._M_base[1] celle de la dimension 1, etc.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.

Voici comment une à deux dimensions Concurrency::array objet ressemble dans le débogueur :Here's how a two-dimensional Concurrency::array object looks in the debugger:

Tableau à deux dimensions avec expansion ArrayItemsTwo-dimensional array with ArrayItems expansion

Expansion d'IndexListItemsIndexListItems expansion

Vous pouvez utiliser l'expansion ArrayItems , uniquement si les éléments du tableau sont disposés de façon contiguë en mémoire.You can use the ArrayItems expansion, only if the array elements are laid out contiguously in memory. Le débogueur atteint l'élément suivant tout simplement en incrémentant son pointeur vers l'élément actuel.The debugger gets to the next element by simply incrementing its pointer to the current element. Pour prendre en charge les cas où vous devez manipuler l'index du nœud de valeur, vous pouvez utiliser des nœuds IndexListItems .To support cases where you need to manipulate the index to the value node, IndexListItems nodes can be used. Voici une visualisation à l’aide de IndexListItems nœud :Here's a visualization using 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>  

Vous pouvez maintenant utiliser l'opérateur [] avec une expansion IndexListItems , par exemple vector[i].You can now use the [] operator with an IndexListItems expansion, for example vector[i]. L'opérateur [] peut être utilisé avec n'importe quelle visualisation d'un tableau unidimensionnel qui utilise ArrayItems ou IndexListItems, même si le type lui-même n'autorise pas cet opérateur (par exemple CATLArray).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).

La seule différence entre ArrayItems et IndexListItems est que ValueNode attend l'expression complète de l'élément ième avec le paramètre $i implicite.The only difference between ArrayItems and IndexListItems is that the ValueNode expects the full expression to the ith element with the implicit $i parameter.

Expansion de LinkedListItemsLinkedListItems expansion

Si le type visualisé représente une liste liée, le débogueur peut afficher ses enfants à l'aide d'un nœud LinkedListItems .If the visualized type represents a linked list, the debugger can display its children by using a LinkedListItems node. Voici la visualisation pour la CAtlList type à l’aide de cette fonctionnalité :Here's the visualization for the CAtlList type using this feature:

<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>  

L'élément Size fait référence à la longueur de la liste.The Size element refers to the length of the list. HeadPointer pointe vers le premier élément, NextPointer fait référence à l'élément suivant et ValueNode fait référence à la valeur de l'élément.HeadPointer points to the first element, NextPointer refers to the next element, and ValueNode refers to the value of the item.

  • Les expressions NextPointer et ValueNode sont évalués dans le contexte du nœud de la liste liée et non du type de la liste parent.The NextPointer and ValueNode expressions are evaluated in the context of the linked list node element and not the parent list type. Dans l’exemple précédent, CAtlList a un CNode classe (trouvé dans atlcoll.h) qui représente un nœud de la liste liée.In the preceding example, CAtlList has a CNode class (found in atlcoll.h) that represents a node of the linked list. m_pNext et m_element sont des champs de cette classe CNode et non de la classe CAtlList .m_pNext and m_element are fields of that CNode class and not of CAtlList class.

  • L'expression ValueNode peut être laissée vide ou utiliser this pour faire référence au nœud même de la liste liée.The ValueNode can be left empty or have this to refer to the linked list node itself.

Expansion CustomListItemsCustomListItems expansion

L'expansion CustomListItems vous permet d'écrire une logique personnalisée permettant de parcourir une structure de données telle qu'une table de hachage.The CustomListItems expansion allows you to write custom logic for traversing a data structure such as a hashtable. Vous devez utiliser CustomListItems pour visualiser les données dans lesquelles tout ce que vous avez besoin évaluer des structures est exprimée via des expressions C++ mais ne correspondent pas tout à fait au moule pour ArrayItems, TreeItems, ou LinkedListItems.You should use CustomListItems to visualize data structures in which everything you need to evaluate is expressible via C++ expressions, but don't quite fit the mold for ArrayItems, TreeItems, or LinkedListItems.

Le visualiseur pour CAtlMap est un excellent exemple où CustomListItems est approprié.The visualizer for CAtlMap is an excellent example of 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>  

Vous pouvez utiliser Exec pour exécuter du code à l’intérieur d’un CustomListItems expansion à l’aide des variables et objets définis dans le CustomListItems expansion.You can use Exec to execute code inside of a CustomListItems expansion using the variables and objects defined in the CustomListItems expansion. Vous ne pouvez pas utiliser Exec pour évaluer les fonctions.You cannot use Exec to evaluate functions.

Vous pouvez utiliser des opérateurs logiques, les opérateurs arithmétiques et les opérateurs d’assignation avec Exec.You can use logical operators, arithmetic operators, and assignment operators with Exec.

Les fonctions intrinsèques suivantes sont prises en charge :The following intrinsic functions are supported:

  • strlen, wcslen, strnlen, wcsnlen, strcmp, wcscmp, _stricmp, _strcmpi, _wcsicmp, strncmp, wcsncmp, _strnicmp, _wcsnicmp, memcmp, memicmp, wmemcmp, strchr, wcschr, memchr, wmemchr, strstr, wcsstr, __log2, __findNonNull
  • GetLastError, TlsGetValue, DecodeHString, WindowsGetStringLen, WindowsGetStringRawBuffer, WindowsCompareStringOrdinal, RoInspectCapturedStackBackTrace, CoDecodeProxy, GetEnvBlockLength, DecodeWinRTRestrictedException, DynamicMemberLookup, DecodePointer, DynamicCast
  • ConcurrencyArray_OperatorBracket_idx // Concurrency::array<>::operator[index<>] and operator(index<>)
  • ConcurrencyArray_OperatorBracket_int // Concurrency::array<>::operator(int, int, ...)
  • ConcurrencyArray_OperatorBracket_tidx // Concurrency::array<>::operator[tiled_index<>] and operator(tiled_index<>)
  • ConcurrencyArrayView_OperatorBracket_idx // Concurrency::array_view<>::operator[index<>] and operator(index<>)
  • ConcurrencyArrayView_OperatorBracket_int // Concurrency::array_view<>::operator(int, int, ...)
  • ConcurrencyArrayView_OperatorBracket_tidx // Concurrency::array_view<>::operator[tiled_index<>] and operator(tiled_index<>)
  • Stdext_HashMap_Int_OperatorBracket_idx
  • Std_UnorderedMap_Int_OperatorBracket_idx
  • TreeTraverse_Init // Initializes a new tree traversal
  • TreeTraverse_Next // Returns nodes in a tree
  • TreeTraverse_Skip // Skips nodes in a pending tree traversal

Expansion de TreeItemsTreeItems expansion

Si le type visualisé représente une arborescence, le débogueur peut la parcourir et afficher ses enfants à l'aide d'un nœud TreeItems .If the visualized type represents a tree, the debugger can walk the tree and display its children by using a TreeItems node. Voici la visualisation pour la std::map type à l’aide de cette fonctionnalité :Here's the visualization for the std::map type using this feature:

<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>  

La syntaxe est semblable à la LinkedListItems nœud.The syntax is similar to the LinkedListItems node. LeftPointer, RightPointeret ValueNode sont évalués dans le contexte de la classe du nœud de l'arborescence et l'expression ValueNode peut être laissée vide ou utiliser this pour faire référence au nœud même de l'arborescence.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.

Expansion d'ExpandedItemExpandedItem expansion

L'élément ExpandedItem peut servir à générer un affichage agrégé des enfants en présentant les propriétés des classes de base ou des membres de données comme s'ils étaient des enfants du type visualisé.The ExpandedItem element can be used to generate an aggregated child view by displaying properties of base classes or data members as if they were children of the visualized type. L'expression spécifiée est évaluée et les nœuds enfants du résultat sont ajoutés à la liste enfant du type visualisé.The specified expression is evaluated and the child nodes of the result are appended to the child list of the visualized type. Par exemple, supposons que nous ayons un type pointeur intelligent auto_ptr<vector<int>>, qui affiche généralement sous la forme :For example, suppose we have a smart pointer type auto_ptr<vector<int>>, which typically displays as:

Auto_ptr<vecteur<int> > expansion par défautauto_ptr<vector<int>> default expansion

Pour voir les valeurs du vecteur, vous devez descendre de deux niveaux dans la fenêtre de variables en passant par le membre _Myptr.To see the values of the vector, you have to drill down two levels in the variable window passing through _Myptr member. En ajoutant un élément ExpandedItem , vous pouvez éliminer la variable _Myptr de la hiérarchie et afficher directement les éléments du vecteur :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<vecteur<int> > d’ExpandedItemauto_ptr<vector<int>> ExpandedItem expansion

L’exemple suivant montre comment agréger des propriétés de la classe de base dans une classe dérivée.The following example shows how to aggregate properties from the base class in a derived class. Supposons que la classe CPanel dérive de la classe CFrameworkElement.Suppose the CPanel class derives from CFrameworkElement. Au lieu de répéter les propriétés provenant de la classe CFrameworkElement de base, le nœud ExpandedItem permet à ces propriétés d'être ajoutées à la liste enfant de la classe CPanel .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. Le nd spécificateur de format, ce qui désactive le correspondantes pour la classe dérivée de visualisation, est nécessaire ici.The nd format specifier, which turns off visualization matching for the derived class, is necessary here. Sinon, l’expression *(CFrameworkElement*)this provoque la CPanel visualisation à appliquer à nouveau, car les règles de correspondance de type de la visualisation par défaut considérez-la comme celui qui est plus approprié.Otherwise, the expression *(CFrameworkElement*)this causes the CPanel visualization to be applied again because the default visualization type matching rules consider it the most appropriate one. À l’aide de la nd spécificateur de format indique au débogueur d’utiliser la visualisation de la classe de base ou l’expansion par défaut de la classe de base si la classe de base n’a pas une visualisation.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.

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

Expansion de l'élément SyntheticSynthetic Item expansion

Alors que l'élément ExpandedItem offre une vue plus plate des données en éliminant les hiérarchies, le nœud Synthetic fait exactement le contraire.Where the ExpandedItem element provides a flatter view of data by eliminating hierarchies, the Synthetic node does the opposite. Il vous permet de créer un élément enfant artificiel (c'est-à-dire, un élément enfant qui n'est pas le résultat d'une expression).It allows you to create an artificial child element (that is, a child element that is not a result of an expression). Cet élément enfant peut contenir ses propres éléments enfants.This child element can contain children elements of its own. Dans l'exemple suivant, la visualisation du type Concurrency::array utilise un nœud Synthetic pour présenter un message de diagnostic à l'utilisateur :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>  

Concurrence::tableau avec expansion d’élément synthétiqueConcurrency::Array with Synthetic element expansion

HResultHResult

L'élément HResult vous permet de personnaliser les informations affichées pour un HRESULT dans les fenêtres du débogueur.The HResult element enables you to customize the information that is displayed for an HRESULT in debugger windows. L'élément HRValue doit contenir la valeur 32 bits du HRESULT à personnaliser.The HRValue element must contain the 32-bit value of the HRESULT that is to be customized. L'élément HRDescription contient les informations affichées dans le débogueur.The HRDescription element contains the information that is displayed in the debugger.


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

UIVisualizerUIVisualizer

Un élément UIVisualizer permet d'inscrire un plug-in de visualiseur graphique auprès du débogueur.A UIVisualizer element registers a graphical visualizer plug-in with the debugger. Un plug-in de visualiseur graphique crée une boîte de dialogue ou une autre interface pour afficher une variable ou un objet de manière appropriée par rapport à son type de données.A graphical visualizer plug-in creates a dialog box or another interface to display a variable or object in a manner that is appropriate to its data type. Il doit être créé en tant que VSPackage et il doit exposer un service consommable par le débogueur.The visualizer plug-in must be authored as a VSPackage and needs to expose a service that can be consumed by the debugger. Le fichier .natvis contient les informations d’inscription du plug-in, comme son nom, le GUID du service exposé et les types qu’il peut visualiser.The .natvis file contains registration information for the plug-in such as its name, the GUID of the service exposed, and also the types it can visualize.

Voici un exemple d'élément UIVisualizer :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>  

Un élément UIVisualizer est identifié par une paire d’attributs ServiceId - Id .A UIVisualizer is identified by a ServiceId - Id attribute pair. ServiceId correspond au GUID du service exposé par le package du visualiseur. Id correspond à un identificateur unique pouvant servir à différencier les visualiseurs si un service en propose plusieurs.ServiceId is the GUID of the service exposed by the visualizer package, Id is a unique identifier that can be used to differentiate visualizers if a service provides more than one visualizer. Dans l'exemple ci-dessus, le même service de visualiseur fournit deux visualiseurs.In the example above, the same visualizer service provides two visualizers.

L'attribut MenuName correspond au nom du visualiseur que voient les utilisateurs quand ils ouvrent le menu contextuel situé en regard de l'icône de loupe dans les fenêtres de variables du débogueur, comme dans cet exemple :The MenuName attribute is what the users see as the name of the visualizer when they open the drop-down menu next to the magnifying glass icon in the debugger variable windows, for example:

Menu contextuel du menu UIVisualizerUIVisualizer menu shortcut menu

Chaque type défini dans le fichier .natvis doit explicitement répertorier les visualiseurs d’interface utilisateur capables de l’afficher.Each type defined in the .natvis file must explicitly list the UI visualizers that can display them. Le débogueur associe les références de visualiseur incluses dans les entrées de type aux types avec les visualiseurs inscrits.The debugger matches the visualizer references in the type entries to match types with the registered visualizers. Par exemple, ce qui suit tapez entrée pour std::vector fait référence au UIVisualizer dans notre exemple précédent.For example, the following type entry for std::vector references the UIVisualizer in our preceding example.

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

Vous pouvez voir un exemple de UIVisualizer dans l’extension Image Watch utilisée pour afficher des images bitmap en mémoire : ImageWatchYou can see an example of the UIVisualizer in the Image Watch extension used to view in-memory bitmaps: ImageWatch

Élément CustomVisualizerCustomVisualizer element

CustomVisualizer est un point d'extensibilité qui spécifie une extension VSIX que vous pouvez écrire pour contrôler la visualisation dans le code qui s'exécute dans Visual Studio.CustomVisualizer is an extensibility point that specifies a VSIX extension that you can write to control the visualization in code that runs in Visual Studio. Pour plus d’informations sur l’écriture d’extensions VSIX, consultez Visual Studio SDK.For more information about writing VSIX extensions, see Visual Studio SDK. Écriture d’un visualiseur personnalisé est beaucoup plus de travail que l’écriture d’une définition natvis XML, mais vous êtes libre de toute contrainte relative à ce que natvis prend en charge ou ne prend en charge.Writing a custom visualizer is a lot more work than writing an XML natvis definition, but you are free from constraints about what natvis supports or doesn't support. Les visualiseurs personnalisés ont accès à l'ensemble des API d'extensibilité du débogueur, qui peuvent être utilisées pour interroger et modifier le processus du programme débogué ou pour communiquer avec d'autres parties de Visual Studio.Custom visualizers have access to the full set of debugger extensibility APIs, which can be used to query and modify the debuggee process or communicate with other parts of Visual Studio.

Vous pouvez utiliser les attributs Condition, IncludeViewet ExcludeView sur les éléments CustomVisualizer.You can use the Condition, IncludeView, and ExcludeView attributes on CustomVisualizer elements.