Здравствуйте, MishaVBA, Вы писали:
MVB>Помогите запустить функцию ProgIDFromCLSID в VBA
Option Explicit
Private Type TGUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Private Declare Function CLSIDFromString Lib"ole32.dll" ( _
ByVal lpsz As Long, rguid As TGUID) As Long
Private Declare Function ProgIDFromCLSID Lib"ole32.dll" ( _
clsid As TGUID, lplpszProgID As Long) As Long
Private Const NOERROR As Long = 0
Private Declare Function lstrlenW Lib"kernel32" ( _
ByVal lpString As Any) As Long
Private Declare Function lstrcpynW Lib"kernel32" ( _
ByVal lpString1 As Any, ByVal lpString2 As Any, _
ByVal iMaxLength As Long) As Long
Private Function LPWSTR2String(ByVal lpWStr As Long) As String
Dim nStrLen As Long
Dim sTmp As String
nStrLen = lstrlenW(lpWStr)
sTmp = String$(nStrLen, vbNullChar)
lstrcpynW ByVal StrPtr(sTmp), lpWStr, nStrLen + 1
LPWSTR2String = sTmp
End Function
Private Sub Command1_Click()
Dim Result As Long
Dim clsid As TGUID
Dim lpszProgID As Long
Result = CLSIDFromString(StrPtr("{D3E34B21-9D75-101A-8C3D-00AA001A1652}"), _
clsid)
If Result = NOERROR Then
Result = ProgIDFromCLSID(clsid, lpszProgID)
If Result = NOERROR Then
Debug.Print LPWSTR2String(lpszProgID)
End If
End If
End Sub
Re[2]: Помогите запустить функцию ProgIDFromCLSID в VBA
Здравствуйте, Vi2, Вы писали:
Vi2>Только нужно бы еще освободить память Vi2>
Vi2> CoTaskMemFree lpszProgID
Vi2>
Да, у меня возникал этот же вопрос. В статье MSDN о ProgIDFromCLSID говорится только об освобождении памяти для CLSID при вызове CLSIDFromProgID (интересно, почему там, а не в статье о CLSIDFromProgID?), а в Q183544 освобождения памяти нет.
Здравствуйте, Бенедикт, Вы писали:
Б>Здравствуйте, MishaVBA, Вы писали:
MSDN:
The lstrcpyn function has an undefined behavior if source and destination buffers overlap.
и там ещё Security Alert есть...
Так шо, командовать парадом предлагаю так:
Option Explicit
Public Declare Function SysReAllocString _
Lib"oleaut32.dll" (ByRef pBstr As String, _
ByVal lpOlechar As Long) As Long
Public Declare Sub CoTaskMemFree _
Lib"ole32.dll" (ByVal pv As Long)
Public Declare Sub ProgIDFromCLSID _
Lib"ole32.dll" (ByRef clsid As GUID, _
ByRef lplpszProgID As Long)
Public Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Public Sub main()
Dim udtGUID As GUID
With udtGUID
.Data1 = &HD43FE01
.Data2 = &HF093
.Data3 = &H11CF
.Data4(0) = &H89
.Data4(1) = &H40
.Data4(2) = &H0
.Data4(3) = &HA0
.Data4(4) = &HC9
.Data4(5) = &H5
.Data4(6) = &H42
.Data4(7) = &H28
End With
Dim bstProgID As String
Dim lngLpOleChar As Long
ProgIDFromCLSID udtGUID, lngLpOleChar
bstProgID = LpOleChar2BSTR(lngLpOleChar)
MsgBox bstProgID
End Sub
Private Function LpOleChar2BSTR(ByVal lp As Long) As String
Dim lngLpOleStr As Long
lngLpOleStr = lp
Dim bstReturn As String
If SysReAllocString(bstReturn, lp) = 0& Then
Err.Raise 7&
End If
CoTaskMemFree lp
bstReturn = StrConv(bstReturn, vbFromUnicode)
LpOleChar2BSTR = bstReturn
End Function
...да и по проще это IMHO.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
ZAM>The lstrcpyn function has an undefined behavior if source and destination buffers overlap.
Где ты узрел пересечение буферов? ZAM>и там ещё Security Alert есть...
Всегда надо осознавать, что делаешь. Такой Security Alert можно написать на и на memcpy, и на операцию разыменования указателя.
Здравствуйте, Бенедикт, Вы писали:
Б>Здравствуйте, ZAMUNDA, Вы писали:
ZAM>>MSDN: ZAM>>
ZAM>>The lstrcpyn function has an undefined behavior if source and destination buffers overlap.
Б>Где ты узрел пересечение буферов?
Не в этом дело. Эта функция небезопасна и могжет кинуть AV если что, особенно при отладке. Да и ладно вопщим, но зачем тогда нужна lstrcpyn, когда есть более шустрая RtlMoveMemory?
Да и вообще неясно зачем надо использовать две сложные функции, дополнительные буффера, преобразование из BSTR в CS-String, когда можно делать всё одной функцией, которая из Automation API, не вызывает исключений и работает с BSTR напрямую?
ZAM>>и там ещё Security Alert есть... Б>Всегда надо осознавать, что делаешь. Такой Security Alert можно написать на и на memcpy,
Security Alert это было, к слову... впрочем удар защитан: Каюсь, простите несмышлённого.
Б>и на операцию разыменования указателя.
Такой операции в VB/VBA/VBS нет. ;-)
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[2]: Помогите запустить функцию ProgIDFromCLSID в VBA
Здравствуй, Бенедикт! Спасибо за ответ.
Создал по твоим указаниям функцию:
Private Sub Command1_Click()
Dim Result As Long
Dim clsid As TGUID
Dim lpszProgID As Long
Result = CLSIDFromString(StrPtr("{D3E34B21-9D75-101A-8C3D-00AA001A1652}"), clsid)
GoSub Ansver
Result = CLSIDFromString(StrPtr("{851A4561-F4EC-4631-9B0C-E7DC407512C9}"), clsid) '"AutoCAD2007"
GoSub Ansver
Result = CLSIDFromString(StrPtr("{1EFD8E85-7F3B-48E6-9341-3C8B2F60136B}"), clsid) '"AutoCAD2006"
GoSub Ansver
Result = CLSIDFromString(StrPtr("{93BC4E71-AFE7-4AA7-BC07-F80ACDB672D5}"), clsid) '"AutoCAD2004"
GoSub Ansver
Result = CLSIDFromString(StrPtr("{8E75D910-3D21-11D2-85C4-080009A0C626}"), clsid) '"AutoCAD2002"
GoSub Ansver
Result = CLSIDFromString(StrPtr("{C094C1E2-57C6-11D2-85E3-080009A0C626}"), clsid) '"AutoCAD2000"
GoSub Ansver
Exit Sub
Ansver:
If Result = NOERROR Then
Result = ProgIDFromCLSID(clsid, lpszProgID)
If Result = NOERROR Then
Debug.Print LPWSTR2String(lpszProgID)
CoTaskMemFree lpszProgID
End If
End If
Return
End Sub
Но эта функция выдаёт только Paint.Picture
А про AutoCAD ничего не выдаёт, однако у меня на компютере AutoCAD20002 и AutoCAD2006. В чём может быть ошибка?
Re[3]: Маньяки вы все... <8-(
От:
Аноним
Дата:
31.10.06 15:58
Оценка:
Здравствуй, ZAMUNDA!
Спасибо за ответ!
По твоим указаниям сделал программу:
Public Sub main()
Dim Result As Long
Dim udtGUID As TGUID
' With udtGUID
' .Data1 = &HD43FE01
' .Data2 = &HF093
' .Data3 = &H11CF
' .Data4(0) = &H89
' .Data4(1) = &H40
' .Data4(2) = &H0
' .Data4(3) = &HA0
' .Data4(4) = &HC9
' .Data4(5) = &H5
' .Data4(6) = &H42
' .Data4(7) = &H28
' End With
Result = CLSIDFromString(StrPtr("{D3E34B21-9D75-101A-8C3D-00AA001A1652}"), udtGUID)
GoSub Ansver
Result = CLSIDFromString(StrPtr("{851A4561-F4EC-4631-9B0C-E7DC407512C9}"), udtGUID) '"AutoCAD2007"
GoSub Ansver
Result = CLSIDFromString(StrPtr("{1EFD8E85-7F3B-48E6-9341-3C8B2F60136B}"), udtGUID) '"AutoCAD2006"
GoSub Ansver
Result = CLSIDFromString(StrPtr("{93BC4E71-AFE7-4AA7-BC07-F80ACDB672D5}"), udtGUID) '"AutoCAD2004"
GoSub Ansver
Result = CLSIDFromString(StrPtr("{8E75D910-3D21-11D2-85C4-080009A0C626}"), udtGUID) '"AutoCAD2002"
GoSub Ansver
Result = CLSIDFromString(StrPtr("{C094C1E2-57C6-11D2-85E3-080009A0C626}"), udtGUID) '"AutoCAD2000"
GoSub Ansver
Exit Sub
Ansver:
Dim bstProgID As String
Dim lngLpOleChar As Long
ProgIDFromCLSID udtGUID, lngLpOleChar
bstProgID = LpOleChar2BSTR(lngLpOleChar)
MsgBox bstProgID
Return
End Sub
Кстати тип GIUD компилятор не понимает, наверное ключевое слово. Пришлось примеить TGUID.
Выдаёт сообщения только Paint.Picture а остальные месаджи пустые, однако у меня на компьютере есть AutoCAD20002 и AutoCAD2007. Почему так происходит помоги разобраться!
Здравствуйте, Аноним, Вы писали:
А>По твоим указаниям сделал программу:
А> Result = CLSIDFromString(StrPtr("{D3E34B21-9D75-101A-8C3D-00AA001A1652}"), udtGUID)
А скажи мне, зачем тебе надо этот CLSID и из него получать ProgID? Ведь у всех COM'ов есть Version Independent ProgID, который от версии к версии не меняется.
А>Кстати тип GIUD компилятор не понимает, наверное ключевое слово. Пришлось примеить TGUID.
Странно... У меня в MSO2k работает.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[3]: Помогите запустить функцию ProgIDFromCLSID в VBA
[код skipped] MVB>Но эта функция выдаёт только Paint.Picture MVB>А про AutoCAD ничего не выдаёт, однако у меня на компютере AutoCAD20002 и AutoCAD2006. В чём может быть ошибка?
В том, что GUIDы предназначены для идентификации многих вещей. Даже есть их специальные сокращения. Например, CLSID — это GUID COM-объекта, IID — это GUID интерфейса, LIBID — это GUID библиотеки типов (то, что подключается в References), CATID — это GUID катагорий и т.п. и т.д.
ProgID соответствует только CLSIDу, поэтому не нужно вместо CLSID использовать LIBID — такого соответствия нет и быть не может.
PS
Используй теги форматирования, если уважаешь собеседников.
Здравствуйте, MishaVBA, Вы писали:
MVB>Здравствуй, Бенедикт! Спасибо за ответ. MVB>Создал по твоим указаниям функцию: MVB><skipped> MVB>Но эта функция выдаёт только Paint.Picture MVB>А про AutoCAD ничего не выдаёт, однако у меня на компютере AutoCAD20002 и AutoCAD2006. В чём может быть ошибка?
В том, что ты не CLSID передаёшь в функцию. Я нашёл компьютер с установленным AutoCAD-ом, попробуй CLSID {8E75D913-3D21-11D2-85C4-080009A0C626}. Должно получиться что-то вроде "AutoCAD.Drawing.15".
Если у тебя есть установленная Visual Studio или Platform SDK, воспользуйся утилитой OleView, чтобы разобраться, какие есть CLSID и ProgID.
Re[4]: Помогите запустить функцию ProgIDFromCLSID в VBA
От:
Аноним
Дата:
01.11.06 15:58
Оценка:
Здравствуй, Бенедикт, Вы писали:
Б>В том, что ты не CLSID передаёшь в функцию. Я нашёл компьютер с установленным AutoCAD-ом, попробуй CLSID {8E75D913-3D21-11D2-85C4-080009A0C626}. Должно получиться что-то вроде "AutoCAD.Drawing.15".
Да действительно у меня получилось:
Private Sub Command1_Click()
Dim Result As Long
Dim clsid As TGUID
Dim lpszProgID As Long
Result = CLSIDFromString(StrPtr("{D3E34B21-9D75-101A-8C3D-00AA001A1652}"), clsid)
GoSub Ansver
Result = CLSIDFromString(StrPtr("{851A4561-F4EC-4631-9B0C-E7DC407512C9}"), clsid) '"AutoCAD2007"
GoSub Ansver
Result = CLSIDFromString(StrPtr("{1EFD8E85-7F3B-48E6-9341-3C8B2F60136B}"), clsid) '"AutoCAD2006"
GoSub Ansver
Result = CLSIDFromString(StrPtr("{93BC4E71-AFE7-4AA7-BC07-F80ACDB672D5}"), clsid) '"AutoCAD2004"
GoSub Ansver'{8E75D913-3D21-11D2-85C4-080009A0C626}
Result = CLSIDFromString(StrPtr("{8E75D913-3D21-11D2-85C4-080009A0C626}"), clsid) '"AutoCAD2002"
GoSub Ansver
Result = CLSIDFromString(StrPtr("{C094C1E2-57C6-11D2-85E3-080009A0C626}"), clsid) '"AutoCAD2000"
GoSub Ansver
Exit Sub
Ansver:
If Result = NOERROR Then
Result = ProgIDFromCLSID(clsid, lpszProgID)
If Result = NOERROR Then
Debug.Print LPWSTR2String(lpszProgID)
CoTaskMemFree lpszProgID
End If
End If
Return
End Sub
И Вы правы наверное я путаю CLSID с LIBID. Мне для программы VBA надо подключать различные библиотеки в референсе используя ComboBox.
Чтобы быстро объяснить в чём суть дела я скопирую текст моего сообщения с форума: http://www.autocad.ru/cgi-bin/f1/board.cgi?t=30875Kz
=============================================================================================
Private Sub Workbook_Open()
Dim objReference As Object
Dim intКолвоБиблиотек As Integer
If ПризнакНаличияВерсииAutoCAD("{851A4561-F4EC-4631-9B0C-E7DC407512C9}") Then ActiveWorkbook.Sheets(1).ComboBox1_ВерсияAutoCAD.AddItem "AutoCAD2007"
If ПризнакНаличияВерсииAutoCAD("{1EFD8E85-7F3B-48E6-9341-3C8B2F60136B}") Then ActiveWorkbook.Sheets(1).ComboBox1_ВерсияAutoCAD.AddItem "AutoCAD2006"
If ПризнакНаличияВерсииAutoCAD("{93BC4E71-AFE7-4AA7-BC07-F80ACDB672D5}") Then ActiveWorkbook.Sheets(1).ComboBox1_ВерсияAutoCAD.AddItem "AutoCAD2004"
If ПризнакНаличияВерсииAutoCAD("{8E75D910-3D21-11D2-85C4-080009A0C626}") Then ActiveWorkbook.Sheets(1).ComboBox1_ВерсияAutoCAD.AddItem "AutoCAD2002"
If ПризнакНаличияВерсииAutoCAD("{C094C1E2-57C6-11D2-85E3-080009A0C626}") Then ActiveWorkbook.Sheets(1).ComboBox1_ВерсияAutoCAD.AddItem "AutoCAD2000"
On Error GoTo ОбработкаОшибок
' Set objReference = Application.VBE.ActiveVBProject.References
ПодключитьБиблиотеку:
Select Case ActiveWorkbook.Sheets(1).ComboBox1_ВерсияAutoCAD
Case "AutoCAD2007" 'Подключение библиотеки типов AutoCAD2007
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{851A4561-F4EC-4631-9B0C-E7DC407512C9}", 1, 0)
Case "AutoCAD2006" 'Подключение библиотеки типов AutoCAD2006
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{1EFD8E85-7F3B-48E6-9341-3C8B2F60136B}", 1, 1)
Case "AutoCAD2004" 'Подключение библиотеки типов AutoCAD2004
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{93BC4E71-AFE7-4AA7-BC07-F80ACDB672D5}", 1, 1)
Case "AutoCAD2002" 'Подключение библиотеки типов AutoCAD2002
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{8E75D910-3D21-11D2-85C4-080009A0C626}", 1, 1)
Case "AutoCAD2000" 'Подключение библиотеки типов AutoCAD2000
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{C094C1E2-57C6-11D2-85E3-080009A0C626}", 1, 1)
End Select
gstrНачВерсияAutoCAD = ActiveWorkbook.Sheets(1).Range("ВерсияAutoCAD")
Exit Sub
ОбработкаОшибок:
If Err.Number = -2147319779 Then
If ActiveWorkbook.Sheets(1).ComboBox1_ВерсияAutoCAD.ListIndex < ActiveWorkbook.Sheets(1).ComboBox1_ВерсияAutoCAD.ListCount Then
ActiveWorkbook.Sheets(1).ComboBox1_ВерсияAutoCAD.ListIndex = ActiveWorkbook.Sheets(1).ComboBox1_ВерсияAutoCAD.ListIndex + 1
Else
ActiveWorkbook.Sheets(1).ComboBox1_ВерсияAutoCAD.ListIndex = 0
End If
intКолвоБиблиотек = intКолвоБиблиотек + 1
If intКолвоБиблиотек < 5 Then GoTo ПодключитьБиблиотеку
ElseIf Err.Number <> 32813 Then
MsgBox "При подключении библиотеки произошла ОШИБКА!" & vbLf & vbLf & _
"Номер ошибки = " & Err.Number & vbLf & vbLf & _
"Описание ошибки: " & Err.Description, vbExclamation, gstrНазваниеПрограммы
End If
Resume Next
End Sub
Private Function ПризнакНаличияВерсииAutoCAD(strGUID As String) As Boolean
Dim lplpszProgID As String, lngОтвет As Long
Dim lngT As Long
ProgIDFromCLSID strGUID, lplpszProgID
lngОтвет = CLSIDFromProgID(strGUID, lngT)
If Len(lplpszProgID) > 0 Then
' If lngОтвет = -2147024809 Then
ПризнакНаличияВерсииAutoCAD = True
Else
ПризнакНаличияВерсииAutoCAD = True
End If
End Function
Сейчас при открытии Excel в ComboBox заполняются все версии AutoCAD, но некоторых нет на моём компютере. На одной из конференций мне посоветовали использовать для этих целей функцию CLSIDFromProgID(strGUID, lngT) я понял что она делает всё наоборот: выдаёт GUID по известному названию приложения, но всё равно решил попробовать её использовать. И эффект для обоих функций одинаковый: для разных версий AutoCAD они выдают одинаковый ответ, то есть этот ответ не меняется при смене версий AutoCAD. Но чтобы хоть как то работать я сделал чтобы функция всегда выдавала ИСТИНА. Мне надо научить мою функцию правильно разбираться какие версии установлены на компьтере а какие нет.
Описание функций API следующее:
Public Declare Sub ProgIDFromCLSID Lib "ole32" _
(ByVal clsid As String, _
ByVal lplpszProgID As String)
Public Declare Function CLSIDFromProgID Lib "ole32.dll" (ByRef TSzProgID As String, ByRef T As Long) As Long
Работа с ComboBoxom усуществляется следующими функциями:
Private Sub ComboBox1_ВерсияAutoCAD_Change()
Dim objReference As Object
On Error GoTo ОбработкаОшибок
If blnПризнакИзмененияВерсии = False Then
'Отключим библиотеку не используемой версии AutoCAD
Select Case gstrНачВерсияAutoCAD
Case "AutoCAD2000" 'Отключение библиотеки типов AutoCAD2000
Application.VBE.ActiveVBProject.References.Remove (ReferenceFromGuid("{C094C1E2-57C6-11D2-85E3-080009A0C626}"))
Case "AutoCAD2002" 'Отключение библиотеки типов AutoCAD2002
Application.VBE.ActiveVBProject.References.Remove (ReferenceFromGuid("{8E75D910-3D21-11D2-85C4-080009A0C626}"))
Case "AutoCAD2004" 'Отключение библиотеки типов AutoCAD2004
Application.VBE.ActiveVBProject.References.Remove (ReferenceFromGuid("{93BC4E71-AFE7-4AA7-BC07-F80ACDB672D5}"))
Case "AutoCAD2006" 'Отключение библиотеки типов AutoCAD2006
Application.VBE.ActiveVBProject.References.Remove (ReferenceFromGuid("{1EFD8E85-7F3B-48E6-9341-3C8B2F60136B}"))
Case "AutoCAD2007" 'Отключение библиотеки типов AutoCAD2007
Application.VBE.ActiveVBProject.References.Remove (ReferenceFromGuid("{851A4561-F4EC-4631-9B0C-E7DC407512C9}"))
End Select
'Подключим библиотеку используемой версии AutoCAD
Select Case ComboBox1_ВерсияAutoCAD
Case "AutoCAD2007" 'Подключение библиотеки типов AutoCAD2007
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{851A4561-F4EC-4631-9B0C-E7DC407512C9}", 1, 0)
If TypeOf objReference Is Object Then
If Not objReference.isbroken Then MsgBox "AutoCAD2007 подключён", vbInformation, gstrНазваниеПрограммы
End If
Case "AutoCAD2006" 'Подключение библиотеки типов AutoCAD2006
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{1EFD8E85-7F3B-48E6-9341-3C8B2F60136B}", 1, 1)
If TypeOf objReference Is Object Then
If Not objReference.isbroken Then MsgBox "AutoCAD2006 подключён", vbInformation, gstrНазваниеПрограммы
End If
Case "AutoCAD2004" 'Подключение библиотеки типов AutoCAD2004
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{93BC4E71-AFE7-4AA7-BC07-F80ACDB672D5}", 1, 1)
If TypeOf objReference Is Object Then
If Not objReference.isbroken Then MsgBox "AutoCAD2004 подключён", vbInformation, gstrНазваниеПрограммы
End If
Case "AutoCAD2002" 'Подключение библиотеки типов AutoCAD2002
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{8E75D910-3D21-11D2-85C4-080009A0C626}", 1, 1)
If TypeOf objReference Is Object Then
If Not objReference.isbroken Then MsgBox "AutoCAD2002 подключён", vbInformation, gstrНазваниеПрограммы
End If
Case "AutoCAD2000" 'Подключение библиотеки типов AutoCAD2000
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{C094C1E2-57C6-11D2-85E3-080009A0C626}", 1, 1)
If TypeOf objReference Is Object Then
If Not objReference.isbroken Then MsgBox "AutoCAD2000 подключён", vbInformation, gstrНазваниеПрограммы
End If
End Select
blnПризнакИзмененияВерсии = False
End If
Exit Sub
ОбработкаОшибок:
If Err.Number = -2147319779 Then
MsgBox "Версия " & ComboBox1_ВерсияAutoCAD & " отсутствует на компьютере", vbInformation, gstrНазваниеПрограммы
blnПризнакИзмененияВерсии = True
ComboBox1_ВерсияAutoCAD = gstrНачВерсияAutoCAD
Err.Clear
Select Case ComboBox1_ВерсияAutoCAD
Case "AutoCAD2007" 'Подключение библиотеки типов AutoCAD2007
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{851A4561-F4EC-4631-9B0C-E7DC407512C9}", 1, 0)
Case "AutoCAD2006" 'Подключение библиотеки типов AutoCAD2006
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{1EFD8E85-7F3B-48E6-9341-3C8B2F60136B}", 1, 1)
Case "AutoCAD2004" 'Подключение библиотеки типов AutoCAD2004
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{93BC4E71-AFE7-4AA7-BC07-F80ACDB672D5}", 1, 1)
Case "AutoCAD2002" 'Подключение библиотеки типов AutoCAD2002
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{8E75D910-3D21-11D2-85C4-080009A0C626}", 1, 1)
Case "AutoCAD2000" 'Подключение библиотеки типов AutoCAD2000
Set objReference = Application.VBE.ActiveVBProject.References.AddFromGuid("{C094C1E2-57C6-11D2-85E3-080009A0C626}", 1, 1)
End Select
blnПризнакИзмененияВерсии = False
Exit Sub
ElseIf Err.Number <> 32813 Then
MsgBox "При подключении новой библиотеки произошла ОШИБКА!" & vbLf & vbLf & _
"Номер ошибки = " & Err.Number & vbLf & vbLf & _
"Описание ошибки: " & Err.Description, vbExclamation, gstrНазваниеПрограммы
End If
Resume Next
End Sub
Private Sub ComboBox1_ВерсияAutoCAD_Click()
gstrНачВерсияAutoCAD = ComboBox1_ВерсияAutoCAD
blnПризнакИзмененияВерсии = False
End Sub
Помогите правильно настроить ComboBox
Кстати я понял что все эти проблемы по сути своей надуманные и этих проблем моглы бы совсем не быть и не надо было бы использовать позднее связывание затрудняющее жизнь и творчество программистов если бы фирма Microsoft продолжила свой правильный курс по использованию GUID. Я где то читал, что GUID нужен для того чтобы пользователь как раз не имел проблем с подключением библиотек, а компютер сам бы определял какие библиотеки надо присоединить по названию приложения или по его GUID. Но кто-то решил использовать GUID не всего приложения, а для каждой библиотеки в отдельности. Поэтому теперь весь мир и мучается с подключением нужных библиотек. Это проделки врагов человечества тормозящих научно-технический прогресс. В самом деле неужели нельзя компьтер научить определять какая библиотека из всего списка библиотек сейчас требуется и подключть эту библиотеку чтобы программа Excel могла работать с работающей в данный момент версией AutoCAD. В лучшем варианте я бы хотел научить Excel именно это и делать:
1) запускаю Excel
2) даю команду обратиться к AutoCAD
3) Excel определяет какая версия AutoCAD сейчас работает (замечу что AutoCAD2007 и AutoCAD2000i могут одновремено работать вместе и находиться на панели задач, но фишка в том, что если библиотеки AutoCAD2000i пытаются обратиться к AutoCAD2007 то запускается бесконечное множество процессов Acad.exe и компьютер виснет. Этого я и хочу научиться избегать)
4) Excel отключает дежурную библиотеку (ранее подключеную)
5) Excel подключает библиотеку AutoCAD2007
6) Excel обращается к AutoCAD2007 без проблем.
Замечу что если библиотека AutoCAD2007 пытается обратиться к AutoCAD2000i то компютер виснет быстрее так как процессы Acad.exe2007 по видимому дольше загружаются и занимают больше места в памяти.
Помогите пожалуйста разобраться со всеми этими проблемами и если всё получится, то можно получить какой-нибудь приз от фирмы Microsoft!
Жду ответов уважаемый Александр Баусук!
Убедительная просьба ко всем: Помогите правильно запустить функции:
ProgIDFromCLSID
CLSIDFromProgID
=================================================================================
Вы правы мне надо получить название библиотеки наверное используя LIBID потому что для всех часто встречающихся версий LIBID библиотек мне известны, а вот найти GUID всех версий мне трудно и бывает так как у меня на компютере дома: Запускаю AutoCAD2002 а библиотека в списке Reference AutoCAD2000 Type Lybrari. Помогите пожалуйста определять наличие библиотек на компютере по известному LIBID.
Если у Вас есть другие предложения, то я могу определить GUID только для AutoCAD2000, 2000i, 2006, 2007.
Но лучше работать с LIBID библиотек чтобы избежать путаницы несоответствий версий AutoCAD и установленных библиотек. И программа на VBA компилируется в зависимости от версии библиотеки наверное в первую очередь, а не от версии AutoCAD. Моё предположение такое, что эти несоответствия возникают иногда из-за разных способов локализации или русификации версий AutoCAD.
Помогите пожалуйста БЕНЕДИКТ! Очень жду Вашего ответа!
Re[5]: Помогите запустить функцию ProgIDFromCLSID в VBA
Наверное, я не до конца уловил, чего ты хочешь, и зачем нужен комбо-бокс.
Похоже, компания Autodesk написала несовместимые Type Library и дала им разные GUID-ы (насколько я понял из твоего кода — у меня нет компьютера с установленными разными версиями AutoCAD-а) — ну, были, наверное, причины (но причём здесь Microsoft?). Идея у кода вроде правильная — идём по GUID-ам библиотек типов и версиям совместимых библиотек от более поздних к более ранним, находим, какая подцепилась (при условии, что VBA-шный код работы с объектами этой библиотеки не зависит от версии). Информация о зарегистрированных библиотеках типов хранится в реестре, уже упомянутая мной утилита OleView предоставляет её в удобоваримом виде. Попробуй найти файл OleView.exe где-нибудь, и посмотри информацию в ветке "Type Libraries". Может, библиотеки типов у 2000-го и 2002-го всё-таки совместимые, и надо 2-м и 3-м параметром AddFromGuid крутить при одинаковом 1-м (например, на том компьютере, что у меня, есть две совместимых библиотеки с GUID {C094C1E2-57C6-11D2-85E3-080009A0C626}, версии 1.1 и 1.2. Т.е., следовало бы сначала попробовать AddFromGuid("{C094C1E2-57C6-11D2-85E3-080009A0C626}", 1, 2), затем, при неудаче, AddFromGuid("{C094C1E2-57C6-11D2-85E3-080009A0C626}", 1, 1)), или в реестре мусор остался после удаления 2000-го, или не зарегистрирована библиотека типов 2002-го... Отлаживать надо, смотреть в конкретных условиях, почему не работает.
P.S. Почему objReference As Object, а не As Reference при такой нелюбви к позднему связыванию?
Re[4]: Помогите запустить функцию ProgIDFromCLSID в VBA
Здравствуй, Vi2
Vi2>Здравствуйте, MishaVBA, Вы писали:
Vi2>[код skipped] MVB>>Но эта функция выдаёт только Paint.Picture MVB>>А про AutoCAD ничего не выдаёт, однако у меня на компютере AutoCAD20002 и AutoCAD2006. В чём может быть ошибка?
Vi2>В том, что GUIDы предназначены для идентификации многих вещей. Даже есть их специальные сокращения. Например, CLSID — это GUID COM-объекта, IID — это GUID интерфейса, LIBID — это GUID библиотеки типов (то, что подключается в References), CATID — это GUID катагорий и т.п. и т.д.
Vi2>ProgID соответствует только CLSIDу, поэтому не нужно вместо CLSID использовать LIBID — такого соответствия нет и быть не может.
Помоги использовать LIBID вместо GUID. Как это делается?
Vi2>PS Vi2>Используй теги форматирования, если уважаешь собеседников.
А где находятся эти тэги форматирования?
Re[6]: Помогите запустить функцию ProgIDFromCLSID в VBA
Насчёт совместимости библиотек, мне кажется, что библиотеки в некотором смысле совместимые, потому что моя программа работает при любых библиотеках. Просто AutoCADу надо было бы сделать менеджер библиотек, который сам бы определял к какой библиотеке надо подключать Excel перед комптляцией кода. А пользователям давать не ссылку на библиотеку а ссылку на менеджер, тогда бы не было проблем с отсутствующими библиотеками при установленном AutoCAD на компьютере.
Б>P.S. Почему objReference As Object, а не As Reference при такой нелюбви к позднему связыванию?
Oblect я использовал, чтобы в просмотровщике переменных прочитать GUIDы или LIBIDы подключенных библиотек
Мне Vi2 написал:
"GUIDы предназначены для идентификации многих вещей. Даже есть их специальные сокращения. Например, CLSID — это GUID COM-объекта, IID — это GUID интерфейса, LIBID — это GUID библиотеки типов (то, что подключается в References), CATID — это GUID катагорий и т.п. и т.д.
ProgID соответствует только CLSIDу, поэтому не нужно вместо CLSID использовать LIBID — такого соответствия нет и быть не может."
А чем отличается работа c LIBID от GUID, надо наверное поменять тип переменной и используемую функцию? Может быть в этом причина того, что программа не находит установленые библиотеки?
Re[5]: Помогите запустить функцию ProgIDFromCLSID в VBA
Здравствуйте, MishaVBA, Вы писали:
Vi2>>ProgID соответствует только CLSIDу, поэтому не нужно вместо CLSID использовать LIBID — такого соответствия нет и быть не может. MVB>Помоги использовать LIBID вместо GUID. Как это делается?
Еще раз скажу: невозможно использовать GUID, именуемый LIBID (идентифицирующий библиотеку типов некоего СОМ объекта), вместо GUID, именуемого CLSID (идентифицирующего сам этот СОМ объект).
С другой стороны, читая твою проблему, не могу не отметить, что Application.VBE.ActiveVBProject.References.AddFromGuid("{LIBID}") вернет ошибку, если такой библиотеки типов не будет в Реестре, следовательно, и АвтоКада такого не установлено. Затем можно удалить эту референсу, чтобы не плодить их, и подключить только выбранную.
MVB>А где находятся эти тэги форматирования?
Внизу окна нового сообщения. Или руками [vb] и [/vb]. Еще есть масса ключевых тегов вместо vb.
Здравствуйте, MishaVBA, Вы писали:
MVB>Насчёт совместимости библиотек, мне кажется, что библиотеки в некотором смысле совместимые, потому что моя программа работает при любых библиотеках.
Может быть совместимость по именам, но не быть двоичной совместимости. Третий раз говорю: установи OLE/COM Viewer. Нельзя помочь человеку, если он сам этого не хочет.
MVB>Просто AutoCADу надо было бы сделать менеджер библиотек, который сам бы определял к какой библиотеке надо подключать Excel перед комптляцией кода. А пользователям давать не ссылку на библиотеку а ссылку на менеджер, тогда бы не было проблем с отсутствующими библиотеками при установленном AutoCAD на компьютере.
??? Без комментариев.
Б>>P.S. Почему objReference As Object, а не As Reference при такой нелюбви к позднему связыванию?
MVB>Oblect я использовал, чтобы в просмотровщике переменных прочитать GUIDы или LIBIDы подключенных библиотек
Можно описывать как As Reference, тогда не будет позднего связывания при, например, обращении к Reference.IsBroken. Подключи к проету библиотеку "Microsoft Visual Basic for Applications Extensibility", если ещё не подключена.
MVB>Мне Vi2 написал: MVB><skipped> MVB>А чем отличается работа c LIBID от GUID, надо наверное поменять тип переменной и используемую функцию? Может быть в этом причина того, что программа не находит установленые библиотеки?
LIBID, IID, CLSID — частные виды GUID. Т. е. можно и переменные, и параметры функций описывать как GUID, но работать с ними, представляя, что это конкретный частный случай GUID. Если ты пока путаешься, описывай LIBID и иже как UDT такой же структуры, как и GUID, т. е.
Private Type TGUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Private Type LIBID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
, и используй в описаниях переменных и параметров функций ужЕ LIBID (если есть функция в DLL, которая может принимать GUID-ы разных видов, можно воспользоваться конструкцией Alias в описании Declare, чтобы получить "разные" виды этой функции). С точки зрения строгой типизации этот подход даже более правильный. С точки зрения двоичного вида они одинаковые, и способа сказать, какого подвида этот GUID, кроме как порывшись в h-никах и реестре в надежде что-то выяснить, нет. Поэтому если ты передашь функции неправильный параметр типа GUID, то она, естественно, ничего не найдёт, но не скажет — "э, нет, это не LIBID".
Бери в руки OLE/COM Viewer, вставляй в VBA-шный код кучу Debug.Print-ов, и смотри, что происходит.
Re[8]: Помогите запустить функцию ProgIDFromCLSID в VBA
Б>Бери в руки OLE/COM Viewer, вставляй в VBA-шный код кучу Debug.Print-ов, и смотри, что происходит.
Очень интересная программа OLE/COM Viewer! Я так понял она мне нужна чтобы правильно определить GUIDы различных версий AutoCAD?
Это можно сделать. Правда теперь я маленько понимаю, что LIBID это не совсем PROGID и чтобы определить наличие LIBID функция ProgIDFromCLSID не совсем подходит. Наверное надо написать самому функцию TypeLibFromLIBID используя функции работы с реестром. Вот только какие функции надо использовать, какие задавать параметры (а именно в какой ветке реестра искать LIBIDы) и в какой последовательности вызывать эти функции? Помогите пожалуйста разобраться.