http://www.microsoft.com/msj/0399/comtype/comtype.aspx
ITypeLib, ITypeInfo, and Friends
As
a first-time user of the typelib interfaces, where do you start? Take a
look at the LoadTypeLib API exported by OLEAUT32.DLL. It takes the name
of a typelib file (or a file containing a typelib resource) and returns
an ITypeLib interface instance. The ITypeLib interface has various bits
of information that can be obtained via its methods. More importantly,
the ITypeLib interface is a container of sorts for ITypeInfo interface
instances (see Figure 2). As you'll see in more detail later, an
ITypeInfo is how you get at the names of interface methods, parameters,
enums, structs, and so on.
 |
Figure 2 ITypeInfo Instances
|
Each
typelib (and its associated ITypeLib interface instance) has a unique
GUID assigned to it. This GUID is typically found in the registry under
the HKEY_CLASSES_ROOT\TypeLib key. The ITypeLib::GetLibAttr method
allocates
and returns a pointer to a TYPEATTR structure that contains the
typelib's GUID and other assorted information. When you're done with the
TYPEATTR, you'll need to call ITypeLib::ReleaseTLibAttr to free the
memory for the TYPEATTR structure.
The
ITypeLib::GetDocumentation method retrieves things like the typelib
name, a description string, a help file lookup string, and the name of
the typelib's associated help file. These are the very same strings that
OLEVIEW uses when it generates IDL from a typelib. Passing -1 as the
first parameter to GetDocumentation gets information specific to the
typelib rather than for one of the ITypeInfo instances that it
encapsulates. In true COM fashion, the strings that GetDocumentation
returns are allocated internally, and you're responsible for freeing
them by calling SysFreeString. This is a good time to point out that all
strings used with typelibs are Unicode.
There's
a variety of other ITypeLib methods that you can explore on your own.
However, let's look at the single most important ITypeLib method,
GetTypeInfo. Each ITypeLib acts as a dispenser for ITypeInfo interface
instances. To get an ITypeInfo instance, simply call GetTypeInfo,
passing in the index of the desired ITypeInfo. What's this index thing?
Each ITypeInfo instance in an ITypeLib has an associated index value.
The index values are 0 through n-1, where n is the number of ITypeInfos.
The GetTypeInfoCount method returns the number of ITypeInfos in the
typelib. As you'll see shortly, calling GetTypeInfo repeatedly with a
monotonically increasing ITypeInfo index is all that's necessary to pick
apart a typelib.
After
getting your hands on an ITypeInfo instance, the real fun begins. Each
ITypeInfo represents something
such as an interface (TKIND_INTERFACE), a structure (TKIND_RECORD), or a
creatable object (TKIND_COCLASS). The complete list of ITypeInfo
representable items are the TKIND_XXX enums in OAIDL.H.
Like
ITypeLib, the ITypeInfo interface has a GetDocumentation method that
returns the name of the interface, a description string, a help file
lookup string, and the name of the associated help file. Passing -1 as
the memberid parameter returns information for the interface, structure,
enum, or whatever the ITypeInfo represents. Passing other values for
the memberid parameter retrieves the corresponding strings for the
desired interface's methods, an enum's string values, and so on. If
you've ever wondered how Visual Basic can call up context-sensitive
online help for third-party controls, here's your answer.
Much
more information about an ITypeInfo is obtained via the GetTypeAttr
method, which returns a pointer to a TYPEATTR structure containing all
sorts of goodies concerning the ITypeInfo. Included in this structure is
a GUID and a TYPEKIND (TKIND_XXX) indicating what the ITypeInfo
describes. If the ITypeInfo is of type TKIND_INTERFACE or
TKIND_DISPATCH, the GUID is the IID for the interface. This is the same
IID you'll see under the registry's HKEY_CLASSES_ROOT\Interface key.
Likewise, for TKIND_COCLASS ITypeInfos, the GUID is the CLSID. Most
CLSIDs are found in the registry under the HKEY_
CLASSES_ROOT\CLSID key. Note that TKIND_COCLASS ITypeInfos are
essentially what you think of as creatable objects (for instance, an
MSGraph.Chart object).
Some
TYPEATTR fields are meaningful only for specific TYPEKIND values. For
example, in a TKIND_DISPATCH the TYPEATTR.cFuncs element indicates how
many methods are associated with this class, while a nonzero cImplTypes
element indicates if the interface is derived from another interface.
For a TKIND_COCLASS ITypeInfo, however, the cImplTypes field indicates
how many interfaces the creatable object exposes directly. Typically, a
TKIND_COCLASS exposes two interfaces. The first is the incoming
interface that you think of as the object's properties and methods. The
second interface is the out interface that you associate with the object
firing events. (Note to COM geeks: think IConnectionPoint.) For
example, the Graph1_DblClick event handler subroutine you'd write in
Visual Basic is called through the out interface.
Some
other notable fields in the TYPEATTR are cVars and cbSizeInstance. For a
TKIND_ENUM, cVars indicates the number of enum values. In a
TKIND_RECORD, the cVars field indicates how many structure elements are
present, and cbSizeInstance tells you the size of the structure.