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

Enumerating the constants

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

If the retrieved type info is of type TKIND_ENUM or TKIND_MODULE, the cvars member of the TYPEATTR structure ( https://msdn.microsoft.com/en-us/library/windows/desktop/ms221003(v=vs.85).aspx ) contains the number of variables and the GetVarDesc method of the ITypeInfo interface retrieves a VARDESC structure ( https://msdn.microsoft.com/en-us/library/windows/desktop/ms221391(v=vs.85).aspx ) that describes the specified variable.

 

' =====================================================================================

' Retrieves information about constants

' =====================================================================================

FUNCTION CParseTypeLib.GetConstants (BYVAL pTypeInfo AS Afx_ITypeInfo PTR, BYVAL pTypeAttr AS TYPEATTR PTR, BYVAL hTreeView AS HWND, BYVAL hSubNode AS HTREEITEM) AS HRESULT

 

 DIM hr AS HRESULT                      ' // HRESULT

 DIM x AS LONG                          ' // Loop counter

 DIM pVarDesc AS VARDESC PTR            ' // Pointer to a VARDESC structure

 DIM ptdesc AS TYPEDESC PTR             ' // Pointer to a TYPEDESC structure

 DIM cbstrName AS CBSTR                 ' // Name

 DIM vtPtr AS tagVARIANT PTR            ' // Pointer to a tagVARIANT structure

 DIM cbstrTypeKind AS CBSTR             ' // Type kind

 DIM cbstrValue AS CBSTR                ' // Value

 DIM bstrLen AS LONG                    ' // Length of the unicode string

 DIM wstrLen AS LONG                    ' // Length of the null-terminated unicode string

 DIM hSubNode2 AS HTREEITEM             ' // Sub node handle

 

 IF pTypeInfo = NULL OR pTypeAttr = NULL THEN RETURN E_INVALIDARG

 

 FOR x = 0 TO pTypeAttr->cVars - 1

    hr = pTypeInfo->GetVarDesc(x, @pVarDesc)

    IF hr <> S_OK OR pVarDesc = NULL THEN EXIT FOR

    cbstrName.Clear

    pTypeInfo->GetDocumentation(pVarDesc->memid, @cbstrName, NULL, NULL, NULL)

    ' // Some components use spaces in the names of enumeration members!

    IF INSTR(**cbstrName, " ") THEN

       cbstrName = AfxStrReplace(cbstrName, " ", "_")

    END IF

    ' // Pointer to the variant that stores the value of the constant

    vtPtr = pVarDesc->lpvarvalue

    ' // Gets the value of the constant

    cbstrValue.Clear : cbstrTypeKind.Clear

    cbstrValue = AfxVarToBstr(vtPtr)

    cbstrTypeKind = TLB_VarTypeToConstant(pVarDesc->elemdescVar.tdesc.vt)

    SELECT CASE pVarDesc->elemdescVar.tdesc.vt

       CASE VT_I1, VT_UI1, VT_I2, VT_UI2, VT_I4, VT_UI4, VT_INT, VT_UINT

          cbstrValue = **cbstrValue & "   ' (&h" & HEX(VAL(**cbstrValue), 8) & ")"

       CASE VT_BSTR, VT_LPSTR, VT_LPWSTR

          ' // cdosys.dll contains VT_BSTR constants

          cbstrValue = CHR(34) & **cbstrValue & CHR(34)

       CASE VT_PTR

          ptdesc = pVarDesc->elemdescVar.tdesc.lptdesc

          IF ptdesc THEN

             ' WORD PTR (null terminated unicode string)

             ' hxds.dll contains a module with these kind of constants.

             IF ptdesc->vt = VT_UI2 THEN cbstrValue = CHR(34) & **cbstrValue & CHR(34)

          END IF

       ' // Other types can be VT_CARRAY and VT_USERDEFINED, but don't have a typelib to test

    END SELECT

    hSubNode2 = TreeView_AddItem(hTreeView, hSubNode, NULL, **cbstrName & " = " & **cbstrValue)

    TreeView_AddItem(hTreeView, hSubNode2, NULL, "TYPE = " & cbstrTypeKind)

    TreeView_AddItem(hTreeView, hSubNode2, NULL, "VALUE = " & cbstrValue)

    TreeView_AddItem(hTreeView, hSubNode2, NULL, "ID = " & WSTR(pVarDesc->memid))

    TreeView_Expand(hTreeView, hSubNode, TVE_EXPAND)

    pTypeInfo->ReleaseVarDesc(pVarDesc)

    pVarDesc = NULL

 NEXT

 

 IF pVarDesc THEN pTypeInfo->ReleaseVarDesc(pVarDesc)

 

END FUNCTION

' =====================================================================================

 

Modules can also contain string constants and declarations of functions and procedures of external DLLs. This is covered by the following code in the GetFunctions method.

 

hr = pTypeInfo->GetDllEntry(pFuncDesc->memid, pFuncDesc->invkind, @cbstrDllName, @cbstrEntryPoint, @wOrdinal)

IF hr = S_OK THEN

 IF LEN(cbstrDllName) THEN TreeView_AddItem(hTreeView, hSubNode2, NULL, "DLL name = " & cbstrDllName)

 IF LEN(cbstrEntryPoint) THEN TreeView_AddItem(hTreeView, hSubNode2, NULL, "Entry point = " & cbstrEntryPoint)

 IF wOrdinal THEN TreeView_AddItem(hTreeView, hSubNode2, NULL, "Ordinal = " & WSTR(wOrdinal))

END IF