home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / com / acdual / server / mfcdual.h < prev    next >
Text File  |  1998-04-02  |  7KB  |  170 lines

  1. // mfcdual.h: Helpful macros for adding dual interface support to
  2. //            MFC applications
  3.  
  4. // This is a part of the Microsoft Foundation Classes C++ library.
  5. // Copyright (C) 1992-1998 Microsoft Corporation
  6. // All rights reserved.
  7. //
  8. // This source code is only intended as a supplement to the
  9. // Microsoft Foundation Classes Reference and related
  10. // electronic documentation provided with the library.
  11. // See these sources for detailed information regarding the
  12. // Microsoft Foundation Classes product.
  13.  
  14. /////////////////////////////////////////////////////////////////////
  15. // BEGIN_DUAL_INTERFACE_PART is just like BEGIN_INTERFACE_PART,
  16. // except that it also adds the IDispatch methods to your class
  17. // declaration.
  18. #define BEGIN_DUAL_INTERFACE_PART(localClass, baseClass) \
  19.     BEGIN_INTERFACE_PART(localClass, baseClass) \
  20.        STDMETHOD(GetTypeInfoCount)(UINT FAR* pctinfo); \
  21.        STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo); \
  22.        STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, UINT cNames, LCID lcid, DISPID FAR* rgdispid); \
  23.        STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult, EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr); \
  24.  
  25. /////////////////////////////////////////////////////////////////////
  26. // END_DUAL_INTERFACE_PART is just like END_INTERFACE_PART. It
  27. // is only added for symmetry...
  28. #define END_DUAL_INTERFACE_PART(localClass) \
  29.     END_INTERFACE_PART(localClass) \
  30.  
  31.  
  32.  
  33. /////////////////////////////////////////////////////////////////////
  34. // DELEGATE_DUAL_INTERFACE expands to define the standard IDispatch
  35. // methods for a dual interface, delegating back to the default
  36. // MFC implementation
  37. #define DELEGATE_DUAL_INTERFACE(objectClass, dualClass) \
  38.     STDMETHODIMP_(ULONG) objectClass::X##dualClass::AddRef() \
  39.     { \
  40.         METHOD_PROLOGUE(objectClass, dualClass) \
  41.         return pThis->ExternalAddRef(); \
  42.     } \
  43.     STDMETHODIMP_(ULONG) objectClass::X##dualClass::Release() \
  44.     { \
  45.         METHOD_PROLOGUE(objectClass, dualClass) \
  46.         return pThis->ExternalRelease(); \
  47.     } \
  48.     STDMETHODIMP objectClass::X##dualClass::QueryInterface( \
  49.         REFIID iid, LPVOID* ppvObj) \
  50.     { \
  51.         METHOD_PROLOGUE(objectClass, dualClass) \
  52.         return pThis->ExternalQueryInterface(&iid, ppvObj); \
  53.     } \
  54.     STDMETHODIMP objectClass::X##dualClass::GetTypeInfoCount( \
  55.         UINT FAR* pctinfo) \
  56.     { \
  57.         METHOD_PROLOGUE(objectClass, dualClass) \
  58.         LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE); \
  59.         ASSERT(lpDispatch != NULL); \
  60.         return lpDispatch->GetTypeInfoCount(pctinfo); \
  61.     } \
  62.     STDMETHODIMP objectClass::X##dualClass::GetTypeInfo( \
  63.         UINT itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo) \
  64.     { \
  65.         METHOD_PROLOGUE(objectClass, dualClass) \
  66.         LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE); \
  67.         ASSERT(lpDispatch != NULL); \
  68.         return lpDispatch->GetTypeInfo(itinfo, lcid, pptinfo); \
  69.     } \
  70.     STDMETHODIMP objectClass::X##dualClass::GetIDsOfNames( \
  71.         REFIID riid, OLECHAR FAR* FAR* rgszNames, UINT cNames, \
  72.         LCID lcid, DISPID FAR* rgdispid) \
  73.     { \
  74.         METHOD_PROLOGUE(objectClass, dualClass) \
  75.         LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE); \
  76.         ASSERT(lpDispatch != NULL); \
  77.         return lpDispatch->GetIDsOfNames(riid, rgszNames, cNames, \
  78.                                          lcid, rgdispid); \
  79.     } \
  80.     STDMETHODIMP objectClass::X##dualClass::Invoke( \
  81.         DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, \
  82.         DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult, \
  83.         EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr) \
  84.     { \
  85.         METHOD_PROLOGUE(objectClass, dualClass) \
  86.         LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE); \
  87.         ASSERT(lpDispatch != NULL); \
  88.         return lpDispatch->Invoke(dispidMember, riid, lcid, \
  89.                                   wFlags, pdispparams, pvarResult, \
  90.                                   pexcepinfo, puArgErr); \
  91.     } \
  92.  
  93.  
  94.  
  95. /////////////////////////////////////////////////////////////////////
  96. // TRY_DUAL and CATCH_ALL_DUAL are used to provide exception handling
  97. // for your dual interface methods. CATCH_ALL_DUAL takes care of
  98. // returning the appropriate error code.
  99.  
  100. #define TRY_DUAL(iidSource) \
  101.     HRESULT _hr = S_OK; \
  102.     REFIID  _riidSource = iidSource; \
  103.     TRY \
  104.  
  105. #define CATCH_ALL_DUAL \
  106.     CATCH(COleException, e) \
  107.     { \
  108.         _hr = e->m_sc; \
  109.     } \
  110.     AND_CATCH_ALL(e) \
  111.     { \
  112.         AFX_MANAGE_STATE(pThis->m_pModuleState); \
  113.         _hr = DualHandleException(_riidSource, e); \
  114.     } \
  115.     END_CATCH_ALL \
  116.     return _hr; \
  117.  
  118. /////////////////////////////////////////////////////////////////////
  119. // DualHandleException is a helper function used to set the system's
  120. // error object, so that container applications that call through
  121. // VTBLs can retrieve rich error information
  122. HRESULT DualHandleException(REFIID riidSource, const CException* pAnyException);
  123.  
  124. /////////////////////////////////////////////////////////////////////
  125. // DECLARE_DUAL_ERRORINFO expands to declare the ISupportErrorInfo
  126. // support class. It works together with DUAL_ERRORINFO_PART and
  127. // IMPLEMENT_DUAL_ERRORINFO defined below.
  128. #define DECLARE_DUAL_ERRORINFO() \
  129.     BEGIN_INTERFACE_PART(SupportErrorInfo, ISupportErrorInfo) \
  130.         STDMETHOD(InterfaceSupportsErrorInfo)(THIS_ REFIID riid); \
  131.     END_INTERFACE_PART(SupportErrorInfo) \
  132.  
  133. /////////////////////////////////////////////////////////////////////
  134. // DUAL_ERRORINFO_PART adds the appropriate entry to the interface map
  135. // for ISupportErrorInfo, if you used DECLARE_DUAL_ERRORINFO.
  136. #define DUAL_ERRORINFO_PART(objectClass) \
  137.     INTERFACE_PART(objectClass, IID_ISupportErrorInfo, SupportErrorInfo) \
  138.  
  139. /////////////////////////////////////////////////////////////////////
  140. // IMPLEMENT_DUAL_ERRORINFO expands to an implementation of
  141. // ISupportErrorInfo which matches the declaration in
  142. // DECLARE_DUAL_ERRORINFO.
  143. #define IMPLEMENT_DUAL_ERRORINFO(objectClass, riidSource) \
  144.     STDMETHODIMP_(ULONG) objectClass::XSupportErrorInfo::AddRef() \
  145.     { \
  146.         METHOD_PROLOGUE(objectClass, SupportErrorInfo) \
  147.         return pThis->ExternalAddRef(); \
  148.     } \
  149.     STDMETHODIMP_(ULONG) objectClass::XSupportErrorInfo::Release() \
  150.     { \
  151.         METHOD_PROLOGUE(objectClass, SupportErrorInfo) \
  152.         return pThis->ExternalRelease(); \
  153.     } \
  154.     STDMETHODIMP objectClass::XSupportErrorInfo::QueryInterface( \
  155.         REFIID iid, LPVOID* ppvObj) \
  156.     { \
  157.         METHOD_PROLOGUE(objectClass, SupportErrorInfo) \
  158.         return pThis->ExternalQueryInterface(&iid, ppvObj); \
  159.     } \
  160.     STDMETHODIMP objectClass::XSupportErrorInfo::InterfaceSupportsErrorInfo( \
  161.         REFIID iid) \
  162.     { \
  163.         METHOD_PROLOGUE(objectClass, SupportErrorInfo) \
  164.         return (iid == riidSource) ? S_OK : S_FALSE; \
  165.     }
  166.  
  167.  
  168.  
  169. /////////////////////////////////////////////////////////////////////
  170.