Udostępnij za pośrednictwem


Uwidaczniaj listy symboli dostarczonych przez bibliotekę do menedżera obiektów

Narzędzia przeglądania symboli, widok klas, przeglądarka obiektów, przeglądarka wywołań i wyniki wyszukiwania symboli, przekazują żądania dotyczące nowych danych do menedżera obiektów programu Visual Studio. Menedżer obiektów znajduje odpowiednie biblioteki i żąda nowych list symboli. Biblioteki odpowiadają, dostarczając żądane dane do menedżera obiektów programu Visual Studio za pośrednictwem interfejsu IVsSimpleObjectList2 . Menedżer obiektów programu Visual Studio wywołuje metody w IVsSimpleObjectList2 interfejsie w celu uzyskania danych i używa ich do wypełniania lub aktualizowania widoków narzędzi przeglądania symboli.

Biblioteka może pobierać żądania dotyczące danych po wywołaniu narzędzia, rozwinięciu węzła lub odświeżeniu widoku. Gdy narzędzie przeglądania symboli jest wywoływane po raz pierwszy, menedżer obiektów żąda biblioteki, aby udostępnić listę najwyższego poziomu. Gdy użytkownik rozwija węzeł listy, biblioteka udostępnia listę elementów podrzędnych w tym węźle. Każde zapytanie menedżera obiektów zawiera indeks interesującego elementu. Aby wyświetlić nową listę, menedżer obiektów musi określić, ile elementów znajduje się na liście, typ elementów, ich nazwy, ułatwienia dostępu i inne właściwości.

Uwaga

W poniższych przykładach kodu zarządzanego pokazano, jak udostępnić listy symboli za pomocą implementowania interfejsu IVsSimpleObjectList2 . Menedżer obiektów wywołuje metody w tym interfejsie i używa uzyskanych danych do wypełniania lub aktualizowania narzędzi przeglądania symboli.

W przypadku implementacji dostawcy symboli kodu natywnego użyj interfejsu IVsObjectList2 .

Aby podać listy symboli do menedżera obiektów

  1. Pobierz liczbę elementów na liście symboli, implementując metodę GetItemCount . W poniższym przykładzie pokazano, jak menedżer obiektów uzyskuje informacje o liczbie elementów na liście.

    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. Uzyskaj informacje o kategoriach i atrybutach danego elementu listy, implementując metodę GetCategoryField2 . Kategorie elementów są określone w wyliczenie LIB_CATEGORY . W poniższym przykładzie pokazano, jak menedżer obiektów uzyskuje atrybuty elementów dla danej kategorii.

    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. Pobierz tekstową reprezentację danego elementu listy, implementując metodę GetTextWithOwnership . W poniższym przykładzie pokazano, jak uzyskać pełną nazwę danego elementu.

    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. Uzyskaj informacje o ikonie dla danego elementu listy, implementując metodę GetDisplayData . Ikona reprezentuje typ (klasa, metoda itd.) oraz ułatwienia dostępu (prywatne, publiczne itd.) elementu listy. W poniższym przykładzie pokazano, jak uzyskać informacje o ikonie na podstawie atrybutów danego elementu.

    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. Uzyskaj informacje na temat tego, czy dany element listy można rozwinąć, implementując metodę GetExpandable3 . W poniższym przykładzie pokazano, jak uzyskać informacje na temat tego, czy dany element można rozszerzyć.

    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. Pobierz podrzędną listę symboli danego elementu listy, implementując metodę GetList2 . W poniższym przykładzie pokazano, jak uzyskać podrzędną listę symboli danego elementu dla wykresów Wywołanie lub Osoby wywołujące .

    // 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;
    }