Vues à onglet unique et onglets multiples

Un éditeur peut créer différents types de vues. Un exemple est une fenêtre d’éditeur de code, une autre est un concepteur de formulaires.

Une vue à plusieurs onglets est une vue qui a plusieurs onglets. Par exemple, l’éditeur HTML a deux onglets en bas : Création et source, chacun d’eux une vue logique. L’affichage création affiche une page web rendue, tandis que l’autre affiche le code HTML qui comprend la page web.

Accès aux vues physiques

Les vues physiques hébergent des objets d’affichage de document, chacun représentant une vue des données dans la mémoire tampon, comme le code ou un formulaire. En conséquence, chaque objet d’affichage de document a une vue physique (identifiée par un élément appelé chaîne d’affichage physique) et généralement une vue logique unique.

Dans certains cas, toutefois, une vue physique peut avoir deux vues logiques ou plus. Voici quelques exemples d’éditeur qui a une fenêtre fractionnée avec des vues côte à côte, ou un concepteur de formulaires qui a un affichage GUI/conception et un affichage code-behind-the-form.

Pour permettre à votre éditeur d’accéder à toutes les vues physiques disponibles, vous devez créer une chaîne d’affichage physique unique pour chaque type d’objet d’affichage de document que votre fabrique d’éditeur peut créer. Par exemple, la fabrique de l’éditeur Visual Basic peut créer des objets d’affichage de document pour une fenêtre de code et une fenêtre du concepteur de formulaires.

Création de vues à onglets multiples

Bien qu’un objet d’affichage de document doit être associé à une vue physique via une chaîne d’affichage physique unique, vous pouvez placer plusieurs onglets dans la vue physique pour permettre l’affichage des données de différentes façons. Dans cette configuration à plusieurs onglets, tous les onglets sont associés à la même chaîne d’affichage physique, mais chaque onglet reçoit un GUID d’affichage logique différent.

Pour créer une vue à plusieurs onglets pour un éditeur, implémentez l’interface IVsMultiViewDocumentView , puis associez un GUID d’affichage logique différent (LogicalViewID) à chaque onglet que vous créez.

L’éditeur HTML Visual Studio est un exemple d’éditeur avec une vue à plusieurs onglets. Il comporte des onglets Création et Source . Pour l’activer, une vue logique différente est associée à chaque onglet, LOGICALVIEWID_TextView pour l’onglet Création et LOGICALVIEWID_Code pour l’onglet Source .

En spécifiant la vue logique appropriée, un VSPackage peut accéder à la vue qui correspond à un objectif particulier, comme la conception d’un formulaire, la modification de code ou le code de débogage. Toutefois, l’une des fenêtres doit être identifiée par la chaîne NULL et cela doit correspondre à la vue logique principale (LOGVIEWID_Primary).

Le tableau suivant répertorie les valeurs d’affichage logique disponibles et leur utilisation.

LOGVIEWID GUID Utilisation recommandée
LOGVIEWID_Primary Vue par défaut/principale de la fabrique de l’éditeur.

Toutes les fabriques d’éditeur doivent prendre en charge cette valeur. Cette vue doit utiliser la chaîne NULL comme chaîne d’affichage physique. Au moins une vue logique doit être définie sur cette valeur.
LOGVIEWID_Debugging Mode Débogage. En règle générale, LOGVIEWID_Debugging mappe à la même vue que LOGVIEWID_Code.
LOGVIEWID_Code Vue lancée par la commande Afficher le code .
LOGVIEWID_Designer Vue lancée par la commande Afficher le formulaire .
LOGVIEWID_TextView Affichage de l’éditeur de texte. Il s’agit de la vue qui retourne IVsCodeWindow, à partir de laquelle vous pouvez accéder IVsTextView.
LOGVIEWID_UserChooseView Invite l’utilisateur à choisir l’affichage à utiliser.
LOGVIEWID_ProjectSpecificEditor Passé par la boîte de dialogue Ouvrir avec à

OpenItem

lorsque l’utilisateur choisit l’entrée « (Éditeur par défaut du projet) ».

