home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / BOCOLE.PAK / BCOM.H next >
C/C++ Source or Header  |  1995-08-29  |  6KB  |  188 lines

  1. //
  2. //**************************************************************************
  3. //
  4. // BCom.h -- Contains some macros and utility stuff for implementing COM
  5. //           support (i.e. IUnknown) in Bolero apps.
  6. //
  7. // Copyright (c) 1993,94 by Borland International, Inc. All rights reserved
  8. //
  9. //**************************************************************************
  10.  
  11. #ifndef BCOM_H
  12. #define BCOM_H
  13.  
  14. /*
  15.  *                      Include COM definitions
  16.  */
  17.  
  18. #include <string.h>                     // for fmemcmp
  19.  
  20. #ifdef  WIN32
  21. #include <objbase.h>                    // include COM definitions
  22. #else
  23. #include <compobj.h>                    // include COM definitions
  24. #endif
  25.  
  26. #ifdef INITGUID
  27.         #ifndef WIN32
  28.         #include <coguid.h>             // why do they exclude this?
  29.         #endif
  30. #endif
  31.  
  32. #include "portdefs.h"           // temporarily. portdefs is in transition. (PHP)
  33.  
  34. #ifdef WIN32
  35. #include "pshpack8.h"
  36. #endif
  37.  
  38. #ifdef __BORLANDC__
  39.         #undef NOERROR
  40.         #define NOERROR ((HRESULT) 0L)
  41.         #undef ResultFromScode(sc)
  42.         inline HRESULT ResultFromScode(SCODE sc)
  43.                 {return (HRESULT) (sc & 0x800FFFFFL);}
  44.         #undef GetScode(hr)
  45.         inline SCODE GetScode(HRESULT hr)
  46.                 {return   ((SCODE)(hr) & 0x800FFFFFL); }
  47. #endif
  48.  
  49. // force this and vtable pointers far on interfaces
  50. #ifdef __BORLANDC__
  51.         #define _ICLASS  __HUGE
  52. #else
  53.         #define _ICLASS  FAR
  54. #endif
  55.  
  56. #define _IFUNC STDMETHODCALLTYPE
  57.  
  58. #ifndef NULLP
  59.         #define NULLP 0L
  60. #endif
  61.  
  62. #define PREDECLARE_INTERFACE( I )               \
  63.   class _ICLASS I;                                                      \
  64.   typedef const I FAR * PC##I;                  \
  65.   typedef const I FAR & RC##I;                  \
  66.   typedef I FAR * P##I;                                         \
  67.   typedef I FAR & R##I;                                         \
  68.  
  69. #if ((defined __BORLANDC__) && (!defined WIN32))
  70.         #pragma option -po-
  71. #endif
  72.  
  73. typedef IUnknown FAR *  PIUnknown;
  74. PREDECLARE_INTERFACE( IBUnknownMain )
  75.  
  76.  
  77. #if ((defined __BORLANDC__) && (!defined WIN32))
  78.         #pragma option -po.
  79. #endif
  80.  
  81. /*
  82.  *              Aggregation help while using multiple inheritance of interfaces.
  83.  */
  84.  
  85. // IUnknownMain (IUnknown replica forces separate implementation in MI)
  86. //
  87. // QueryInterfaceMain handles IID discrimination and delegation
  88. // to "inner" helper objects.
  89. // AddRefMain and ReleaseMain update a reference count data member.
  90. // And delete the object when the reference count reaches zero.
  91. //
  92. // All other IUnknown's (inherited by other interfaces) simply delegate to
  93. // this IUnknownMain, (or that of an aggregator if one exists).
  94. //
  95. // The layout of IUnknownMain is identical to that of IUnknown and can be
  96. // casted to IUnknown safely.  The names are different to prevent the compiler
  97. // from overriding the implementation when multiple inheritance is used.
  98. //      This is the best way to support aggregation and multiple inheritance
  99. // of interfaces, and requires less indirection than the "nested class"
  100. // approach used by Microsoft's OLE2 samples.
  101. //
  102.  
  103. #if ((defined __BORLANDC__) && (!defined WIN32))
  104.         #pragma option -po-
  105. #endif
  106.  
  107. class _ICLASS IBUnknownMain
  108. {
  109. public:
  110.     virtual HRESULT _IFUNC QueryInterfaceMain(REFIID, LPVOID FAR *) = 0;
  111.     virtual ULONG   _IFUNC AddRefMain() = 0;
  112.     virtual ULONG   _IFUNC ReleaseMain() = 0;
  113. };
  114.  
  115. #if ((defined __BORLANDC__) && (!defined WIN32))
  116.         #pragma option -po.
  117. #endif
  118.  
  119.  
  120. #define DEFINE_IUNKNOWN(pUnkOuter)                                              \
  121.         HRESULT _IFUNC QueryInterface(REFIID iid, void FAR* FAR* pif)   \
  122.                 {return pUnkOuter->QueryInterfaceMain(iid, pif);}               \
  123.         ULONG _IFUNC AddRef() {return pUnkOuter->AddRefMain();}                 \
  124.         ULONG _IFUNC Release(){return pUnkOuter->ReleaseMain();}
  125.  
  126.  
  127. /*
  128.  *      Macros for defining inline QueryInterface implementation that can be
  129.  * called statically from derived classes' QueryInterface
  130.  *
  131.  *      For each interface a global inline function with the interface name
  132.  * prepended (followed by an underscore) is defined to allow
  133.  * each interface to compare its own id and QueryInterface its parents'.
  134.  * This simplifies writing QueryInterface.
  135.  */
  136.  
  137. inline HRESULT _IFUNC IUnknown_QueryInterface(IUnknown FAR *, REFIID iid, LPVOID FAR * pif)
  138. {
  139.         // To avoid handing out different IUnknown pointers for
  140.         // the same Windows Object don't match here.
  141.         // Only match in the main IUnknown in the outermost aggregator.
  142.  
  143.         return ResultFromScode(E_NOINTERFACE);
  144. }
  145.  
  146. #define DEFINE_INLINE_QI(I, P) \
  147. inline HRESULT _IFUNC I##_QueryInterface(I FAR * This, REFIID iid, LPVOID FAR *pif) \
  148. {                                                                                                                                                                       \
  149.         return (iid == IID_##I) ?                                                                                               \
  150.                 (*pif = This), This->AddRef(), NOERROR :                                                                \
  151.                 P##_QueryInterface(This, iid, pif);                                                             \
  152. }
  153.  
  154. #define DEFINE_INLINE_QI2(I, P1, P2) \
  155. inline HRESULT _IFUNC I##_QueryInterface(I FAR* This, REFIID iid, LPVOID FAR* pif) \
  156. {                                            \
  157.   return (iid == IID_##I) ?                  \
  158.     (*pif = This), ((P1*)This)->AddRef(), NOERROR : \
  159.     SUCCEEDED(P1##_QueryInterface(This, iid, pif))? NOERROR :\
  160.     P2##_QueryInterface(This, iid, pif);      \
  161. }
  162.  
  163.  
  164. inline HRESULT _IFUNC IBUnknownMain::QueryInterfaceMain(REFIID iid, LPVOID FAR *pif)
  165. {
  166.         return (iid == IID_IUnknown) ?
  167.                 (*pif = this), AddRefMain(), NOERROR :
  168.                 ResultFromScode(E_NOINTERFACE);
  169. }
  170.  
  171. inline HRESULT _IFUNC IUnknown::QueryInterface(REFIID iid, LPVOID FAR *pif)
  172. {
  173.         return (iid == IID_IUnknown) ?
  174.                 (*pif = this), AddRef(), NOERROR :
  175.                 ResultFromScode(E_NOINTERFACE);
  176. }
  177.  
  178. inline PIBUnknownMain AsPIUnknownMain(PIUnknown pUnk) {return (PIBUnknownMain)pUnk;}
  179. inline PIUnknown AsPIUnknown(PIBUnknownMain pUnk) {return (PIUnknown)pUnk;}
  180.  
  181.  
  182. #ifdef WIN32
  183. #include "poppack.h"
  184. #endif
  185.  
  186. #endif
  187.  
  188.