Rerouting the Internal IDispatch

Your extension needs to reroute its IDispatch implementation to the aggregator through the ADSI object manager and let ADSI make an invocation decision. ADSI can invoke itself, another extension, or your extension, depending on the algorithm.

Follow these steps to implement this behavior:

  1. Comment out IDispatchImpl in your extension's header file (for our example the file name is myextension.h), as shown in the following example:
    //public IDispatchImpl<IMyExtension, &IID_IMyExtension, //&LIBID_ADSFIRSTEXTLib>, 
    
  2. Add the following string just below the now commented out line:
    public IMyExtension,
    
  3. To implement the IDispatch portion of IMyExtension, you will need to declare them as shown in the following example:
    // IDispatch.
    STDMETHOD(GetTypeInfoCount)(UINT* pctinfo); 
    STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo);
    STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
    LCID lcid, DISPID* rgdispid);
    STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,
    LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
    EXCEPINFO* pexcepinfo, UINT* puArgErr);
    
  4. Now use the following code to make the implementation. This sample code is intended for example only and may not be completely valid for every situation.:
    //-----------------------------------------------
    // Delegate IDispatch methods to the aggregator
    //-----------------------------------------------
    
    STDMETHODIMP MyExtension::GetTypeInfoCount(UINT* pctinfo)
    {
       IDispatch *pDisp;
       HRESULT    hr;
       hr = OuterQueryInterface( 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;
       HRESULT    hr;
       hr = OuterQueryInterface( 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;
       HRESULT    hr;
       hr = OuterQueryInterface( 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;
       HRESULT    hr;
       hr = OuterQueryInterface( IID_IDispatch, (void**) &pDisp );
       if ( SUCCEEDED(hr) )
       {
           hr = pDisp->Invoke( dispidMember, riid, lcid, wFlags, 
                    pdispparams, pvarResult, pexcepinfo, puArgErr);
           pDisp->Release();
       }
       return hr;
    }
    
    //---------------------------------
    // End delegating IDispatch methods.
    //---------------------------------