уведомления о событиях не получены, как описано - PullRequest
0 голосов
/ 06 февраля 2009

Проблема:

  • Уведомления о событиях (от COM-объекта - сервера) не принимаются, как указано в реализации Sink (класса).

  • Одно уведомление о событии равно получено (Event_one), однако другие не получено соответственно

  • Если заказ равен изменен - в IDispatch :: Invoke, то есть:

    • если Event_one поменять местами на Event_two, то Event_two получено уведомление, но Event_one и другие соответственно пренебрегли

Вопрос:

  • Лучший способ реализовать, IDispatch :: Invoke или QI?
  • Используя неправильную логику или подход?

Примечание

  • Нет MFC
  • Нет ATL
  • Чистый C ++
  • использование цикла сообщений: GetMessage ()
  • STA модель (Coinitialize ())
  • Позвонить в IDispatch :: Консультировать Успешно (HRESULT от звонка S_OK )
  • После вышесказанного вызов метода COM-объекта выполняется как обычно (с указателем на интерфейс)
  • Один звонок в Advise
  • Библиотека типов, сгенерированная из Компилятор MIDL

Например (пример):

Иллюстрация IDispatch :: Invoke - взято из Класс мойки :

HRESULT STDMETHODCALLTYPE Invoke(
{
//omitted parameters

// The riid parameter is always supposed to be IID_NULL
        if (riid != IID_NULL)
            return DISP_E_UNKNOWNINTERFACE;

if (pDispParams) //DISPID dispIdMember
    {
        switch (dispIdMember) { 
        case 1:
            return Event_one();
        case 2:
            return Event_two();
        case 3:
            return Event_three();
        default:
            return E_NOTIMPL;
        }
    }
    return E_NOTIMPL;
}

Иллюстрация QueryInterface:

STDMETHOD (QueryInterface)(
//omitted parameters
{
    if (iid == IID_IUnknown || iid == __uuidof(IEvents))
    {
        *ppvObject = (IEvents *)this;
    } else {
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }
    m_dwRefCount++;
    return S_OK;
};

Ответы [ 2 ]

1 голос
/ 07 февраля 2009

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

Вы также можете установить точку останова в методе Invoke клиентского приложения, чтобы проверить, какие события оно получает.

0 голосов
/ 09 февраля 2009

РЕШИТЬ:

После просмотра соответствующего IDL ФАЙЛА (сгенерированного компилятором MIDL) стало очевидно, что каждый метод , содержащийся в интерфейсе IEvent , имеет уникальный идентификатор . Например, Event_one имеет идентификатор 2 . Например:

methods:
    [id(0x00000002)]
    HRESULT Event_one();

Следовательно, внесение изменений следующим образом - в реализацию IDispatch :: invoke (проиллюстрировано в приведенном выше вопросе):

//omitted


if (pDispParams) //DISPID dispIdMember
        {
            switch (dispIdMember) { 
            case 2:
                    return Event_one();

//omitted 

Теперь при соответствующем вызове желаемый / правильный метод - , теперь выполнен.

...