导航:  COM (Component Object Model) > The making of a type library browser >

Parsing the information

上一页返回章节概述下一页

To parse the type library information we need to call the methods of the ITypeInfo interface.

 

This is my definition of that interface:

 

' ########################################################################################

' Interface name = ITypeInfo

' Extracts information about the characteristics and capabilities of objects from type libraries.

' Inherited interface = IUnknown

' ########################################################################################

 

TYPE Afx_ITypeInfo AS Afx_ITypeInfo_

 

#ifndef __Afx_ITypeInfo_INTERFACE_DEFINED__

#define __Afx_ITypeInfo_INTERFACE_DEFINED__

 

TYPE Afx_ITypeInfo_ EXTENDS Afx_IUnknown

 DECLARE ABSTRACT FUNCTION GetTypeAttr (BYVAL ppTypeAttr AS TYPEATTR PTR PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetTypeComp (BYVAL ppTComp AS ITypeComp PTR PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetFuncDesc (BYVAL index AS UINT, BYVAL ppFuncDesc AS FUNCDESC PTR PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetVarDesc (BYVAL index AS UINT, BYVAL ppVarDesc AS VARDESC PTR PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetNames (BYVAL memid AS MEMBERID, BYVAL rgBstrNames AS AFX_BSTR PTR, BYVAL cMaxNames AS UINT, BYVAL pcNames AS UINT PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetRefTypeOfImplType (BYVAL index AS UINT, BYVAL pRefType AS HREFTYPE PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetImplTypeFlags (BYVAL index AS UINT, BYVAL pImplTypeFlags AS INT_ PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetIDsOfNames (BYVAL rgszNames AS LPOLESTR PTR, BYVAL cNames AS UINT, BYVAL pMemId AS MEMBERID PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION Invoke (BYVAL pvInstance AS PVOID, BYVAL memid AS MEMBERID, BYVAL wFlags AS WORD, BYVAL pDispParams AS DISPPARAMS PTR, BYVAL pVarResult AS VARIANT PTR, BYVAL pExcepInfo AS EXCEPINFO PTR, BYVAL puArgErr AS UINT PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetDocumentation (BYVAL memid AS MEMBERID, BYVAL pBstrName AS AFX_BSTR PTR, BYVAL pBstrDocString AS AFX_BSTR PTR, BYVAL pdwHelpContext AS DWORD PTR, BYVAL pBstrHelpFile AS AFX_BSTR PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetDllEntry (BYVAL memid AS MEMBERID, BYVAL invKind AS INVOKEKIND, BYVAL pBstrDllName AS AFX_BSTR PTR, BYVAL pBstrName AS AFX_BSTR PTR, BYVAL pwOrdinal AS WORD PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetRefTypeInfo (BYVAL hRefType AS HREFTYPE, BYVAL ppTInfo AS Afx_ITypeInfo PTR PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION AddressOfMember (BYVAL memid AS MEMBERID, BYVAL invKind AS INVOKEKIND, BYVAL ppv AS PVOID PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION CreateInstance (BYVAL pUnkOuter AS IUnknown PTR, BYVAL riid AS CONST IID CONST PTR, BYVAL ppvObj AS PVOID PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetMops (BYVAL memid AS MEMBERID, BYVAL pBstrMops AS AFX_BSTR PTR) AS HRESULT

 DECLARE ABSTRACT FUNCTION GetContainingTypeLib (BYVAL ppTLib AS Afx_ITypeLib PTR PTR, BYVAL pIndex AS UINT PTR) AS HRESULT

 DECLARE ABSTRACT SUB      ReleaseTypeAttr (BYVAL pTypeAttr AS TYPEATTR PTR)

 DECLARE ABSTRACT SUB      ReleaseFuncDesc (BYVAL pFuncDesc AS FUNCDESC PTR)

 DECLARE ABSTRACT SUB      ReleaseVarDesc (BYVAL pVarDesc AS VARDESC PTR)

END TYPE

 

#endif

 

To extract the type library information first wee need to rerieve how many TypeInfos it contains:

 

 ' // Retrieves the number of TypeInfos

 TypeInfoCount = m_pTypeLib->GetTypeInfoCount

 IF TypeInfoCount = 0 THEN

    TLB_MsgBox m_pWindow->hWindow, "This TypeLib doesn't have type infos", _

       MB_OK OR MB_ICONERROR OR MB_APPLMODAL, "CParseTypeLib.ParseTypeInfos"

    RETURN S_FALSE

 END IF

 

For each type info we will retrieve the type of a type description, a pointer to its ITypeInfo interface and a pointer to the TYPEATTR structure that contains the attributes of the type description.

 

 FOR i = 0 TO TypeInfoCount - 1

 

    ' // Retrieves the TypeKind

    hr = m_pTypeLib->GetTypeInfoType(i, @pTKind)

    IF hr <> S_OK THEN

       TLB_MsgBox m_pWindow->hWindow, "Error &H" & HEX$(hr, 8) & " retrieving the info type", _

          MB_OK OR MB_ICONERROR OR MB_APPLMODAL, "CParseTypeLib.ParseTypeInfos"

       EXIT FOR

    END IF

 

    ' // Retrieves the ITypeInfo interface

    hr = m_pTypeLib->GetTypeInfo(i, @pTypeInfo)

    IF hr <> S_OK OR pTypeInfo = NULL THEN

       TLB_MsgBox m_pWindow->hWindow, "Error &H" & HEX$(hr, 8) & " retrieving the ITypeInfo interface", _

          MB_OK OR MB_ICONERROR OR MB_APPLMODAL, "CParseTypeLib.ParseTypeInfos"

       EXIT FOR

    END IF

 

    ' // Gets the address of a pointer to the TYPEATTR structure

    hr = pTypeInfo->GetTypeAttr(@pTypeAttr)

    IF hr <> S_OK OR pTypeAttr = NULL THEN

       TLB_MsgBox m_pWindow->hWindow, "Error &H" & HEX$(hr, 8) & " retrieving the address of the TypeAttr structure", _

          MB_OK OR MB_ICONERROR OR MB_APPLMODAL, "CParseTypeLib.ParseTypeInfos"

       EXIT FOR

    END IF

 

    ...

    ...

    ...

 

 NEXT

 

Inside the loop, we will process each block of information separately according its type:

 

    SELECT CASE pTKind

       CASE TKIND_COCLASS   ' // CoClasses

          ...

          ...

          ...

       CASE TKIND_RECORD, TKIND_UNION   ' // Structures and unions

          ...

          ...

          ...

       CASE TKIND_ALIAS   ' // Aliases and typedefs

          ...

          ...

          ...

       CASE TKIND_ENUM, TKIND_MODULE   ' // Enumerations and modules

          ...

          ...

          ...

       CASE TKIND_INTERFACE, TKIND_DISPATCH   ' // Interfaces

          ...

          ...

          ...

    END SELECT