Condividi tramite


Esporre elenchi di simboli forniti dalla libreria al gestore oggetti

Gli strumenti di esplorazione dei simboli, Visualizzazione classi, Visualizzatore oggetti, Browser chiamate e Risultati dei simboli di ricerca, passano le richieste di nuovi dati al gestore oggetti di Visual Studio. Gestione oggetti trova le librerie appropriate e richiede nuovi elenchi di simboli. Le librerie rispondono fornendo i dati richiesti al gestore oggetti di Visual Studio tramite l'interfaccia IVsSimpleObjectList2 . Gestione oggetti di Visual Studio chiama i metodi nell'interfaccia IVsSimpleObjectList2 per ottenere i dati e lo usa per popolare o aggiornare le visualizzazioni degli strumenti di esplorazione dei simboli.

Una libreria può ricevere richieste di dati quando viene richiamato lo strumento, il nodo viene espanso o la visualizzazione viene aggiornata. Quando viene richiamato per la prima volta uno strumento di esplorazione dei simboli, il gestore oggetti richiede alla libreria di fornire l'elenco di primo livello. Quando l'utente espande un nodo elenco, la libreria fornisce un elenco di elementi figlio in tale nodo. Ogni richiesta di gestione oggetti contiene un indice dell'elemento di interesse. Per visualizzare un nuovo elenco, il gestore oggetti deve determinare il numero di elementi presenti nell'elenco, il tipo di elementi, i nomi, l'accessibilità e altre proprietà.

Nota

Gli esempi di codice gestito seguenti illustrano come fornire elenchi di simboli tramite l'implementazione dell'interfaccia IVsSimpleObjectList2 . Gestione oggetti chiama i metodi in questa interfaccia e usa i dati ottenuti per popolare o aggiornare gli strumenti di esplorazione dei simboli.

Per l'implementazione del provider di simboli di codice nativo, usare l'interfaccia IVsObjectList2 .

