GetObject和VB6 ActiveX exe

时间:2009-05-27 08:38:08

标签: com vb6 activex

VB6 help on GetObject说“你不能使用GetObject来获取对用Visual Basic创建的类的引用”(最后一句话!)。我的VB6 GUI将对象公开为ActiveX exe,供其他组件操作。我希望其他组件连接到已经运行的GUI,而不是启动exe的新实例。我发现使用GetObject确实有用,如果你使用这种语法:

Set myobj = GetObject("", "ProjectName.ClassName")

令我担心的是,帮助说这应该不起作用,虽然我做了很多测试,到目前为止还没有发现任何问题。任何COM专家谁能告诉我是否会遇到问题?无论如何我会使用CreateObject吗?

ActiveX exe设置是:只有一个线程的线程池。该课程具有MultiUse实例化。这些设置可能足以阻止CreateObject启动exe的新实例。这是对的吗?

2 个答案:

答案 0 :(得分:10)

文档令人困惑,但是正确无误。您引用的MSDN页面有助于解释为什么GetObject调用不会引发错误:

  

如果 路径名 [第一个参数]是零长度字符串   (“”), GetObject 返回一个新对象   指定类型的实例。如果   pathname参数被省略,    GetObject 会返回当前有效的内容   指定类型的对象。如果不   存在指定类型的对象,   发生错误。

这很微妙,但暗示是

GetObject "", "ProjectName.ClassName

实际上相当于

CreateObject "ProjectName.ClassName"

也就是说,将空字符串传递给GetObject的第一个参数使其操作与CreateObject完全相同,这意味着它将创建一个新实例 class,而不是返回对已经运行的实例的引用。

回到MSDN摘录,它提到完全省略GetObject的第一个参数将导致GetObject返回对已经运行的实例的引用(如果存在)。这样的电话会是这样的:

GetObject , "ProjectName.ClassName" 'Note nothing at all is passed for the first argument'

但是,如果您尝试执行此操作,则会立即收到运行时错误。这是文档在指出GetObject不适用于使用VB6创建的类时引用的用例。

这不起作用的原因是GetObject如何发挥其魔力。当省略第一个参数时,它会尝试通过查询运行对象表(ROT)来返回现有对象实例,ROT是一个包含正在运行的COM对象的机器范围查找表。问题是对象必须由创建它们的进程在运行对象表中显式注册才能被其他进程访问 - VB6运行时不在ROT中注册ActiveX EXE类,因此GetObject无法检索对已经运行的实例的引用。

答案 1 :(得分:2)

  

我想要其他组件连接   到已经运行的GUI,   而不是开始一个新的实例   exe。

诀窍是要记住,在ActiveX EXE中,可以设置它,以便只有一个LIBRARY实例在运行。正确的是,您无法跨越流程边界并且只是在一个给定的类实例中进行操作。但是,可以设置ActiveX EXE,以便任何类实例都可以访问GLOBAL变量。

如何准确地做到这一点有点复杂。您可以将ActiveX EXE用作普通EXE,主要区别在于您必须使用Sub Main。您还可以检查它是否独立运行。现在我假设MarkJ的应用就是这种情况。

如果是这种情况,您需要创建一个应用程序类并进行设置,以便在创建它时(通过使用Class_Initialize),它将填充当前正在运行的表单和集合实例。

我强烈建议您创建一个ActiveX DLL(而不是EXE),它只包含要实现为接口的类。而不是去

'Class ThisGUIApp
Public MainForm as Form

您创建的接口具有访问主窗体元素所需的所有属性和方法。然后你去

'Class ThisGUIApp
Public MainForm as IMainForm

Private Sub Class_Initialize
  Set MainForm = frmMyMainForm
End Sub

'Form frmMyMainForm
Implements IMainForm

您这样做是因为虽然您可以跨应用程序进程发送表单,但当您尝试访问其成员和控件时,事情会变得很糟糕。如果您通过接口分配,则连接更加稳固。此外,它更好地记录了您正在尝试的事情类型。