2

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

Kara
  • 6,115
  • 16
  • 50
  • 57
UncleBob
  • 41
  • 1
  • 7
  • maybe try [**this**](http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/Q_22489757.html) (*ive never used it so I can't recommend*) –  Dec 17 '13 at 10:33
  • 1
    Yes, that is a good link for techniques about using Shell.Application as an alternative to shDocVw.ShellWindows. And, I have used those techniques successfully in the past. Today's question was focused on ways to avoid that alternative, but that turns out to be impossible with late binding. – UncleBob Dec 17 '13 at 12:03
  • that's correct. We tried... –  Dec 17 '13 at 12:05

3 Answers3

1

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

  • + 1 You are on fire ;p – Siddharth Rout Dec 16 '13 at 14:32
  • I have clarified my initial post to say "I also wish to avoid the need setting a reference to "Microsoft Internet Controls". With that in mind, I am sure you will now understand why I need to dim as Object. It also makes the error you mention go away. – UncleBob Dec 16 '13 at 15:54
  • I am new to this site. Is it OK for me to edit your response directly? – UncleBob Dec 16 '13 at 16:51
  • @user3107264 I feel that I have well explained why the error appears. You're creating 2 different objects. Declaring your `variable` as Object is not the solution. –  Dec 16 '13 at 17:03
  • 1
    mehow: I think you misunderstand my question. If you read my clarified version you will see that there is one and only one object. – UncleBob Dec 17 '13 at 02:43
0

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.

Aditya Guru
  • 646
  • 2
  • 10
  • 18
0

There is a slightly better approach outlined at https://www.experts-exchange.com/questions/28961564/How-to-find-the-class-id-of-an-arbitrary-object-Example-Set-x-CreateObject-New-1C3B4210-F441-11CE-B9EA-00AA006B1A69.html#a41743468.

UncleBob
  • 41
  • 1
  • 7
  • It took me way too long to realize why a post from 2013 was showing up on the front page as `Top Questions`. Necro'd it... regarding what you provided as an answer is in @user2140173 's post, regarding using RegEdit to find appropriate keys. – Cyril May 30 '19 at 20:01
  • This link only answer does not contain the answer. We should always include the relevant bits of information in the answer as stated here: https://stackoverflow.com/help/how-to-answer – HackSlash Jun 01 '21 at 15:40
  • My response to HackSlash's comment: I revisited the question and I must admit my "answer" was a confusing mess that did not answer anything. The correct answer was not found until 2016. To convert from Set obj = New SHDocVw.ShellWindows You should replace it with Set obj = CreateObject("New:{9BA05972-F6A8-11CF-A442-00A0C90A8F39}") To derive the magic numbers see https://www.experts-exchange.com/questions/28961564/How-to-find-the-class-id-of-an-arbitrary-object-Example-Set-x-CreateObject-New-1C3B4210-F441-11CE-B9EA-00AA006B1A69.html#a41743468 UncleBob – UncleBob Jun 06 '21 at 18:25