COMWindows 2003Visual Basic 6Windows 2000Visual C++ 6.0Windows XPMFCIntermediateDevVisual StudioWindowsC++Visual Basic
运行时 COM 对象检查





4.00/5 (4投票s)
2003年10月10日
3分钟阅读

73381

2223
如何检查运行时COM对象的内容。
引言
可能每个人都知道为对象创建监视器、检查其属性等等是多么令人愉悦。无论如何,你可能已经注意到VB在不同的会话之间会忘记你正在监视的内容,所以显而易见的想法是构建一个自定义的调试窗体来显示你需要的内容。但有一个问题,那就是你可以轻松地检查默认类型,但对于COM对象来说,情况完全不同。我的这个小而简单的控件解决了这个问题,因为它允许你通过一个TreeView
控件来检查一个通用COM对象的全部运行时属性。
使用代码
用法非常简单
- 创建一个窗体
- 将一个
ObjView
控件添加到窗体上 - 运行你的程序,
- 运行时,你可以
- 通过控件的
Add
方法添加一个对象进行检查。请注意,你需要提供一个字符串来唯一标识你的对象。 - 使用
Remove
方法从检查中移除一个对象。 - 通过
Refresh
方法刷新所有正在检查的对象的值。 - 通过
RefreshOBJ
方法刷新单个对象,该方法需要第一个参数为对象的引用,第二个参数为你添加对象时给控件的标识符。
- 通过控件的
所有的检查工作都使用了TypeLib Information库(tlbinf32.dll),该库暴露了各种类和方法。请注意,VB COM对象不能暴露每个类超过一个接口(或者至少我没有找到任何这样做的对象),这个想法很简单:
- 获取给定对象的接口描述符
Dim tliApp as TLI.TLIApplication Dim tliIrf as TLI.InterfaceInfo Set tliApp = new TLI.TLIApplication Set tliIrf = tliApp.InterfaceInfoFromObject(< object variable > )
- 检查
tliIrf
变量的Members
集合,其中包含类暴露的所有公共成员Dim tliMI as TLI.MemberInfo For Each tliMi In tliIrf.Members ... Next
每个
MemberInfo
类都包含指向选定接口的公共成员(函数、子程序、变量、属性……)的数据。相关的字段是:Name:
成员的名称,用于检索值。Parameters:
这是一个ParameterInfo
集合,包含关于选定方法参数的信息。InvokeKind:
这是一个InvokeKinds
枚举类型,用于说明这是哪种类型的成员。ReturnType:
这是一个VarTypeInfo
类,包含关于返回类型的信息。
- 由于我想要创建一个类似调试器的对象,我做了以下假设:
- 如果它是一个集合,或者一个实现了集合的对象,则分析每个项。要判断它是否为集合,控件使用以下过程:
Private Function IsCollection(v As Variant) As Boolean Dim tlApp As TLI.TLIApplication Dim tlIrf As TLI.InterfaceInfo Dim tlmi As TLI.MemberInfo Dim Obj As Object If IsObject(v) Then If TypeName(v) = "Collection" Then IsCollection = True End If Set Obj = v Set tlApp = New TLI.TLIApplication Set tlIrf = tlApp.InterfaceInfoFromObject(Obj) For Each tlmi In tlIrf.Members If LCase$(tlmi.Name) = "item" Then IsCollection = True Exit For End If Next End If Set tlmi = Nothing Set tlIrf = Nothing Set tlApp = Nothing End Function
因此,如果对象没有
Item
方法,它就不会被识别为集合,这与VB的行为是一致的。 - 如果不是集合,则使用以下表解析每个成员:
InvokeKind
:如果不是Get
(INVOKE_PROPERTYGET
),则丢弃。- 如果它有1个或更多参数,则丢弃。
- 关于返回类型:
- 它使用
CallByName
语句获取选定成员的当前值。 - 如果它是一个对象,它将递归地遍历这个对象。
- 如果不是,它将显示字符串成员名称 = 成员值。
- 它使用
- 如果它是一个集合,或者一个实现了集合的对象,则分析每个项。要判断它是否为集合,控件使用以下过程:
关注点
一个有趣的点是TypeInfo库如何管理枚举类型。它不将其视为long,而是将枚举类型的各项填充到ReturnType
成员的TypeInfo.Members
集合中,因此每一项都是一个TypeInfo
,包含:
Value
:枚举项的数值。Name
:与之关联的符号名称。
因此,使用For ... Each
循环,很容易找到代表给定数值的符号名称,而这个数值通常开发者更容易理解。
历史
- 2003/10/12:第一个版本公开发布。