windows-nt/Source/XPSP1/NT/net/homenet/beacon/server/dispimpl2.h
2020-09-26 16:20:57 +08:00

131 lines
4.3 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000.
//
// File: D I S P I M P L 2 . H
//
// Contents: Implementation of IDispatch without dual interfaces
//
// Notes:
//
// Author: mbend 26 Sep 2000
//
//----------------------------------------------------------------------------
// -IDelegatingDispImpl for implementing IDispatch by delegation
// to another interface (typically a custom interface).
//
// These classes are useful because ATL's IDispatchImpl can
// only implement duals.
//
/////////////////////////////////////////////////////////////////////////////
//
// IDelegatingDispImpl: For implementing IDispatch in terms of another
// (typically custom) interface, e.g.:
//
// [oleautomation]
// interface IFoo : IUnknown
// {
// ...
// }
//
// IDelegatingDispImpl implements all four IDispatch methods.
// IDelegatingDispImpl gets the IDispatch vtbl entries by deriving from
// IDispatch in addition to the implementation interface.
//
// Usage:
// class CFoo : ..., public IDelegatingDispImpl<IFoo>
//
// In the case where the coclass is intended to represent a control,
// there is a need for the coclass to have a [default] dispinterface.
// Otherwise, some control containers (notably VB) throw arcane error when
// the control is loaded. For a control that you intend to provide the
// custom interface and delegating dispatch mechanism, you will have to
// provide a dispinterface defined in terms of a custom interface like
// so:
//
// dispinterface DFoo
// {
// interface IFoo;
// }
//
// coclass Foo
// {
// [default] interface DFoo;
// interface IFoo;
// };
//
// For every other situation, declaring a dispinterface in terms of a
// custom interface is not necessary to use IDelegatingDispatchImpl.
// However, if you'd like DFoo to be in the base class list (as needed
// for the caveat control), you may use DFoo as the base class instead
// of the default template argument IDispatch like so:
//
// Usage:
// class CFoo : ..., public IDelegatingDispImpl<IFoo, &IID_IFoo, DFoo>
//
#pragma once
#ifndef INC_DISPIMPL2
#define INC_DISPIMPL2
/////////////////////////////////////////////////////////////////////////////
// IDelegatingDispImpl
template <class T, const IID* piid = &__uuidof(T), class D = IDispatch,
const GUID* plibid = &CComModule::m_libid, WORD wMajor = 1,
WORD wMinor = 0, class tihclass = CComTypeInfoHolder>
class ATL_NO_VTABLE IDelegatingDispImpl : public T, public D
{
public:
typedef tihclass _tihclass;
// IDispatch
STDMETHOD(GetTypeInfoCount)(UINT* pctinfo)
{
*pctinfo = 1;
return S_OK;
}
STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
{
return _tih.GetTypeInfo(itinfo, lcid, pptinfo);
}
STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
LCID lcid, DISPID* rgdispid)
{
return _tih.GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
}
STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
EXCEPINFO* pexcepinfo, UINT* puArgErr)
{
// NOTE: reinterpret_cast because CComTypeInfoHolder makes the mistaken
// assumption that the typeinfo can only Invoke using an IDispatch*.
// Since the implementation only passes the itf onto
// ITypeInfo::Invoke (which takes a void*), this is a safe cast
// until the ATL team fixes CComTypeInfoHolder.
return _tih.Invoke(reinterpret_cast<IDispatch*>(static_cast<T*>(this)),
dispidMember, riid, lcid, wFlags, pdispparams,
pvarResult, pexcepinfo, puArgErr);
}
protected:
static _tihclass _tih;
static HRESULT GetTI(LCID lcid, ITypeInfo** ppInfo)
{
return _tih.GetTI(lcid, ppInfo);
}
};
template <class T, const IID* piid, class D, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
IDelegatingDispImpl<T, piid, D, plibid, wMajor, wMinor, tihclass>::_tihclass
IDelegatingDispImpl<T, piid, D, plibid, wMajor, wMinor, tihclass>::_tih =
{ piid, plibid, wMajor, wMinor, NULL, 0, NULL, 0 };
#endif // INC_DISPIMPL2