Prise en charge des interfaces double ou dispatch
Comme l’interface de répartition, toutes les interfaces doubles doivent hériter d’IDispatch, qui délègue toutes ses fonctions IDispatch (GetIDsOfNames, Invoke, GetTypeInfo, GetTypeInfoCount) à l’IDispatch de l’agrégateur (ADSI). Pour déléguer, un objet d’extension doit interroger l’IDispatch de l’agrégateur, appeler la méthode d’agrégateur appropriée et libérer le pointeur après utilisation.
Si l’extension peut être un composant autonome, vérifiez qu’elle est agrégée. Si c’est le cas, redirigez les fonctions dispatch vers l’IDispatch de l’agrégateur. Sinon, vous pouvez appeler votre implémentation interne d’IDispatch, ou vous pouvez appeler votre implémentation d’IADsExtension.
L’exemple de code suivant montre comment rediriger l’appel IDispatch vers l’IDispatch de l’agrégateur. Cet exemple de code suppose que la variable membre m_pOuterUnknown a été initialisée sur le pointeur IUnknown de l’agrégateur.
///////////////////////////////////////////////////
// Delegating IDispatch Methods to the aggregator
///////////////////////////////////////////////////
STDMETHODIMP MyExtension::GetTypeInfoCount(UINT* pctinfo)
{
IDispatch *pDisp = NULL;
HRESULT hr = S_OK;
hr = m_pOuterUnknown->QueryInterface( IID_IDispatch, (void**) &pDisp );
if ( SUCCEEDED(hr) )
{
hr = pDisp->GetTypeInfoCount( pctinfo );
pDisp->Release();
}
return hr;
}
STDMETHODIMP MyExtension::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
{
IDispatch *pDisp = NULL;
HRESULT hr = S_OK;
hr = m_pOuterUnknown->QueryInterface( IID_IDispatch, (void**) &pDisp );
if ( SUCCEEDED(hr) )
{
hr = pDisp->GetTypeInfo( itinfo, lcid, pptinfo );
pDisp->Release();
}
return hr;
}
STDMETHODIMP MyExtension::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid)
{
IDispatch *pDisp = NULL;
HRESULT hr = S_OK;
hr = m_pOuterUnknown->QueryInterface( IID_IDispatch, (void**) &pDisp );
if ( SUCCEEDED(hr) )
{
hr = pDisp->GetIDsOfNames( riid, rgszNames, cNames, lcid,
rgdispid);
pDisp->Release();
}
return hr;
}
STDMETHODIMP MyExtension::Invoke(DISPID dispidMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT*
pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr)
{
IDispatch *pDisp = NULL;
HRESULT hr = S_OK;
hr = m_pOuterUnknown->QueryInterface( IID_IDispatch, (void**) &pDisp );
if ( SUCCEEDED(hr) )
{
hr = pDisp->Invoke( dispidMember, riid, lcid, wFlags,
pdispparams, pvarResult, pexcepinfo, puArgErr);
pDisp->Release();
}
return hr;
}
Les enregistreurs d’extension sont fortement encouragés à prendre en charge les interfaces doubles au lieu de distribuer des interfaces dans leurs objets d’extension. Une interface double permet à un client d’avoir un accès plus rapide, tant que l’accès vtable est activé dans le client. Pour plus d’informations, consultez Liaison tardive et accès vtable dans le modèle d’extension ADSI. Sur la base du modèle actuel, l’implémentation de deux interfaces ne doit pas être plus difficile que l’implémentation d’interfaces de répartition.