Здравствуйте.
Появилась необходимость создавать COM-объект на OLE-сервере и возвращать его клиенту VBA. Причём всё делать при позднем связывании. То есть я создаю и внедряю OLE-сервер в документ MS Word:
Dim MyObj As Object
Set MyObj = Selection.InlineShapes.AddOLEObject ClassType:="MyOLEServer.Document", _
FileName:="", LinkToFile:=False, DisplayAsIcon:=False
Далее, добавляю метод документу на создание ATL-объекта (соответственно и сам ATL-объект с интерфейсом и коклассом через мастер):
IMyClass* CMyOLEServerDoc::CreateMyClassObj(LONG)
{
AFX_MANAGE_STATE(AfxGetAppModuleState());
CComObject<CMyClass> *myClass;
CComObject<CMyClass>::CreateInstance(&myClass);
myClass->QueryInterface(&iMyClass);
return iMyClass;
}
iMyClass объявлена в классе CMyOLEServerDoc как CComPtr<IMyClass> iMyClass.
И когда в VBA запускаю на выполнение:
Dim MyObj As Object
Set MyObj = Selection.InlineShapes.AddOLEObject ClassType:="MyOLEServer.Document", _
FileName:="", LinkToFile:=False, DisplayAsIcon:=False
Dim myClass As Object
Set myClass = MyObj.OLEFormat.Object.CreateMyClassObj(123)
то ругается на последнюю строчку и выдаёт ошибку "Object required". Что я делаю не так? Как всегда прошу ответить мне кодом с комментариями
P. S. Эта штука работает при раннем связывании, когда объявляю myClass как MyOLEServer.MyClass.
Здравствуйте, Аноним, Вы писали:
А>Далее, добавляю метод документу на создание ATL-объекта (соответственно и сам ATL-объект с интерфейсом и коклассом через мастер):
А>IMyClass* CMyOLEServerDoc::CreateMyClassObj(LONG)
А>{
А> AFX_MANAGE_STATE(AfxGetAppModuleState());
А> CComObject<CMyClass> *myClass;
А> CComObject<CMyClass>::CreateInstance(&myClass);
А> myClass->QueryInterface(&iMyClass);
А> return iMyClass;
А>}
Что-то мне не верится, что такой метод можно сделать мастером, причем в АТЛ. Стандарт СОМ требует, чтобы методы были HRESULT f(параметры). Поэтому не плохо бы привести код и способ вызова этого метода из обработчика IDispatch::Invoke.
PS
То, что возвращаемое значение (return iMyClass) как простой указатель интерфейса не обладает увеличенной ссылкой, учитывается?
Здравствуйте, Vi2, Вы писали:
Vi2>Что-то мне не верится, что такой метод можно сделать мастером, причем в АТЛ. Стандарт СОМ требует, чтобы методы были HRESULT f(параметры). Поэтому не плохо бы привести код и способ вызова этого метода из обработчика IDispatch::Invoke.
MyClass создан как ATL-объект. А в интерфейс класса CMyOLEServerDoc добавлен метод CreateMyClassObj, который должен создавать (опять неправильно выражаюсь) объект класса MyClass (или указатель на него, или указатель на его интерфейс
)
Vi2>PS
Vi2>То, что возвращаемое значение (return iMyClass) как простой указатель интерфейса не обладает увеличенной ссылкой, учитывается?
Здравствуйте, Аноним, Вы писали:
А>MyClass создан как ATL-объект. А в интерфейс класса CMyOLEServerDoc добавлен метод CreateMyClassObj, который должен создавать (опять неправильно выражаюсь) объект класса MyClass (или указатель на него, или указатель на его интерфейс )
Этот метод "IMyClass* CMyOLEServerDoc::CreateMyClassObj(LONG)" нельзя вызвать из интерфейса напрямую. Его может вызвать только код обработчика IDispatch::Invoke. Вот и покажи, как ты говоришь этому обработчику, что и как вызвать при вызове клиентом CreateMyClassObj. Скорее всего, дело может быть в магических константах.
Кстати, и обработчик QueryInterface тоже, потому что вполне возможно, что в VB при "Dim myClass As Object" и "Dim myClass As MyClass" запрашиваются разные интерфейсы у объекта с правой стороны присваивания, и один из них не поддерживается.