Figures
Figure 4 A Simple ODL Type Library File
[
//Generate the Universal Unique identifier (UUID) with UUID.EXE
uuid(006da100-110f-11cf-83b2-00aa0068851c),

//The Help String is displayed by object browsers
helpstring("API TypeLib"),

//The Locale Identifier (LCID) indicates the language used
lcid(0x9),

//This is the version number of the type library
version(1.0)
]

//The type library's name is displayed by object browsers
library MyAPI
{
  //Indicate where the API function lives
  [dllname("user32.dll")]
  module API
  {
  //The Help String is displayed by object browsers
  [helpstring("API to close a window"), entry("CloseWindow")] boolean

  CloseWindow([in] long hWnd);
  };
}
Figure 5 Partial View of the TLI Object Model

Figure 5 Partial View of the TLI Object Model

Figure 7 Opening and Processing a Type Library
Private Sub Form_Load()
  'Establish some logical settings for common dialog
  cdlTypeLibrary.DialogTitle = "Open Type Library"
  cdlTypeLibrary.InitDir = "d:\winnt\system32\"
  cdlTypeLibrary.Filter = "Type Libraries (*.tlb;*.olb;*.dll;*.ocx)|" _
    "*.tlb;*.olb;*.dll;*.ocx|All Files (*.*)|*.*"

  'Instantiate a global TypeLibInfo object
  Set tliTypeLibInfo = New TypeLibInfo
  tliTypeLibInfo.AppObjString = "<Global>"

  'Miscellaneous initialization
  lvwLibraryInfo.ColumnHeaders(1).Width = lvwLibraryInfo.Width / 4 - 100
  lvwLibraryInfo.ColumnHeaders(2).Width = lvwLibraryInfo.Width * 3 / 4
  lblEntityName = ""
  lblMemberOf = ""
  lblHelpText = ""
  Label3.Visible = False
End Sub

Private Sub mnuFileOpen_Click()
  On Error Resume Next

  'Solicit the user for a type library
  cdlTypeLibrary.ShowOpen
  If Err.Number <> cdlCancel Then
    tliTypeLibInfo.ContainingFile = cdlTypeLibrary.FileName
      If Err.Number = tliErrCantLoadLibrary Then
        MsgBox "The file you selected does not " & _
               "contain valid type library information." & _
               vbCrLf & "Try a file with the extension *.tlb.", _
               vbCritical, "Invalid Type Library"
      Else
        Call ProcessTypeLibrary
      End If
  End If
  On Error Goto 0
End Sub

Public Sub ProcessTypeLibrary()
  frmTypeLibraryExplorer.Caption = "Type Library Explorer - " & _
    tliTypeLibInfo.Name

  'Display general type library information
  lvwLibraryInfo.ListItems.Clear
  lvwLibraryInfo.ListItems.Add , "Name", "Name"
  lvwLibraryInfo.ListItems("Name").SubItems(1) = tliTypeLibInfo.Name
  
  lvwLibraryInfo.ListItems.Add , "File", "File"
  lvwLibraryInfo.ListItems("File").SubItems(1) = _
    LCase(tliTypeLibInfo.ContainingFile)
  
  lvwLibraryInfo.ListItems.Add , "Description", "Description"
  lvwLibraryInfo.ListItems("Description").SubItems(1) = _
    tliTypeLibInfo.HelpString
  
  lvwLibraryInfo.ListItems.Add , "Version", "Version"
  lvwLibraryInfo.ListItems("Version").SubItems(1) = _
    tliTypeLibInfo.MajorVersion & "." & tliTypeLibInfo.MinorVersion
  
  lvwLibraryInfo.ListItems.Add , "HelpFile", "Help File"
  lvwLibraryInfo.ListItems("HelpFile").SubItems(1) = _
    LCase(tliTypeLibInfo.HelpFile)

  lvwLibraryInfo.ListItems.Add , "System", "System"
  Select Case tliTypeLibInfo.SysKind
    Case SYS_MAC:
      lvwLibraryInfo.ListItems("System").SubItems(1) = "Macintosh"
    Case SYS_WIN16:
      lvwLibraryInfo.ListItems("System").SubItems(1) = "Win16"
    Case SYS_WIN32:
      lvwLibraryInfo.ListItems("System").SubItems(1) = "Win32"
  End Select

  lvwLibraryInfo.ListItems.Add , "Guid", "Guid"
  lvwLibraryInfo.ListItems("Guid").SubItems(1) = tliTypeLibInfo.Guid

  'Clear lists
  lstTypeInfos.Clear
  lstMembers.Clear

  'Display members for type library
  tliTypeLibInfo.GetTypesDirect lstTypeInfos.hWnd, , tliStAll
End Sub
Figure 8 The Listbox Event Procedures
Private Sub lstTypeInfos_Click()
  Dim tliTypeInfo As TypeInfo
  Set tliTypeInfo = _
    tliTypeLibInfo.GetTypeInfo(lstTypeInfos.List( _
    lstTypeInfos.ListIndex))
  lblEntityName = lstTypeInfos.[_Default]
  lblMemberOf = "Member of " & tliTypeInfo.Parent
  lblHelpText = tliTypeInfo.HelpString
  txtEntityPrototype = ""

  'Use the ItemData in lstTypeInfos to set the SearchData for lstMembers
  tliTypeLibInfo.GetMembersDirect _
    lstTypeInfos.ItemData(lstTypeInfos.ListIndex), lstMembers.hWnd
