Re: Проблема с компилятором интерфейсов
От: Vi2 Удмуртия http://www.adem.ru
Дата: 09.07.04 14:59
Оценка: 1 (1)
Здравствуйте, s_anatoli, Вы писали:

_>    dispinterface _IGetTypeEvents
_>    {
_>        properties:
_>        methods:
_>        [id(1), helpstring("method OnGetTypeFinished")] HRESULT OnGetTypeFinished([in] IGetType * getType);
_>    };

_>Вот беда, компилятор интерфейсов формирует пустую структуру
_>    MIDL_INTERFACE("B5BE3B07-98E4-489C-BB9F-1D5351FA9ED9")
_>    _IGetTypeEvents : public IDispatch
_>    {
_>    };

А что хотелось бы?
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Проблема с компилятором интерфейсов
От: s_anatoli Украина http://koresha.org/sakhnik
Дата: 09.07.04 08:19
Оценка:
В куске кода объявлена типичная схема точек соединения:
[
    object,
    uuid(EF582D07-2E55-4EAA-9A70-A7188923C7A2),
    dual,
    nonextensible,
    helpstring("IGetType Interface"),
    pointer_default(unique)
]
interface IGetType : IDispatch{
    [propget, id(1), helpstring("property Type")] HRESULT Type([out, retval] LONG* pVal);
    [propget, id(2), helpstring("property Version")] HRESULT Version([out, retval] LONG* pVal);
    [propget, id(3), helpstring("property Subver")] HRESULT Subver([out, retval] LONG* pVal);
};
...................................
    [
        uuid(B5BE3B07-98E4-489C-BB9F-1D5351FA9ED9),
        helpstring("_IGetTypeEvents Interface")
    ]
    dispinterface _IGetTypeEvents
    {
        properties:
        methods:
        [id(1), helpstring("method OnGetTypeFinished")] HRESULT OnGetTypeFinished([in] IGetType * getType);
    };
    [
        uuid(BAD71DF5-3943-432B-A7E8-1CDAE76D0376),
        helpstring("GetType Class")
    ]
    coclass GetType
    {
        [default] interface IGetType;
        [default, source] dispinterface _IGetTypeEvents;
    };

Вот беда, компилятор интерфейсов формирует пустую структуру
    MIDL_INTERFACE("B5BE3B07-98E4-489C-BB9F-1D5351FA9ED9")
    _IGetTypeEvents : public IDispatch
    {
    };

Всё действие происходит в MSVC 7.1. Если кто-нибудь сталкивался с такой проблеммой, подскажите.

Жизнь — это чудо! Только вперёд: sakhnik@jabber.kiev.ua
Re[2]: Проблема с компилятором интерфейсов
От: s_anatoli Украина http://koresha.org/sakhnik
Дата: 09.07.04 15:59
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>А что хотелось бы?


Должен признать, я неправильно сформулировал вопрос. На самом деле я не могу с помощью мастера реализовать методы событий в Connection Point. То есть, иногда срабатывает, а иногда нет. Не могу даже выяснить, когда же возникает проблема: не прослеживается зависимость от аргументов. Клас всё время перед попыткой очищаю от сгенерированного бесполезных определений (включение файла прокси-объекта, наследование класса от прокси, карту точек соединения), файл с описанием интерфейсов перекомпилирую. Вот, хотелось бы узнать, сталкивался ли кто-нибудь с подобной проблемой?

Жизнь — это чудо! Только вперёд: sakhnik@jabber.kiev.ua
Re[3]: Проблема с компилятором интерфейсов
От: rus blood Россия  
Дата: 09.07.04 16:31
Оценка:
Здравствуйте, s_anatoli, Вы писали:

_>Должен признать, я неправильно сформулировал вопрос. На самом деле я не могу с помощью мастера реализовать методы событий в Connection Point. То есть, иногда срабатывает, а иногда нет. Не могу даже выяснить, когда же возникает проблема: не прослеживается зависимость от аргументов. Клас всё время перед попыткой очищаю от сгенерированного бесполезных определений (включение файла прокси-объекта, наследование класса от прокси, карту точек соединения), файл с описанием интерфейсов перекомпилирую. Вот, хотелось бы узнать, сталкивался ли кто-нибудь с подобной проблемой?


По порядку.

1. Создаешь ATL-объект, включаешь поддержку Connection Points.
2. Для события создается dispinterface.
3. В студии открываешь Class View и у интерфейса добавляешь метод.
4. В Class View у интефейса события добавляешь метод события.
5. Компилируем (чтоб cгенерить tlb).
6. В Class View у класс для COM-объект делаем Implement Connection Points.
7. На диалоге выбираем интерфейс события.
8. Готово.

В h-файле для idl будет пустая запись (без методов), потому что для события генерируется dispinterface. Это значит, что этот интерфейс работает через IDispatch (не дуальный), а соответственно, объявления методов (vtable) ему не нужны. В коде, который генерируется мастером во время выполнения Implement Connection Points, dispid-ы уже прописаны. Когда ты реализуешь sink используя SINK_ENTRY_EX, там тоже используятся явные dispid-ы событий.
Имею скафандр — готов путешествовать!
Re[3]: Проблема с компилятором интерфейсов
От: rus blood Россия  
Дата: 09.07.04 16:48
Оценка:
Здравствуйте, s_anatoli, Вы писали:

Если хочешь сделать рассылку событий используя раннее связывание, то для этого надо сделать следующее.

1. В idl файле добавить новый интерфейс (руками).
    [
        uuid(B5BE3B07-98E4-489C-BB9F-1D5351FA9ED9),
        helpstring("_IGetTypeEvents Interface")
    ]
    dispinterface _IGetTypeEvents
    {
        properties:
        methods:
        [id(1), helpstring("method OnGetTypeFinished")] HRESULT OnGetTypeFinished([in] IGetType * getType);
    };
    [
        uuid(<generate_new_guid_here>),
        helpstring("IGetTypeEventsVtbl Interface")
    ]
    interface IGetTypeEventsVtbl : IUnknown
    {
        [id(1)] HRESULT Fired();
    };
    [
        uuid(BAD71DF5-3943-432B-A7E8-1CDAE76D0376),
        helpstring("GetType Class")
    ]
    coclass GetType
    {
        [default] interface IGetType;
        [default, source] dispinterface _IGetTypeEvents;
        [source] interface IGetTypeEventsVtbl;
    };


2. Компилим idl.

3. В ClassView для класса COM-объекта выполняем Implement Connection Points.

4. В диалоге указываем оба (или только нужный) вариант connection points.

5. Готово.

Теперь у тебя есть вариант connection points с ранним связыванимем. Если ты указал оба варианта, то твой класс com-объекта поддерживает их оба. В этом случае (если названия методов событий одинаковы для disp-варианта и для нового варианта), то для генерации события нужно использовать приведение к базовому классу, который реализует connection points.

Теперь у тебя для нового интерфейса события в h-файле будет определение и метода. Поэтому в классе sink-а ты можешь просто объявить наследование от этого интерфейса, просто добавить его в карту интерфейсов (а не синков), и просто реализовать метод. Никаких макросов для синков не нужно.
Имею скафандр — готов путешествовать!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.