Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
4.3 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: D I S P I M P L 2 . H
  7. //
  8. // Contents: Implementation of IDispatch without dual interfaces
  9. //
  10. // Notes:
  11. //
  12. // Author: mbend 26 Sep 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. // -IDelegatingDispImpl for implementing IDispatch by delegation
  16. // to another interface (typically a custom interface).
  17. //
  18. // These classes are useful because ATL's IDispatchImpl can
  19. // only implement duals.
  20. //
  21. /////////////////////////////////////////////////////////////////////////////
  22. //
  23. // IDelegatingDispImpl: For implementing IDispatch in terms of another
  24. // (typically custom) interface, e.g.:
  25. //
  26. // [oleautomation]
  27. // interface IFoo : IUnknown
  28. // {
  29. // ...
  30. // }
  31. //
  32. // IDelegatingDispImpl implements all four IDispatch methods.
  33. // IDelegatingDispImpl gets the IDispatch vtbl entries by deriving from
  34. // IDispatch in addition to the implementation interface.
  35. //
  36. // Usage:
  37. // class CFoo : ..., public IDelegatingDispImpl<IFoo>
  38. //
  39. // In the case where the coclass is intended to represent a control,
  40. // there is a need for the coclass to have a [default] dispinterface.
  41. // Otherwise, some control containers (notably VB) throw arcane error when
  42. // the control is loaded. For a control that you intend to provide the
  43. // custom interface and delegating dispatch mechanism, you will have to
  44. // provide a dispinterface defined in terms of a custom interface like
  45. // so:
  46. //
  47. // dispinterface DFoo
  48. // {
  49. // interface IFoo;
  50. // }
  51. //
  52. // coclass Foo
  53. // {
  54. // [default] interface DFoo;
  55. // interface IFoo;
  56. // };
  57. //
  58. // For every other situation, declaring a dispinterface in terms of a
  59. // custom interface is not necessary to use IDelegatingDispatchImpl.
  60. // However, if you'd like DFoo to be in the base class list (as needed
  61. // for the caveat control), you may use DFoo as the base class instead
  62. // of the default template argument IDispatch like so:
  63. //
  64. // Usage:
  65. // class CFoo : ..., public IDelegatingDispImpl<IFoo, &IID_IFoo, DFoo>
  66. //
  67. #pragma once
  68. #ifndef INC_DISPIMPL2
  69. #define INC_DISPIMPL2
  70. /////////////////////////////////////////////////////////////////////////////
  71. // IDelegatingDispImpl
  72. template <class T, const IID* piid = &__uuidof(T), class D = IDispatch,
  73. const GUID* plibid = &CComModule::m_libid, WORD wMajor = 1,
  74. WORD wMinor = 0, class tihclass = CComTypeInfoHolder>
  75. class ATL_NO_VTABLE IDelegatingDispImpl : public T, public D
  76. {
  77. public:
  78. typedef tihclass _tihclass;
  79. // IDispatch
  80. STDMETHOD(GetTypeInfoCount)(UINT* pctinfo)
  81. {
  82. *pctinfo = 1;
  83. return S_OK;
  84. }
  85. STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
  86. {
  87. return _tih.GetTypeInfo(itinfo, lcid, pptinfo);
  88. }
  89. STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
  90. LCID lcid, DISPID* rgdispid)
  91. {
  92. return _tih.GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
  93. }
  94. STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,
  95. LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
  96. EXCEPINFO* pexcepinfo, UINT* puArgErr)
  97. {
  98. // NOTE: reinterpret_cast because CComTypeInfoHolder makes the mistaken
  99. // assumption that the typeinfo can only Invoke using an IDispatch*.
  100. // Since the implementation only passes the itf onto
  101. // ITypeInfo::Invoke (which takes a void*), this is a safe cast
  102. // until the ATL team fixes CComTypeInfoHolder.
  103. return _tih.Invoke(reinterpret_cast<IDispatch*>(static_cast<T*>(this)),
  104. dispidMember, riid, lcid, wFlags, pdispparams,
  105. pvarResult, pexcepinfo, puArgErr);
  106. }
  107. protected:
  108. static _tihclass _tih;
  109. static HRESULT GetTI(LCID lcid, ITypeInfo** ppInfo)
  110. {
  111. return _tih.GetTI(lcid, ppInfo);
  112. }
  113. };
  114. template <class T, const IID* piid, class D, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
  115. IDelegatingDispImpl<T, piid, D, plibid, wMajor, wMinor, tihclass>::_tihclass
  116. IDelegatingDispImpl<T, piid, D, plibid, wMajor, wMinor, tihclass>::_tih =
  117. { piid, plibid, wMajor, wMinor, NULL, 0, NULL, 0 };
  118. #endif // INC_DISPIMPL2