End Sub

Private Sub lstMembers_Click()
  Dim tliInvokeKinds As InvokeKinds
  tliInvokeKinds = lstMembers.ItemData(lstMembers.ListIndex)
  lblEntityName = lstMembers.[_Default]
  txtEntityPrototype = _
    PrototypeMember(lstTypeInfos.ItemData(lstTypeInfos.ListIndex), _
    tliInvokeKinds, lstMembers.[_Default])
End Sub
Figure 9 Protoyping a MemberInfo Object
Public Function PrototypeMember(ByVal SearchData As Long, _
  ByVal InvokeKinds As InvokeKinds, _
  Optional ByVal MemberName As String) As String
      
  Dim tliParameterInfo As ParameterInfo
  Dim tliTypeInfo As TypeInfo
  Dim tliResolvedTypeInfo As TypeInfo
  Dim tliTypeKinds As TypeKinds
  'Additional variables
  •••  

  With tliTypeLibInfo
    'First, determine the type of member we're dealing with
    bIsConstant = GetSearchType(SearchData) And tliStConstants
    With .GetMemberInfo(SearchData, InvokeKinds, , MemberName)
      If bIsConstant Then
        strReturn = "Const "
      ElseIf InvokeKinds = INVOKE_FUNC Or _
        InvokeKinds = INVOKE_EVENTFUNC Then
        Select Case .ReturnType.VarType
          Case VT_VOID, VT_HRESULT
            strReturn = "Sub "
          Case Else
            strReturn = "Function "
        End Select
      Else
        strReturn = "Property "
      End If
     'Now add the name of the member
     strReturn = strReturn & .Name
        
      'Process the member's parameters
      With .Parameters
        If .Count Then
          strReturn = strReturn & " ("
          bFirstParameter = True
          bParamArray = .OptionalCount = -1
          For Each tliParameterInfo In .Me
            'Determine whether parameter is default, optional, etc.
            •••
            With tliParameterInfo.VarTypeInfo
              Set tliTypeInfo = Nothing
              Set tliResolvedTypeInfo = Nothing
              tliTypeKinds = TKIND_MAX
              intVarTypeCur = .VarType
              If (intVarTypeCur And Not (VT_ARRAY Or VT_VECTOR)) = 0 Then
                On Error Resume Next
                Set tliTypeInfo = .TypeInfo
                If Not tliTypeInfo Is Nothing Then
                  Set tliResolvedTypeInfo = tliTypeInfo
                  tliTypeKinds = tliResolvedTypeInfo.TypeKind
                  Do While tliTypeKinds = TKIND_ALIAS
                    'Resolve alias types
                    •••
                  Loop
                End If
                'Determine whether parameters are ByVal or ByRef
                •••
                'Display the parameter name
                strReturn = strReturn & tliParameterInfo.Name
                'If array, unknown, or external, format accordingly
                •••
                'Reset error handling
                On Error GoTo 0
              Else
                If .PointerLevel = 0 Then
                  strReturn = strReturn & "ByVal "
                End If
                                    
                strReturn = strReturn & tliParameterInfo.Name
                If intVarTypeCur <> vbVariant Then
                  strTypeName = TypeName(.TypedVariant)
                  If intVarTypeCur And (VT_ARRAY Or VT_VECTOR) Then
                    strReturn = strReturn & "() As " & _
                      Left$(strTypeName, Len(strTypeName) - 2)
                  Else
                    strReturn = strReturn & " As " & strTypeName
                  End If
                End If
              End If
                                
              If bOptional Then
                If bDefault Then
                  strReturn = strReturn & _
                    ProduceDefaultValue(tliParameterInfo.DefaultValue, _
                    tliResolvedTypeInfo)
                End If
                strReturn = strReturn & "]"
              End If
            End With
          Next
          strReturn = strReturn & ")"
        End If
      End With
        
      If bIsConstant Then
        ConstVal = .Value
        strReturn = strReturn & " = " & ConstVal
      Else
        With .ReturnType
          intVarTypeCur = .VarType
          If intVarTypeCur = 0 Or (intVarTypeCur And Not _
            (VT_ARRAY Or VT_VECTOR)) = 0 Then
            On Error Resume Next
            If Not .TypeInfo Is Nothing Then
              'If array, unknown, or external, format accordingly
              •••
            End If
            On Error GoTo 0
          Else
            Select Case intVarTypeCur
              Case VT_VARIANT, VT_VOID, VT_HRESULT
              Case Else
                strTypeName = TypeName(.TypedVariant)
                'Format return type for display
                •••
            End Select
          End If
        End With
      End If
            
      PrototypeMember = strReturn
      lblMemberOf = "Member of " & tliTypeLibInfo.Name & "." & _
        tliTypeLibInfo.GetTypeInfo(SearchData And &HFFFF&).Name
      lblHelpText = .HelpString
    End With
  End With
End Function
Page view tracker