convert early binding to late binding without changing object type

2.6k views Asked by At

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").

3

There are 3 answers

5
AudioBubble On BEST ANSWER

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

0
Aditya Guru On

I bumped into your question trying to find something for myself. But I don't know if you have tried the following -

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

This answers your question for datatype. It prints IShellWindows for me. I'm not sure though if it could actually solve your purpose for latebinding meaning if this would be the object required though the datatype is what you need.

So, I would advise you to give it a try.