How to fire COM-event from aggregated coclass
От: slava_529872  
Дата: 15.06.05 14:26
Оценка:
Здравствуйте, коллеги!

Пороблема следующая:

Есть два СОМ-объекта. Агрегируемый и внешний. Внешний публикует несколько событий в интерфейсе:

[
dispinterface,
library_block,
uuid("01A7556D-BA02-427D-9E61-EB132F4E3836"),
helpstring("IBaseDataFeedEvents Interface")
]
__interface IBaseDataFeedEvents
{
[id(1), helpstring("method EventLevel1")] HRESULT EventLevel1([in] VARIANT guid, [in] VARIANT level1Update);
[id(2), helpstring("method EventLevel2")] HRESULT EventLevel2([in] VARIANT guid, [in] VARIANT level2Update);
[id(3), helpstring("method EventHistory")] HRESULT EventHistory([in] VARIANT guid, [in] VARIANT historyData);
};

Хочу научить внутренний (аггрегируемый) объект генерировать события внешнего. Использую MS VC++ 2003.
Ничего пока не получается.

Помогите! Спасибо!
Re: How to fire COM-event from aggregated coclass
От: sakhnik Украина http://koresha.org/sakhnik
Дата: 15.06.05 15:01
Оценка:
Здравствуйте, slava_529872, Вы писали:

_>Хочу научить внутренний (аггрегируемый) объект генерировать события внешнего. Использую MS VC++ 2003.

_>Ничего пока не получается.

По-моему, аггрегированный объект ничего не знает о его использующем. Может, следует выбрасывать событие из какого-нибудь метода интерфейса внешнего объекта? То есть, в аггрегированном:
CComQIPtr<IOuter> outer;
outer = pUnkOuter; // Указатель передаётся в CoCreateInstance
outer->FireEvent1(parm);

Во внешнем:
STDMETHODIMP COuter::FireEvent1(LONG parm)
{
    return Fire_OnEvent1(parm);
}

Жизнь — это чудо! Только вперёд: sakhnik@jabber.kiev.ua
Re[2]: How to fire COM-event from aggregated coclass
От: slava_529872  
Дата: 15.06.05 15:11
Оценка:
Здравствуйте, sakhnik, Вы писали:

S>По-моему, аггрегированный объект ничего не знает о его использующем. Может, следует выбрасывать событие из какого-нибудь метода интерфейса внешнего объекта? То есть, в аггрегированном:

S>
S>CComQIPtr<IOuter> outer;
S>outer = pUnkOuter; // Указатель передаётся в CoCreateInstance
S>outer->FireEvent1(parm);
S>

S>Во внешнем:
S>
S>STDMETHODIMP COuter::FireEvent1(LONG parm)
S>{
S>    return Fire_OnEvent1(parm);
S>}
S>


Так у меня сейчас и сделано. Событие генерирует внешний кокласс по просьбе внутреннего
Но в моём случае набор событий строго ограничен и агрегируемый кокласс всё о них знает. Т.е. он как бы является базовым для постоения на его базе других. Т.е. базовый с логической точки зрения может сгенерить событие. Но кроме указателя на внешний IUnknown у него ничего нет. Есть ли какой нужный и полезный для этого случая интерфейс у класса публикующего события...?

Je vous remercie beaucoup, monsieur!
Re[3]: How to fire COM-event from aggregated coclass
От: sakhnik Украина http://koresha.org/sakhnik
Дата: 15.06.05 15:23
Оценка:
Здравствуйте, slava_529872, Вы писали:

_>Так у меня сейчас и сделано. Событие генерирует внешний кокласс по просьбе внутреннего

_>Но в моём случае набор событий строго ограничен и агрегируемый кокласс всё о них знает. Т.е. он как бы является базовым для постоения на его базе других. Т.е. базовый с логической точки зрения может сгенерить событие. Но кроме указателя на внешний IUnknown у него ничего нет. Есть ли какой нужный и полезный для этого случая интерфейс у класса публикующего события...?

Честно говоря, я не слышал о такой возможности, но это не значит, что её нет. Может, будет удобнее вынести выброс событий в аггрегируемый класс, а для приписки клиентов предоставить во внешнем возвращающее указатель на IUnknown аггрегируемого свойство?

Жизнь — это чудо! Только вперёд: sakhnik@jabber.kiev.ua
Re[4]: How to fire COM-event from aggregated coclass
От: slava_529872  
Дата: 16.06.05 10:30
Оценка:
>>Может, будет удобнее вынести выброс событий в аггрегируемый класс, а для приписки клиентов >>предоставить во внешнем возвращающее указатель на IUnknown аггрегируемого свойство?

Так, наверное не получится. Потому что IUnknown у клиента всегда должен быть один и тот же. Иначе нарушится базовый принцип СОМ. Клиент может из любого интерфейса получить любой другой посредством Queryinterface. И какими бы он путями не получал, результат должен быть одним и тем же.
Интересно как в микрософте заделали реалицацию евентов. Укого-нибудь есть полезная информация на этот счет?
Re: How to fire COM-event from aggregated coclass
От: slava_529872  
Дата: 17.06.05 09:21
Оценка:
Я нашел решение. Красивое и очень простое.
Всем спасибо!
Re[2]: How to fire COM-event from aggregated coclass
От: AndrewJD США  
Дата: 17.06.05 09:33
Оценка:
Здравствуйте, slava_529872, Вы писали:

_>Я нашел решение. Красивое и очень простое.

_>Всем спасибо!

Расскажи общественности
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re[3]: How to fire COM-event from aggregated coclass
От: slava_529872  
Дата: 17.06.05 10:04
Оценка: 4 (1)
AJD>Расскажи общественности

Когда в коклассе с помощью ключевого слова __event вносятся поддерживаемые для этого кокласса события, автоматически студия при компиляции добавляет все нужные методы с сигнатурами, как в интерфейсе событий (мы потом вызываем эти методы, когда генерируем события с помощью __raise или вызова вручную). Так вот, теперь если добавить в карту поддерживаемых событий интерфейс событий — его можно будет получить через QueryInterface из агрегируемого кокласса (у него есть ссылка на внешний IUnknown).
Собственно и все. Вызывайте методы интерфейса событий из агрегируемого кокласса, а студия обеспечивает их имплементацию с помощью __event.

Так все сверх просто.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.