Fournir une implémentation IDispatch pour un client de point de connexion
Question
J'ai écrit simple DLL COM serveur inproc avec un seul objet COM simple. L'objet COM met en œuvre un point de connexion.
Je sais comment créer un client ATL qui dérive de IDispEventImpl
, et utilise une carte de l'évier pour simplifier ce processus.
Mais, pour les besoins de la démonstration, je voudrais créer une application console Win32 qui utilise une classe qui appelle mon objet COM simple, puis agit comme un puits de point de connexion.
J'ai aucune idée comment fournir une implémentation de IDispatch
- Quelqu'un peut-il recommander la documentation à ce sujet, car je ne trouve pas (j'ai ATL Internes, mais cela ne semble pas couvrir ce que je dois ).
Voici la classe que j'ai déjà:
#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;
}
};
La solution
Puisque vous avez déjà ATL
vous pouvez examiner ses sources et voir comment IDispatchImpl
fait tout ce genre de choses. méthodes de IDispatch
sont mises en œuvre therehby données de lecture de la bibliothèque de type dans le même module, car il est le moyen le plus simple et le plus fiable quand une bibliothèque de type est déjà présent.
Il est également intéressant de noter que c'est un sujet plutôt difficile pour faire une démonstration - vous aurez besoin d'écrire beaucoup de code qui ne produit pas vraiment aperçu. OMI vous serez beaucoup mieux si vous implémenter l'interface un événement qui n'a pas Hériter de IDispatch
mais hérite directement de IUnknown
-. Cela démontrera comment fonctionnent les événements sans traîner trop d'attention à IDispatch
fonctionnement interne
Autres conseils
Je pense que la meilleure façon de le faire est par CreateStdDispatch
Vous pouvez utiliser cette implémentation IDispatch.
Il est pas exactement ce que vous cherchez, mais Firebreath utilise des points IDispatchEx et de connexion pour fournir un contrôle ActiveX qui fonctionne dans IE. Parce que Firebreath est une abstraction pour permettre des plugins à écrire une fois et utilisé dans tous les navigateurs principaux, l'interface IDispatch devait être écrit à la main -. Y compris les points de connexion
Le code peut être un peu déroutant, car il y a une classe mixin basé sur un modèle utilisé pour fournir IDispatch et ConnectionPoints à deux classes d'objets COM différentes, mais il peut aider.
Vous avez déjà accepté une réponse, mais peut-être il sera toujours de l'aide. Désolé, je ne vois pas la question plus tôt.