Search code examples
vbalate-bindingcreateobjectearly-binding

convert early binding to late binding without changing object type


This seems like a simple question but I after chasing forums for several hours I think it might be impossible.

I often want to convert a program from early binding to late binding. Usually, it is a vba, visual basic for applications, program that runs under Excel 2010 and windows 7 pro.

For discussion purposes, let’s pretend it is the following.

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

In my experience, converting such a program to late binding is sometimes hard.

For instance, I found some forums that suggest I change it to

Set shellwins1 = createobject("Shell.applicaton")

But that creates a IShellDispatch5 object, not an IshellWindows object. That means I have to change other code to accommodate the new object type. And, of course I have to test that other code for subtle differences.

So, my goal is to find a general solution that will allow me to rewrite “Line1” to create the CORRECT object type with late binding. I also wish to avoid the need setting a reference to "Microsof Internet Controls. In other words, I want the code to look like this: Sub LateBind()

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

I know how to use the vba IDE to find the dll associated with the object. In this case the dll is Library SHDocVw C:\Windows\SysWOW64\ieframe.dll.

I have installed OleView and can find the associated IshellWindows “magic numbers” for the clsId, TypeLib, and Inteface (for instance the interface is 85CB6900-4D95-11CF-960C-0080C7F4EE85).

But, I don’t know how to convert them into a program id that can be used in line1 in the sample code posted above.

I hope someone here can help. ------ With MeHow's help, I now have the answer! ------

To switch 'set myObj = new xxxx.yyyyy' to late binding for arbitrary object types

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

Very often that will work.

But, in the some cases, (e.g. "shDocVw.ShellWindows.") it gives error 429 ActiveX component cannot be created.

When that occurs I AM COMPLETELY OUT OF LUCK. It is impossible to use late binding with that EXACT object class. Instead I must find a substitute class that does approximately the same thing. (e.g. "Shell.Application").


Solution

  • Your short answer is

    IShellWindows is an interface.

    It

    Provides access to the collection of open Shell windows.

    Therefore

    enter image description here


    Take a look at the CreateObject() method.

    Note:

    Creates and returns a reference to a COM object. CreateObject cannot be used to create instances of classes in Visual Basic unless those classes are explicitly exposed as COM components.

    IShellWindows is not exposed as a COM component so that's why there is no way to say CreateObject("SHDocVw.IShellWindows")


    When you open your registry (regedit) and search for a key type in IShellWindows. If you find anything that means you've found your Prog ID and if you don't find anything it means that nothing like IShellWindows is registered as a prog Id therefore it would make sense to assume that you can't late bind IShellWindows