Предоставление реализации IDispatch для клиента точки подключения
Вопрос
Я написал простую COM DLL INPROC Server с одним простым COM-объектом. COM-объект реализует точку подключения.
Я знаю, как создать клиент ATL, который вытекает из IDispEventImpl
, и использует карту раковины, чтобы упростить этот процесс.
Но для целей демонстрации я хотел бы создать консольное приложение Win32, которое использует класс, который вызывает мой простой COM-объект, затем действует как точка соединения.
Я понятия не имею, как предоставить реализацию IDispatch
- Может ли кто-то рекомендовать документацию по этому поводу, так как я не могу найти (у меня есть внутренние внутренние органы, но это не оказывает, что мне нужно).
Вот класс, который у меня уже есть:
#pragma once
#include <iostream>
using namespace std;
// Because we're implementing a connection points sink (_IPogFarmEvents)
// in a non-ATL class, we must provide implementations for IUnknown and IDispatch.
class KidWithAPogFarm : public _IPogFarmEvents
{
private:
DWORD m_dwRefCount;
LONG m_lNumPogs;
public:
KidWithAPogFarm() :
m_dwRefCount (0),
m_lNumPogs (0)
{
}
~KidWithAPogFarm()
{
}
// -- IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject)
{
if (iid == DIID__IPogFarmEvents)
{
m_dwRefCount++;
*ppvObject = (void *)this;
return S_OK;
}
if (iid == IID_IUnknown)
{
m_dwRefCount++;
*ppvObject = (void *)this;
return S_OK;
}
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE AddRef()
{
m_dwRefCount++;
return m_dwRefCount;
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG l;
l = m_dwRefCount--;
if ( 0 == m_dwRefCount)
delete this;
return l;
}
// -- IDispatch
STDMETHODIMP GetTypeInfoCount(UINT *pctinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo )
{
return E_NOTIMPL;
}
STDMETHODIMP GetIDsOfNames(const IID &riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId )
{
return E_NOTIMPL;
}
STDMETHODIMP Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr )
{
return E_NOT_IMPL;
}
// -- IAntFarmEvents
STDMETHODIMP OnFarmCreated(LONG lInitialPopulation)
{
m_lNumPogs = lInitialPopulation;
cout << "The kid has a pog farm with " << m_lNumPogs << " pogs " << endl;
return S_OK;
}
};
Решение
Так как у вас уже есть ATL
Вы можете изучить его источники и посмотреть, как IDispatchImpl
делает все это. IDispatch
Методы реализованы здесь, чтение данных из библиотеки типа в том же модуле, поскольку это самый простой и самый надежный способ, когда библиотека типа уже присутствует.
Также стоит отметить, что это довольно сложная тема для демонстрации на нем - вам нужно будет написать много кода, который на самом деле не приносит никакого понимания. IMO вы будете намного лучше, если вы реализуете интерфейс событий, которые не наследуют от IDispatch
а скорее наследует непосредственно от IUnknown
- Это продемонстрирует, как работают события, не тянув слишком много внимания IDispatch
внутренние работы.
Другие советы
Я думаю, что самый простой способ сделать это через Createestddispatch.
Ты можешь использовать это Реализация Idespatch.
Это не совсем то, что вы ищете, но Firebreath Использует IDISPATCEX и точки подключения для обеспечения управления ActiveX, который работает в IE. Поскольку Firebrath - это абстракция, позволяющая записывать плагины один раз и использовать во всех основных браузерах, интерфейс IDispatch, необходимый для того, чтобы быть записан вручную, включая точки подключения.
Код может быть немного запутанным, поскольку есть шаблонный класс Mixin, используемый для обеспечения идиспатч и точек соединения с двумя разными классами объекта COM, но это может помочь.
Вы уже приняли ответ, но, возможно, это все равно поможет. Извините, я не видел вопрос раньше.