共用方式為


將程式庫提供的符號清單公開至物件管理員

符號瀏覽工具、類別檢視物件瀏覽器呼叫瀏覽器尋找符號結果會將對新資料的請求傳遞給 Visual Studio 物件管理。 物件管理員找到適當的程式庫,並要求新的符號清單。 程式庫透過 IVsSimpleObjectList2 介面向 Visual Studio 物件管理員提供要求資料來回應。 Visual Studio 物件管理員呼叫 IVsSimpleObjectList2 介面中的方法來取得資料,並使用它來填入或更新符號瀏覽工具的檢視。

叫用工具、展開節點或重新整理檢視時,程式庫可能會收到資料要求。 第一次叫用符號瀏覽工具時,物件管理員會要求程式庫提供最上層清單。 當使用者展開清單節點時,程式庫會提供該節點下的子系清單。 每個物件管理員查詢都包含感興趣項目的索引。 若要顯示新的清單,物件管理員必須判斷清單中的項目數、項目類型、其名稱、協助工具和其他屬性。

注意

下列 Managed 程式碼範例示範如何透過實作 IVsSimpleObjectList2 介面來提供符號清單。 物件管理員呼叫這個介面中的方法,並使用取得的資料來填入或更新符號瀏覽工具。

對於原生程式碼符號提供者實作,請使用 IVsObjectList2 介面。

提供物件管理員的符號清單

  1. 藉由實作 GetItemCount 方法來取得符號清單中的項目數。 以下範例示範物件管理員如何取得清單中項目數的相關資訊。

    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. 藉由實作 GetCategoryField2 方法來取得指定清單項目類別和屬性的相關資訊。 LIB_CATEGORY 列舉中指定項目類別。 下列範例示範物件管理員如何取得指定類別的項目屬性。

    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. 藉由實作 GetTextWithOwnership 方法來取得指定清單項目的文字表示。 下列範例示範如何取得指定項目的完整名稱。

    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. 藉由實作 GetDisplayData 方法來取得指定清單項目的圖示資訊。 圖示表示清單項目的類型 (類別、方法等),以及清單項目的協助工具 (私用、公用等)。 下列範例示範如何根據指定的項目屬性取得圖示資訊。

    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. 藉由實作 GetExpandable3 方法來取得指定清單項目是否可展開的資訊。 下列範例示範如何取得指定項目是否可以擴展的資訊。

    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. 藉由實作 GetList2 方法來取得指定清單項目的符號子清單。 下列範例示範如何取得呼叫呼叫者圖形指定項目的符號子清單。

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