Bien que les GUID d’affichage logique soient extensibles, vous ne pouvez utiliser que les GUID d’affichage logique définis dans votre VSPackage.

Lors de l’arrêt, Visual Studio conserve le GUID de la fabrique de l’éditeur et les chaînes d’affichage physique associées à la fenêtre de document afin qu’elle puisse être utilisée pour rouvrir les fenêtres de document lorsque la solution est réinitondure. Seules les fenêtres ouvertes lorsqu’une solution est fermée sont conservées dans le fichier solution (.suo). Ces valeurs correspondent aux VSFPROPID_guidEditorTypeVSFPROPID_pszPhysicalView valeurs passées dans le propid paramètre de la GetProperty méthode.

Exemple

Cet extrait de code illustre la façon dont l’objet TextView est utilisé pour accéder à une vue qui implémente IVsCodeWindow. Dans ce cas, le SVsUIShellOpenDocument service est utilisé pour appeler OpenDocumentViaProject et demander LOGVIEWID_TextView, qui obtient un pointeur vers un cadre de fenêtre. Un pointeur vers l’objet d’affichage de document est obtenu en appelant GetProperty et en spécifiant une valeur de VSFPROPID_DocView. À partir de l’objet d’affichage de document, QueryInterface est appelé pour IVsCodeWindow. L’attente dans ce cas est qu’un éditeur de texte est retourné, et donc l’objet d’affichage de document retourné dans la GetProperty méthode est une fenêtre de code.

HRESULT CFindTool::GotoFileLocation(const WCHAR * szFile, long iLine, long iStart, long iLen)
{
  HRESULT hr;
  if (NULL == szFile || !*szFile)
    return E_INVALIDARG;

  if (iLine == -1L)
    return S_FALSE;

  VSITEMID                  itemid;
  VARIANT                   var;
  RECT                      rc;
  IVsUIShellOpenDocument *  pOpenDoc    = NULL;
  IVsCodeWindow *           pCodeWin    = NULL;
  IVsTextView *             pTextView   = NULL;
  IVsUIHierarchy *          pHierarchy  = NULL;
  IVsWindowFrame *          pFrame      = NULL;
  IUnknown *                pUnk        = NULL;
  IVsHighlight *            pHighlight  = NULL;

  IfFailGo(CGlobalServiceProvider::HrQueryService(SID_SVsUIShellOpenDocument, IID_IVsUIShellOpenDocument, (void **)&pOpenDoc));
  IfFailGo(pOpenDoc->OpenDocumentViaProject(szFile, LOGVIEWID_TextView, NULL, &pHierarchy, &itemid, &pFrame));
  pFrame->Show();
  VariantInit(&var);
  IfFailGo(pFrame->GetProperty(VSFPROPID_DocView, &var));
  if (VT_UNKNOWN != var.vt) { hr = E_FAIL; goto Error; }
  pUnk = V_UNKNOWN(&var);
  if (NULL != pUnk)
  {
    IfFailGo(pUnk->QueryInterface(IID_IVsCodeWindow, (void **)&pCodeWin));
    if (SUCCEEDED(hr = pCodeWin->GetLastActiveView(&pTextView)) ||
        SUCCEEDED(hr = pCodeWin->GetPrimaryView(&pTextView)) )
    {
      pTextView->SetSelection(iLine, iStart, iLine, iStart + iLen);
      // uncover selection
      IfFailGo(pTextView->QueryInterface(IID_IVsHighlight, (void**)&pHighlight));
      IfFailGo(SUCCEEDED(pHighlight->GetHighlightRect(&rc)));
      UncoverSelectionRect(&rc);
    }
  }

Error:
  CLEARINTERFACE(pHighlight);
  CLEARINTERFACE(pTextView);
  CLEARINTERFACE(pCodeWin);
  CLEARINTERFACE(pUnk);
  CLEARINTERFACE(pFrame);
  CLEARINTERFACE(pOpenDoc);
  CLEARINTERFACE(pHierarchy);
  RedrawWindow(m_hwndResults, NULL, NULL, RDW_ERASE|RDW_FRAME|RDW_INVALIDATE|RDW_ALLCHILDREN);
  return hr;
}