Per fornire elenchi di simboli al gestore oggetti

  1. Ottenere il numero di elementi nell'elenco dei simboli implementando il GetItemCount metodo . Nell'esempio seguente viene illustrato come il gestore oggetti ottiene le informazioni sul numero di elementi nell'elenco.

    protected System.Collections.Generic.SortedList<string, Method> m_Methods = new System.Collections.Generic.SortedList<string, Method>();
    
    public int GetItemCount(out uint pCount)
    {
        pCount = (uint)m_Methods.Count;
        return Microsoft.VisualStudio.VSConstants.S_OK;
    }
    
    
  2. Ottenere informazioni sulle categorie e sugli attributi di una determinata voce di elenco implementando il GetCategoryField2 metodo . Le categorie di elementi vengono specificate nell'enumerazione LIB_CATEGORY . Nell'esempio seguente viene illustrato come il gestore oggetti ottiene gli attributi degli elementi per una determinata categoria.

    public int GetCategoryField2(uint index, int Category, out uint pfCatField)
    {
        pfCatField = 0;
    
        switch ((LIB_CATEGORY)Category)
        {
            case LIB_CATEGORY.LC_MEMBERTYPE:
                pfCatField = (uint)_LIBCAT_MEMBERTYPE.LCMT_METHOD;
                break;
    
            case LIB_CATEGORY.LC_MEMBERACCESS:
                {
                    Method method = m_Methods.Values[(int)index];
    
                    if (method.IsPublic)
                    {
                        pfCatField = (uint)_LIBCAT_MEMBERACCESS.LCMA_PUBLIC;
                    }
                    else if (method.IsPrivate)
                    {
                        pfCatField = (uint)_LIBCAT_MEMBERACCESS.LCMA_PRIVATE;
                    }
                    else if (method.IsFamily)
                    {
                        pfCatField = (uint)_LIBCAT_MEMBERACCESS.LCMA_PROTECTED;
                    }
                    else if (method.IsFamilyOrAssembly)
                    {
                        pfCatField = (uint)_LIBCAT_MEMBERACCESS.LCMA_PROTECTED |
                                     (uint)_LIBCAT_MEMBERACCESS.LCMA_PACKAGE;
                    }
                    else
                    {
                        // Show everything else as internal.
                        pfCatField = (uint)_LIBCAT_MEMBERACCESS.LCMA_PACKAGE;
                    }
                }
                break;
    
            case LIB_CATEGORY.LC_VISIBILITY:
                pfCatField = (uint)_LIBCAT_VISIBILITY.LCV_VISIBLE;
                break;
    
            case LIB_CATEGORY.LC_LISTTYPE:
                pfCatField = (uint)_LIB_LISTTYPE.LLT_MEMBERS;
                break;
    
            default:
                return Microsoft.VisualStudio.VSConstants.S_FALSE;
        }
        return Microsoft.VisualStudio.VSConstants.S_OK;
    }
    
    
  3. Ottenere la rappresentazione testuale di una determinata voce di elenco implementando il GetTextWithOwnership metodo . Nell'esempio seguente viene illustrato come ottenere un nome completo di un determinato elemento.

    public int GetTextWithOwnership([System.Runtime.InteropServices.ComAliasNameAttribute("Microsoft.VisualStudio.OLE.Interop.ULONG")] uint index, [System.Runtime.InteropServices.ComAliasNameAttribute("Microsoft.VisualStudio.Shell.Interop.VSTREETEXTOPTIONS")] Microsoft.VisualStudio.Shell.Interop.VSTREETEXTOPTIONS tto, [System.Runtime.InteropServices.ComAliasNameAttribute("Microsoft.VisualStudio.OLE.Interop.WCHAR")] out string ppszText)
    {
        ppszText = m_Methods.Values[(int)index].FullName;
        return Microsoft.VisualStudio.VSConstants.S_OK;
    }
    
    
  4. Ottenere le informazioni sull'icona per una determinata voce di elenco implementando il GetDisplayData metodo . L'icona rappresenta il tipo (classe, metodo e così via) e l'accessibilità (privato, pubblico e così via) di una voce di elenco. Nell'esempio seguente viene illustrato come ottenere le informazioni sull'icona in base a un determinato attributo di elemento.

    public virtual int GetDisplayData(uint index, Microsoft.VisualStudio.Shell.Interop.VSTREEDISPLAYDATA[] pData)
    {
        if (pData == null)
        {
            return Microsoft.VisualStudio.VSConstants.E_INVALIDARG;
        }
    
        Method method = m_Methods.Values[(int)index];
    
        int iImage = 12 * 6;    // See env\inc\OMGlyphs.h.
    
        const int OM_GLYPH_ACC_PUBLIC = 0;
        const int OM_GLYPH_ACC_INTERNAL = 1;
        const int OM_GLYPH_ACC_PROTECTED = 3;
        const int OM_GLYPH_ACC_PRIVATE = 4;
    
        if (method.IsPublic)
        {
            iImage += OM_GLYPH_ACC_PUBLIC;
        }
        else if (method.IsPrivate)
        {
            iImage += OM_GLYPH_ACC_PRIVATE;
        }
        else if (method.IsFamily)
        {
            iImage += OM_GLYPH_ACC_PROTECTED;
        }
        else if (method.IsFamilyOrAssembly)
        {
            iImage += OM_GLYPH_ACC_PROTECTED;
        }
        else
        {
            iImage += OM_GLYPH_ACC_INTERNAL;
        }
    
        pData[0].Image = (ushort)iImage;
        pData[0].SelectedImage = (ushort)iImage;
    
        return Microsoft.VisualStudio.VSConstants.S_OK;
    }
    
    
  5. Ottenere le informazioni su se una determinata voce di elenco è espandibile implementando il GetExpandable3 metodo . Nell'esempio seguente viene illustrato come ottenere le informazioni su se un determinato elemento può essere espanso.

    public int GetExpandable(uint index, out int pfExpandable)
    {
        pfExpandable = Microsoft.VisualStudio.VSIP.Samples.CallBrowser.Constants.TRUE;
        return Microsoft.VisualStudio.VSConstants.S_OK;
    }
    
    public int GetExpandable3(uint index, uint ListTypeExcluded, out int pfExpandable)
    {
        return GetExpandable(index, out pfExpandable);
    }
    
    
  6. Ottenere un elenco figlio di simboli di una determinata voce di elenco implementando il GetList2 metodo . Nell'esempio seguente viene illustrato come ottenere un elenco figlio di simboli di un determinato elemento per i grafici Call o Callers .

    // Call graph list.
    public class CallsList :
        ResultsList,
        Microsoft.VisualStudio.Shell.Interop.IVsSimpleObjectList2
    {
        public CallsList(Library library) :
            base(library)
        {
        }
    
        public int GetList2(uint index, uint ListType, uint flags, Microsoft.VisualStudio.Shell.Interop.VSOBSEARCHCRITERIA2[] pobSrch, out Microsoft.VisualStudio.Shell.Interop.IVsSimpleObjectList2 ppList)
        {
            return base.GetCallsList(index, out ppList);
        }
    }
    
    // Callers graph list.
    public class CallersList :
        ResultsList,
        Microsoft.VisualStudio.Shell.Interop.IVsSimpleObjectList2
    {
        public CallersList(Library library) :
            base(library)
        {
        }
    
        public int GetList2(uint index, uint ListType, uint flags, Microsoft.VisualStudio.Shell.Interop.VSOBSEARCHCRITERIA2[] pobSrch, out Microsoft.VisualStudio.Shell.Interop.IVsSimpleObjectList2 ppList)
        {
            return base.GetCallersList(index, out ppList);
        }
    }
    
    // Call graph list.
    public int GetCallsList(uint index, out Microsoft.VisualStudio.Shell.Interop.IVsSimpleObjectList2 ppList)
    {
        ppList = null;
        ResultsList callsList = new CallsList(m_Library);
    
        Method method = m_Methods.Values[(int)index];
        string strMethod = method.m_strPrototype;
    
        System.Collections.Generic.List<CallInstance> Calls = m_Library.CallGraph.GetCallGraph(method);
    
        for (int i = 0; i < Calls.Count; i++)
        {
            Method caller = Calls[i].m_Target;
            callsList.AddMethod(caller);
        }
    
        ppList = (Microsoft.VisualStudio.Shell.Interop.IVsSimpleObjectList2)(callsList);
        return Microsoft.VisualStudio.VSConstants.S_OK;
    }
    
    // Callers graph list.
    public int GetCallersList(uint index, out Microsoft.VisualStudio.Shell.Interop.IVsSimpleObjectList2 ppList)
    {
        ppList = null;
        ResultsList callersList = new CallersList(m_Library);
    
        Method method = m_Methods.Values[(int)index];
        string strMethod = method.m_strPrototype;
    
        System.Collections.Generic.List<CallInstance> Callers = m_Library.CallGraph.GetCallersGraph(method);
    
        for (int i = 0; i < Callers.Count; i++)
        {
            Method caller = Callers[i].m_Source;
            callersList.AddMethod(caller);
        }
    
        ppList = (Microsoft.VisualStudio.Shell.Interop.IVsSimpleObjectList2)(callersList);
        return Microsoft.VisualStudio.VSConstants.S_OK;
    }
    
    // Get a child list of symbols for a given list item.
    public int GetList2(uint index, uint ListType, uint flags, Microsoft.VisualStudio.Shell.Interop.VSOBSEARCHCRITERIA2[] pobSrch, out Microsoft.VisualStudio.Shell.Interop.IVsSimpleObjectList2 ppList)
    {
        ppList = null;
    
        Method method = m_Methods.Values[(int)index];
        string strMethod = method.m_strPrototype;
    
        // Determine if the list belongs to Call or Callers graphs.
        if ((uint)(m_nFlags & (uint)Microsoft.VisualStudio.Shell.Interop._VSOBSEARCHOPTIONS2.VSOBSO_CALLSFROM) > 0)
        {
            // Build the list for the Call graph.
            return base.GetCallsList(index, out ppList);
        }
        else if ((uint)(m_nFlags & (uint)Microsoft.VisualStudio.Shell.Interop._VSOBSEARCHOPTIONS2.VSOBSO_CALLSTO) > 0)
        {
            // Build the list for the Callers graph.
            return base.GetCallersList(index, out ppList);
        }
    
        return Microsoft.VisualStudio.VSConstants.E_FAIL;
    }