Как общаться с интерфейсом событий? - PullRequest
0 голосов
/ 26 октября 2011

У меня есть живой IDevicePtr, (IDevice является компонентом COM).

Я вызываю метод ("get_DeviceEvents") для его интерфейса событий, поэтому теперь у меня есть живой объект "IDeviceEvents",Этот объект имеет следующий интерфейс:

IDeviceEvents : IDispatch
{
    //
    // Raw methods provided by interface
    //

      virtual HRESULT __stdcall add_TalkPressed (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall remove_TalkPressed (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall add_ButtonPressed (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall remove_ButtonPressed (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall add_MuteStateChanged (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall remove_MuteStateChanged (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall add_AudioStateChanged (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall remove_AudioStateChanged (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall add_FlashPressed (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall remove_FlashPressed (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall add_SmartPressed (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall remove_SmartPressed (
        /*[in]*/ IUnknown * value ) = 0;
      virtual HRESULT __stdcall SetInputReport (
        /*[in]*/ SAFEARRAY * reportBuffer ) = 0;
};

Скажем, я хотел перехватить событие MuteStateChanged в моем приложении.Как я могу это сделать?Я могу назвать «add_MuteStateChanged».Я предполагаю, что это какой-то метод добавления обработчика событий.Какую полезную нагрузку я должен использовать?У меня есть локальный производный объект IDispatch, готовый для перехвата любого события с:

STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,
        LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
        EXCEPINFO* pexcepinfo, UINT* puArgErr)
    {
        // ALL I want is to get here when some event in IDeviceEvents is fired.
        return S_OK;
    }

Справочная информация: Я уже несколько дней пытаюсь получить событие COM в приложении M32 / ATL C ++ Win32.Это оказалось самой трудной задачей, которую я когда-либо выполнял, мудрое время.

1 Ответ

1 голос
/ 27 октября 2011

Это не «стандартная» реализация событий.Как правило, объект источника события может отображать IConnectionPointContainer, IConnectionPoint и т. Д. Ваш интерфейс больше похож на реализацию событий другим способом.

Кажется, вы ожидаете, что вы предоставите свой приемник явно для событий, представляющих интерес.Обратите внимание, что хотя это не типичный COM-подход, все это очень специфично для реализации источника событий.Определение интерфейса не предполагает, какой именно интерфейс ожидается в аргументе add_MuteStateChanged.

Вы можете сделать следующее.Передайте свой COM-объект в качестве аргумента add_MuteStateChanged.Реализация IDispatch подойдет, это может быть фактически любой COM-объект - суть в том, что это ваш код, и вы можете отслеживать все вызовы по этому указателю интерфейса.Проверьте, запрашивает ли ваш источник событий какие-либо интерфейсы с этого IUnknown.Он должен вызывать IUnknown::QueryInterface немедленно или позже во время события.Перехватив его, вы увидите, какой интерфейс на самом деле запрашивается.

Если это будет IDispatch, событие, скорее всего, будет доставлено через IDispatch::Invoke.В противном случае это может быть интерфейс, который вам нужно реализовать напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...