Преобразовать раннее связывание в позднее связывание без изменения типа объекта
Это кажется простым вопросом, но я после нескольких часов погони за форумами думаю, что это может быть невозможно.
Я часто хочу преобразовать программу из ранней привязки в позднюю привязку. Обычно это 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", чтобы создать ПРАВИЛЬНЫЙ тип объекта с поздним связыванием. Я также хотел бы избежать необходимости установки ссылки на "Микрософ управления Интернетом". Другими словами, я хочу, чтобы код выглядел так: 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
Я знаю, как использовать vba IDE, чтобы найти DLL, связанную с объектом. В этом случае dll - это библиотека SHDocVw C:\Windows\SysWOW64\ieframe.dll.
Я установил OleView и могу найти связанные "магические числа" IshellWindows для clsId, TypeLib и Inteface (например, интерфейс 85CB6900-4D95-11CF-960C-0080C7F4EE85).
Но я не знаю, как преобразовать их в идентификатор программы, который можно использовать в строке1 в приведенном выше примере кода.
Я надеюсь, что кто-то здесь может помочь. ------ С помощью 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").
2 ответа
Ваш короткий ответ
IShellWindows
это интерфейс.
Это
Предоставляет доступ к коллекции открытых окон оболочки.
Следовательно
Взгляните на метод CreateObject().
Замечания:
Создает и возвращает ссылку на COM-объект. CreateObject нельзя использовать для создания экземпляров классов в Visual Basic, если только эти классы явно не представлены как компоненты COM.
IShellWindows
не выставляется как компонент COM, поэтому нельзя сказать, CreateObject("SHDocVw.IShellWindows")
Когда вы открываете свой реестр (regedit
) и найдитеключ в IShellWindows
, Если вы находите что-либо, что означает, что вы нашли свой Prog ID, и если вы ничего не находите, это означает, что ничто, кромеIShellWindows, не зарегистрировано как Prog Id, поэтому имеет смысл предположить, что вы не можете выполнить позднюю привязку. IShellWindows
Я столкнулся с вашим вопросом, пытаясь найти что-то для себя. Но я не знаю, пробовали ли вы следующее -
Set shellwins1 = createobject("Shell.Application")
MsgBox TypeName(shellWins1.Windows)
Это отвечает на ваш вопрос для типа данных. Он печатает IShellWindows для меня. Я не уверен, что если это действительно может решить вашу цель для позднего связывания значения, если это будет требуемый объект, хотя тип данных - то, что вам нужно.
Итак, я бы посоветовал вам попробовать.
Существует несколько лучший подход, изложенный по адресу 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.