【问题标题】:convert early binding to late binding without changing object type在不更改对象类型的情况下将早期绑定转换为后期绑定
【发布时间】:2013-12-16 13:03:40
【问题描述】:

这似乎是一个简单的问题,但我在论坛追了几个小时后,我认为这可能是不可能的。

我经常想将程序从早期绑定转换为后期绑定。通常,它是一个 vba、Visual Basic 应用程序、在 Excel 2010 和 windows 7 pro 下运行的程序。

出于讨论的目的,我们假设它是以下内容。

Sub EarlyBind()
   ' use IDE > Tools > references > and select “Microsoft Internet Controls”
     Dim shellWins1 as shdocvw.shellwindows
Line1:      Set shellWins1 = New SHDocVw.ShellWindows
      MsgBox TypeName(shellWins1) ' this will display “IShellWindows”
      ' other code that expects to be working with an IshellWindows object …..
 End Sub

根据我的经验,将这样的程序转换为后期绑定有时很困难。

例如,我发现一些论坛建议我将其更改为

Set shellwins1 = createobject("Shell.applicaton")

但这会创建一个 IShellDispatch5 对象,而不是 IshellWindows 对象。这意味着我必须更改其他代码以适应新的对象类型。当然,我必须测试其他代码是否存在细微差别。

所以,我的目标是找到一个通用解决方案,让我可以重写“Line1”以创建具有后期绑定的正确对象类型。我还希望避免设置对“Microsof Internet Controls”的引用。换句话说,我希望代码如下所示: 子后期绑定()

Dim shellWins1 as object

Line1:      Set shellWins1 = createobject(“xxxxxx.yyyyyy”).zzzzzz

 MsgBox TypeName(shellWins1) ‘ this should display “IShellWindows”

  …..  other code that expects to be working with an IshellWindows object …..

End Sub

我知道如何使用 vba IDE 来查找与对象关联的 dll。在这种情况下,dll 是 Library SHDocVw C:\Windows\SysWOW64\ieframe.dll。

我已经安装了 OleView,并且可以找到与 clsId、TypeLib 和接口相关的 IshellWindows“幻数”(例如接口是 85CB6900-4D95-11CF-960C-0080C7F4EE85)。

但是,我不知道如何将它们转换为可以在上面发布的示例代码中的 line1 中使用的程序 id。

我希望这里有人可以提供帮助。 ------ 在 MeHow 的帮助下,我现在有了答案! ------

将“set myObj = new xxxx.yyyyy”切换为任意对象类型的后期绑定

Change  set myObj = new xxxx.yyyyy
into    set myObj = CreateObject("xxxx.yyyyy")

这通常会奏效。

但是,在某些情况下,(例如“shDocVw.ShellWindows。”)它会给出错误 429 ActiveX 组件无法创建。

当这种情况发生时,我完全不走运。不可能对那个 EXACT 对象类使用后期绑定。相反,我必须找到一个替代类来做大致相同的事情。 (例如“Shell.Application”)。

【问题讨论】:

  • 也许可以试试this(我没用过,所以我不能推荐)
  • 是的,这是关于使用 Shell.Application 作为 shDocVw.ShellWindows 的替代技术的一个很好的链接。而且,我过去曾成功使用过这些技术。今天的问题集中在如何避免这种替代方案,但事实证明,使用后期绑定是不可能的。
  • 没错。我们试过...

标签: vba late-binding createobject early-binding


【解决方案1】:

你的简短回答是

IShellWindows is an interface.

它

提供对打开的 Shell 窗口集合的访问。

因此


看看CreateObject() method。

注意:

创建并返回对 COM 对象的引用。 CreateObject 不能 用于在 Visual Basic 中创建类的实例,除非那些 类被显式公开为 COM 组件。

IShellWindows 没有作为 COM 组件公开,因此无法说 CreateObject("SHDocVw.IShellWindows")


当您打开注册表 (regedit) 并搜索 key 时,请输入 IShellWindows。如果您找到任何东西,这意味着您已经找到了您的 Prog ID,并且如果您没有找到任何东西,则意味着没有像 IShellWindows 这样的东西被注册为 prog Id,因此假设您可以不要迟到绑定IShellWindows

【讨论】:

  • + 1 你着火了;p
  • 我已经澄清了我最初的帖子说“我也希望避免需要设置对“Microsoft Internet Controls”的引用。考虑到这一点,我相信你现在会明白我为什么需要暗淡为对象。它也使你提到的错误消失。
  • 我是这个网站的新手。我可以直接编辑您的回复吗?
  • @user3107264 我觉得我已经很好地解释了为什么会出现错误。您正在创建 2 个不同的对象。将您的 variable 声明为 Object 不是解决方案。
  • mehow:我想你误解了我的问题。如果您阅读我的澄清版本,您会发现只有一个对象。
【解决方案2】:

我遇到了你的问题,试图为自己找到一些东西。但不知道你有没有试过以下方法——

Set shellwins1 = createobject("Shell.Application")
MsgBox TypeName(shellWins1.Windows)

这回答了您关于数据类型的问题。它为我打印 IShellWindows。我不确定它是否真的可以解决你后期绑定的目的,如果这将是所需的对象,尽管数据类型是你需要的。

所以,我建议你试一试。

【讨论】:

    【解决方案3】:

    【讨论】:

    • 我花了很长时间才意识到为什么 2013 年的帖子会在首页显示为 Top Questions。 Necro'd it...关于你提供的答案在@user2140173 的帖子中,关于使用 RegEdit 查找适当的键。
    • 此链接仅答案不包含答案。我们应该始终在答案中包含相关信息,如下所述:stackoverflow.com/help/how-to-answer
    • 我对 HackSlash 评论的回应:我重新审视了这个问题,我必须承认我的“答案”是一团混乱,没有回答任何问题。直到 2016 年才找到正确答案。要从 Set obj = New SHDocVw.ShellWindows 转换,您应该将其替换为 Set obj = CreateObject("New:{9BA05972-F6A8-11CF-A442-00A0C90A8F39}") 以导出幻数见experts-exchange.com/questions/28961564/…UncleBob
    猜你喜欢
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多