Я хочу организовать прием событий идущих от COM объекта загруженного в OleConteiner. Обработка события будет происходить в Invoke.
Для начала реализовала класс:
//календарь C:\Program Files\Microsoft Office\OFFICE11\MSCAL.OCX
//календарь имеет интрефейс событий DCalendarEvents
//сам код:
//clsid получу от OleConteiner
IConnectionPointContainer* pICPC = NULL;
CoCreateInstance(clsid, NULL, CLSCTX_SERVER, IID_IConnectionPointContainer, (void**)&pICPC);
IConnectionPoint * pCP = NULL;
//здесь первым параметром в FindConnectionPoint надо писать IID_IDispatch или DIID календаря DIID_DCalendarEvents?
pICPC->FindConnectionPoint(Что тут?, &pCP);
ULONG cookie;
//что передать в g_sink(...)?
CMyCoolEventHandler g_sink(Что тут?);
pCP->Advise(&g_sink, &cookie);
//и дальше что пичать?
Здравствуйте, Kitty, Вы писали:
K>Я хочу организовать прием событий идущих от COM объекта загруженного в OleConteiner. Обработка события будет происходить в Invoke. K>Помогите, пожалуйста, написать код клиента:
K>//календарь C:\Program Files\Microsoft Office\OFFICE11\MSCAL.OCX
K>//календарь имеет интрефейс событий DCalendarEvents
K>//сам код:
K>//clsid получу от OleConteiner
K>IConnectionPointContainer* pICPC = NULL;
K>CoCreateInstance(clsid, NULL, CLSCTX_SERVER, IID_IConnectionPointContainer, (void**)&pICPC);
Так контрол не создается — его тоже нужно запрашивать у контейнера, так же как ты у него хочешь запросить clsid. Ну а дальше, получив OBJECT_WITH_EVENTS, действуй, как Аноним уже написал.
Код написанный Анонимом, мне не понятен. Что такое OBJECT_WITH_EVENTS и т.д.
Я пишу в Builder и ползуюсь книгой Трельсона.
Помогите написать приемник, например для конкретного ActiveX календаря:
Класс для соединения описан в моеем первом сообщении. Теперь пишу клиента:
//календарь C:\Program Files\Microsoft Office\OFFICE11\MSCAL.OCX
//календарь имеет интрефейс событий DCalendarEvents
//clsid полуучмла от OleConteiner-а в который загружен календарь:
AnsiString NameOfClass = OleContainer1->OleClassName;
wchar_t ConvertInID[255];
StringToWideChar(NameOfClass, ConvertInID, 255);
CLSID clsid;
CLSIDFromProgID(ConvertInID,&clsid);
IConnectionPointContainer* pICPC = NULL;
CoCreateInstance(clsid, NULL, CLSCTX_SERVER, IID_IConnectionPointContainer, (void**)&pICPC);
IConnectionPoint * pCP = NULL;
//здесь первым параметром в FindConnectionPoint надо писать IID_IDispatch или DIID календаря DIID_DCalendarEvents?
//если тут надо писать DIID_DCalendarEvents, то как его динамически получить?
pICPC->FindConnectionPoint(Что тут?, &pCP);
ULONG cookie;
//что передать в g_sink(...)?
CMyCoolEventHandler g_sink(Что тут?);
pCP->Advise(&g_sink, &cookie);
Вообщем как будет выглядеть приемник для календаря: C:\Program Files\Microsoft Office\OFFICE11\MSCAL.OCX ?
Здравствуйте, Kitty, Вы писали:
K>Код написанный Анонимом, мне не понятен. Что такое OBJECT_WITH_EVENTS и т.д. K>Я пишу в Builder и ползуюсь книгой Трельсона.
Это тот объект, который будет генерить события. Т.е. его можно было бы подставить в твой код для получения вместо pICPC:
Только я не гарантирую, что этот объект будет генерировать или работать, т.к. контролы создаются не так, а запрашиваются у OleContainer1. Как-то так или подобно:
Vi2>Только я не гарантирую, что этот объект будет генерировать или работать, т.к. контролы создаются не так, а запрашиваются у OleContainer1. Как-то так или подобно: Vi2>
Vi2>Это тебе нужно проконсультироваться у объекта OleContainer1.
Растолкуйте, пожалуйста, подробнее, что вы имеете ввиду. Что значит "контролы"?
Re[5]: Приемник событий
От:
Аноним
Дата:
14.06.07 12:45
Оценка:
Здравствуйте, Kitty, Вы писали:
K>Растолкуйте, пожалуйста, подробнее, что вы имеете ввиду. Что значит "контролы"?
IOleContainer может содержать несколько обьектов/контролов(другими словами ActiveX) не только твой календарь, поэтому нужно копать к нему через:
EnumObjects
Returns all ActiveX controls through an enumerator with IEnumUnknown, but not necessarily all objects (because there's no guarantee that all objects are ActiveX controls; some may be regular Windows controls).
Здравствуйте, Vi2, Вы писали:
Vi2>Здравствуйте, Kitty, Вы писали:
K>>Код написанный Анонимом, мне не понятен. Что такое OBJECT_WITH_EVENTS и т.д. K>>Я пишу в Builder и ползуюсь книгой Трельсона.
Vi2>Это тот объект, который будет генерить события. Т.е. его можно было бы подставить в твой код для получения вместо pICPC: Vi2>
Vi2>Только я не гарантирую, что этот объект будет генерировать или работать, т.к. контролы создаются не так, а запрашиваются у OleContainer1. Как-то так или подобно: Vi2>
Здравствуйте, Kitty, Вы писали:
K>Подскажите как получить имя произошедщего события и как можно получить его параметры? Например занести их в массив Variant.
По "DISPID dispIdMember" в вызове Invoke можно найти имя события, порывшись в библиотеке типов контрола, а в DISPPARAMS * pDispParams уже лежат упакованные и переданные параметры.
К тому же dispIdMember является хорошим синонимом для имени события.
PS
Мы уже писали о том, что обработка произвольного события произвольного контрола — занятие малоприятное.
Здравствуйте, Vi2, Вы писали:
Vi2>Здравствуйте, Kitty, Вы писали:
K>>Подскажите как получить имя произошедщего события и как можно получить его параметры? Например занести их в массив Variant.
Vi2>По "DISPID dispIdMember" в вызове Invoke можно найти имя события, порывшись в библиотеке типов контрола, а в DISPPARAMS * pDispParams уже лежат упакованные и переданные параметры.
Vi2>К тому же dispIdMember является хорошим синонимом для имени события.
Vi2>PS Vi2>Мы уже писали о том, что обработка произвольного события произвольного контрола — занятие малоприятное.
Спасибо большое за помощь!
У меня возникла проблема. Почему-то мой код работает только для календаря.
Буру, например, другие ActiveX-ы которые есть на моем компьюторе. Все они имеют диспинтерфейсы. Вот те, который брала произвольно:
"VIActiveXForm.VIForm" C:\PROGRA~1\MICROC~1\MPLABI~1\VDI\MPVDI.dll
"VCF1.VCF1Ctrl.1" C:\WINDOWS\system32\vcf132.ocx
"CERTWIZ.CertWizCtrl.1" C:\WINDOWS\system32\inetsrv\certwiz.ocx
Например пробую использовать VCF1.VCF1Ctrl.1, соотвественно код:
Не работает, не инициализируется pCP в FindConnectionPoint...
Пробовала так:
#include <VCF1.hpp>
//далее в коде
_result = pICPC->FindConnectionPoint(DIID__DVCF1Events , &pCP); тоже не работает.
Не могу понять, почему работает для календаря, а для других ActiveX-ов нет.
Растолкуйте, пожалуйста, что не так?
Здравствуйте, Vi2, Вы писали:
Vi2>Здравствуйте, Kitty, Вы писали:
K>>Не могу понять, почему работает для календаря, а для других ActiveX-ов нет. K>>Растолкуйте, пожалуйста, что не так?
Vi2>Анализируйте коды возврата при каждом обращении к методам интерфейсов — там находится вся информация.
Вообщем удалось вызвать события и для сетки VCF1.VCF1Ctrl.1.
Объект правильно надо было создать так:
CMyCoolEventHandler g_sink(DIID__DVCF1Events);
ну и вызов:
Я знаю, что есть методы читающие библиотеку типов. Подскажите примером, как я могу программно получить GUID диспинтрефейса, чтобы создовать динамически объект CMyCoolEventHandler g_sink(GUID интрефейса с событиями); ?
Здравствуйте, Kitty, Вы писали:
K>Я знаю, что есть методы читающие библиотеку типов. Подскажите примером, как я могу программно получить GUID диспинтрефейса, чтобы создавать динамически объект CMyCoolEventHandler g_sink(GUID интерфейса с событиями); ?
Теперь учить тебя — только портить.
Вот тебе слова для поиска — IProvideClassInfo (или IProvideClassInfo2), ITypeInfo::GetContainingTypeLib. Есть такая функция AtlGetObjectSourceInterface, где весь этот механизм представлен.
Здравствуйте, Vi2, Вы писали:
Vi2>Здравствуйте, Kitty, Вы писали:
K>>Я знаю, что есть методы читающие библиотеку типов. Подскажите примером, как я могу программно получить GUID диспинтрефейса, чтобы создавать динамически объект CMyCoolEventHandler g_sink(GUID интерфейса с событиями); ?
Vi2>Теперь учить тебя — только портить.
Vi2>Вот тебе слова для поиска — IProvideClassInfo (или IProvideClassInfo2), ITypeInfo::GetContainingTypeLib. Есть такая функция AtlGetObjectSourceInterface, где весь этот механизм представлен.
Спасибо за информацию, буду пробывать разобраться.