用于 COM 对象交互式运行时调试的 ActiveX 控件





4.00/5 (5投票s)
2001年3月13日

96431

1409
三个 ActiveX 控件,用于运行时浏览 COM 对象的对象模型层次结构、其实现的接口,以及浏览和交互式更改其属性和方法(某种程度上扩展了 VB 的属性窗口和调试窗口的组合)。
概述
在开发 COM 对象时,我经常希望拥有类似于 VB 的属性窗口或调试窗口的东西,以便在运行时检索或交互式地更改对象的当前属性。有一些小型演示应用程序(如 MSDN 中的 AtlCon 示例)提供了属性浏览功能,但总的来说,它们对我来说不够完善——无法浏览需要一个或多个额外参数的属性(不仅仅是设置/返回一个值),无法调用方法,只能浏览 COM 对象的默认接口(尽管大多数对象都实现了多个接口),并且只能在设计时进行浏览。
为了绕过这些限制,我实现了三个 ActiveX 控件来完成这项工作(请参见上面的截图)。
一个用于浏览对象模型层次结构(上面的示例:MS Word),一个用于浏览所有已实现的接口(限制:仅列出 typelib 中描述的已注册接口),该接口属于指定对象(上面的示例:VB 窗体上的 MS ProgressBar 控件),还有一个用于浏览对象的当前属性值并交互式地更改(即调用)对象的属性和方法(上面的示例:MS Word 的“Normal Template”对象)。
此外,这些控件的源代码展示了如何通过类型描述接口ITypeInfo
、ITypeLib
等以及类型信息结构(请参见 MSDN:PlatformSDK/Component Services/COM/Automation)检索类型信息。
控件描述
1. 运行对象表浏览器控件
此控件允许以类似 VB 调试窗口的树状视图浏览对象模型层次结构。有两个“类别”的对象可供浏览:注册在“运行对象表”中的对象(请参见 MSDN)以及通过编程方式添加或从“对象浏览器控件”或“调用对话框”(请参见下面的“4. 拖放”)交互式拖放添加的对象。在控件内单击鼠标右键会显示以下上下文菜单。
命令刷新 ROT首先清除“运行对象表”类别,然后枚举运行对象表中的所有对象,并将它们添加到该类别中。第一个可用的对象会自动选为活动项。扫描对象的默认接口以获取返回其他对象的属性,从而构建对象模型层次结构(就像在 VB 中使用“点”一样,例如 App.Documents.Item(1)...)。
使用命令刷新对象,您可以更新当前所选对象的此层次结构。当构建层次结构的某个属性发生更改(即返回的对象与已检索到的对象不同)或集合对象本身发生更改时,需要此操作。
命令删除对象最终会从控件列表中删除所选对象。自然,此命令仅适用于“根”对象。
当前选定的对象会在用户通过鼠标激活树视图项时发生更改。
2. 接口浏览器控件
此控件列出了指定对象在注册表中已注册且在类型库中已描述的所有已实现接口。
注意:几乎所有 Microsoft 定义的“标准”接口(例如IOleXXX
接口)都没有在类型库中描述,因此这些接口不会被列出。显然,Microsoft 不希望通过自动化提供对这些接口的访问。尽管如此,您可以在网上找到不少描述这些接口的类型库(例如 Eduardo A. Morcillo 的网站)。
当用户通过鼠标激活列表中的某个接口时,会利用一种特殊的包装对象以该接口的格式公开(请参见 Chris Sell 的网站“如何向脚本客户端公开多个接口 - 使用单独的对象执行 QI”)。然后,包装后的对象将此接口用于自动化。将包装后的对象提供给对象浏览器控件,就可以浏览该接口的方法/属性,而不是对象的默认接口。请注意,此功能在 VB 中不可用(并且我在网上找不到任何其他应用程序等具备此功能...)。
3. 对象浏览器控件
此控件是 VB 的属性窗口和调试窗口的某种扩展组合。它列出了给定对象的 ALL 方法和属性(隐藏的和受限的,无论参数数量如何)。“普通”、“隐藏”和“受限”的方法/属性可以通过前面方法/属性名称的图标区分。读写属性可以在此控件中交互式编辑(见下文),前提是该属性只有一个参数(就像 VB 的属性窗口一样)。对于只读和读写属性,如果它们只有一个参数(即,对于只读属性是“retval”),则会显示属性的当前值。(注意:VB 的属性窗口仅显示读写属性)。
在控件内单击鼠标右键会显示以下上下文菜单。
命令刷新更新被浏览对象的所有属性。
使用命令显示隐藏成员和显示受限成员,您可以确定是否应浏览隐藏和受限的方法/属性。命令分组成员将对所有方法/属性进行排序,否则它们将按对象类型信息中给出的顺序显示。
如果对象可以在属性页上进行编辑(即,对象需要支持ISpecifyPropertyPages
,请参见 MSDN),命令查看属性页将显示一个(模态)属性表,其中包含对象指定的所有属性页。如果在此控件中当前激活的(即高亮的)方法/属性可以映射到特定的属性页,命令查看属性页将显示一个(模态)属性表,其中仅包含此特定属性页。为此,对象还需要实现IPerPropertyBrowsing
接口(同样,请参见 MSDN)。
命令执行方法、执行获取属性和执行设置属性将打开以下非模态对话框。
使用此对话框,您可以调用接受多个参数的方法和属性。在列表视图必需参数中,您需要指定调用方法/属性所需的每个参数(请参见下面的编辑)。单击调用按钮最终会调用方法/属性。如果调用成功并返回一个值,该值将显示在返回值字段中,否则将显示一个描述错误的弹出消息框。如果返回值是一个 COM 对象,您可以通过单击此字段并将其“拖动”到对象浏览器或运行对象表浏览器控件中来启动拖放操作。
上述对话框和控件本身中的值编辑方式类似:单击值列开始编辑,将焦点移开结束编辑。
编辑的类型取决于要编辑的值的类型,并且按照以下顺序确定:
如果您想在控件本身中编辑属性值,并且该属性支持PerPropertyBrowsing
(请参见 MSDN),将显示一个带有支持字符串的组合框(注意:这不适用于对话框)。如果该值是类型库中定义的类型(例如枚举),将显示一个组合框,列出所有可用值。如果该值是布尔类型,将显示一个带有“True”和“False”的组合框。如果该值本身是一个 COM 对象,“正常”编辑不可用,您需要通过拖放操作来设置该值;将显示文本“<Valid Object>”。所有其他编辑通过显示编辑框和文本编辑完成。
在控件中完成读写属性的编辑后,将自动调用 put-property。如果失败,将显示一个消息框,并更新并显示该属性的当前值。
4. 拖放
运行对象表浏览器控件、对象浏览器控件和调用对话框都支持“COM 对象的拖放操作”。这是必需的,因为许多方法/属性至少需要一个该类型的参数,而且我没有找到更简单的方法来指定这些参数。
在运行对象表浏览器中,您可以通过按住鼠标按钮并移动鼠标来拖动其中一个列出的对象。在对象浏览器控件中,当您选择“值”列中的文本“<Valid Object>”时,会启动此类操作,而在调用对话框中,当您选择返回值编辑字段中的相同文本时,也会启动此类操作。
当在运行对象表浏览器中放下时,对象将被添加到添加的对象类别,然后可以浏览其层次结构。在对象浏览器控件中,仅允许在值列上放置,当相应属性为读写属性且该属性只接受一个“COM 对象”类型的参数时。这将自动调用带有被放置对象的属性。在调用对话框中,仅允许在必需参数列表视图的值列上放置,当相应参数需要是该类型时。
实现说明
这些控件并未实现所有可能的数据类型浏览。例如,不支持交互式设置或浏览 SAFEARRAY 类型的参数;当类型是纯 VARIANT 时也会出现问题(这些参数始终被视为字符串)。如果出现预期之外的情况,您应该在调试模式下运行这些控件,每次遇到不支持的数据类型时都应该会触发一个断言。
与几乎所有此类项目一样,存在一些已知且肯定还有一些未知错误。例如,在浏览 MS Word 时会出现一个问题——关闭演示 VB 应用程序后,Word 在关闭时会崩溃。
接口浏览器控件实现的接口/对象包装是通过 DispAdapter DLL 中的几个 COM 对象完成的。该 DLL 由 Vlad Volkov 和 Dave Rogers 开发。我在 Chris Sell 的网站上找到了其代码的链接,但该链接不再有效。由于我对代码的版权不完全确定,我仅包含 DLL 作为二进制文件,不包含源代码。
如果您想使用提供的演示 VB 应用程序来调试/浏览基于 COM 对象模型的您自己的应用程序,您需要通过“RegisterActiveObject”API 函数在运行对象表中注册您的应用程序对象。
源代码几乎没有文档。我知道这是一个很大的错误,但我的工作占用了太多时间,而文档非常耗时……
演示 VB 应用程序
我包含了一个小型 VB 可执行文件,演示了这三个控件的组合使用。在大多数情况下,这对于调试/测试目的应该足够了。
为了能够运行该应用程序,您必须使用 regsvr32.exe 注册 *DispAdapter.dll* 和 *ObjectBrowser.dll*。