Table of Contents
C:/Program Files/Common Files/system/ado/msado15.dll
.
(On your machine, it may be named and located differently
or simply not present at all.)
We load that library using LoadTypeLib()
lib = LoadTypeLib("C:/Program Files/Common Files/system/ado/msado15.dll")The resulting lib is a reference or handle to the C-level structure that identifies the object. We can use this to examine the different elements about which the library provides type information. When we are finished with it, we can release the library and free the resources it uses using UnloadTypeLib() . (Not implemented yet.) Essentially we can treat the type library as a named list. Each element is an object of type ITypeInfo in our world. This provides a reference to the elemenet in the type library and from that we can find out most things about that type. Since the library reference is equivalent to a list in S, we can find out the names of the different elements it contains using
names(lib)As one might expect, we can extract elements from the type library in the S style using the usual list subsetting operators:
lib[[1]] # Single element. lib[1:4] # Returns a list, not a sub-ITypeLib lib[["CursorTypeEnum"]] # By type name lib[[names(lib)[1]]] # Same thing. lib$CursorTypeEnum # Same thing.Now that we know how to navigate the elements of the type library, we can examine its elements. We can also find out the types of these different elements in the library using \SFunction{getTypeLibTypes}.
getTypeLibTypes(lib)This describes the type of each element in the library by its type name such as dispatch, coclass, enum, interface, alias, module, union, record/structure. These are indexed by the names of the type. If one wants to get the actual numeric type rather than the text descriptions (so that they can be used within the C code), use the byName argument and specify
FALSE
.
This information is convenient for being able to get a
big picture view of what the type library contains.
We can see what are enumerated constants, what are types
with methods (dispatch), and so on. We can identify the elements
that might be of interest based on their name and/or type.
We can then ``zoom in'' and look at the type information for individual
elements of the type library. We get a reference to the underlying C
<c:struct>ITypeInfo</c:struct> object using the overloaded
[[
we discussed above. One
can index the type library reference either by the name or position of
the desired element.
cmd = lib[["Command"]]or
cmd = lib[[91]]We can then get the details of the type of this element using this R object. For example, we can find the collection of values in the enumeration <com:type>BookMarkEnum</com:type>.
getEnum(cmd)Suppose we wanted to find all the enumerations within a library and obtain their definitions as a name-value vector for each enum type. We can do this in two steps
types = getTypeLibTypes(lib) enums = which(types == "enum") lapply(enums, function(x) getEnum(lib[[x]]))If an element in the type library is a coclass type info object, then it can represent multiple interfaces. We get a list of the ITypeInfo objects for each of these interfaces by calling getElements() . We can the operate on each of these ITypeInfo elements as we do above. The getElements() function has a recursive argument.
Workbooks
.
We load the Excel type library, e.g.
lib = LoadTypeLib("c:/Micrsoft Office/OFFICE11/Excel.exe")or referencing the appropriate file. To get the Workbooks class, we use the command
workbooks = lib[["Workbooks"]]. This is an object of class ITypeInfoDispatch indicating that it is indeed describing an IDispatch class. So from this we can directly get the list of functions defined by that particular IDispatch class:
funs = getFuncs(workbooks)This is a regular list in R. The names of the elements are the names of the functions/operations.
names(funs)The first seven entries are common to all IDispatch objects. These provide ways to query the object and dynamically invoking methods and accessing properties. The remaining elements are more interesting from the user's perspective. These tell us what we can do with this class of object. Some of the names have a curious _ and __ in front of them. For instance, we have an OpenText, _OpenText and __OpenText entries! If we look at the number of parameters in each function, we get
sapply(funcs[grep("OpenText", names(funcs))], function(x) length(x@parameters)) __OpenText _OpenText OpenText 14 16 18The _ and __ suggest somehow that these are not necessarily part of the user-level interface. They are somehow being obfuscated or obscured. Indeed, if we look at the hidden field of each of these function descriptions, we see that the first two are indeed hidden.
sapply(funcs[grep("OpenText", names(funcs))], function(x) x@hidden
THIS IS INCORRECT. Everything seems to be hidden,i.e. every function in every type.
open = funcs$OpenThis is an instance of the FunctionInvokeDescription. We can find out more about this class using
getSlots(class(open))We see that we have all of the essential ingredients of a function, and a few more. The name, the return type, the list of parameters are all of the things we need to make sense of the function so that we can invoke it. The invokeType, hidden and memid (and kind) values are internal information that help in actually implementing the call.
COMIDispatch
object.
For instance, we can ask for the
ITypeInfo for the COMIDispatch object
using
getTypeInfo(obj)Similarly, we can get the ITypeLib from the object using
getTypeLib. We can also call getFuncs() on the object to get the collection of functions.