home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / ocfinc.pak / OLEUTIL.H < prev   
C/C++ Source or Header  |  1997-07-23  |  16KB  |  448 lines

  1. //
  2. //----------------------------------------------------------------------------
  3. // ObjectComponents
  4. // (C) Copyright 1994 by Borland International, All Rights Reserved
  5. //
  6. //   Low level OLE Utility class definitions
  7. //----------------------------------------------------------------------------
  8. #if !defined(OCF_OLEUTIL_H)
  9. #define OCF_OLEUTIL_H
  10.  
  11. #if !defined(OSL_DEFS_H)
  12. # include <osl/defs.h>
  13. #endif
  14. #if !defined(__CSTRING_H)
  15. # include <cstring.h>
  16. #endif
  17. #if !defined(OSL_EXCEPT_H)
  18. # include <osl/except.h>
  19. #endif
  20.  
  21. // For 16bit Ole2, can grab the headers now if the're not included already,
  22. // For 32bit Ole2, it is too late
  23. //
  24. #if defined(BI_PLAT_WIN16)
  25. # if !defined(__OLE2_H)
  26. #   include <ole2.h>
  27. # endif
  28. # if !defined(__DISPATCH_H)
  29. #   include <dispatch.h>
  30. # endif
  31. # if !defined(__OLENLS_H)
  32. #   include <olenls.h>
  33. # endif
  34. #endif
  35. #if defined(BI_PLAT_WIN32) && !defined(__OLE2_H) && !defined(_OLE2_H_)
  36. # error INC_OLE2 must be defined before osl/defs.h is included. Include ocdefs.h first
  37. #endif
  38.  
  39. // Force this pointers and vtable pointers far on interfaces
  40. //
  41. #if !defined(_ICLASS)
  42. # if defined(__BORLANDC__)
  43. #   if defined(BI_PLAT_WIN16)
  44. #     define _ICLASS  __huge
  45. #   else
  46. #     define _ICLASS
  47. #   endif
  48. # else
  49. #   define _ICLASS  FAR
  50. # endif
  51. #endif
  52.  
  53. #define _IFUNC STDMETHODCALLTYPE
  54.  
  55. class TRegList;
  56.  
  57. //____________________________________________________________________________
  58. //
  59. // TXOle - OLE API related exception object
  60. //____________________________________________________________________________
  61.  
  62. class TXOle : public TXBase {
  63.   public:
  64.     TXOle(const string& msg, HRESULT stat);
  65.     TXOle(const TXOle& src);
  66.    ~TXOle();
  67.  
  68.     TXOle* Clone();
  69.     void   Throw();
  70.  
  71.     static void Check(HRESULT stat, const char far* msg);
  72.     static void Check(HRESULT stat);
  73.     static void Throw(HRESULT stat, const char far* msg);
  74.     static void OleErrorFromCode(HRESULT stat, char far* buffer, int size);
  75.  
  76.     const long  Stat;
  77. };
  78. inline TXOle::TXOle(const string& msg, HRESULT stat)
  79.             : TXBase(msg), Stat((long)stat) {}
  80. inline TXOle::TXOle(const TXOle& src)
  81.             : TXBase(src), Stat(src.Stat) {}
  82.  
  83. #if (__DEBUG > 0) || defined(__WARN)
  84. # define OLECALL(func, msg) TXOle::Check(func, msg)
  85. #else
  86. # define OLECALL(func, msg) TXOle::Check(func)
  87. #endif
  88.  
  89. //____________________________________________________________________________
  90. //
  91. // TComRef - encapsulation of OLE interface pointers
  92. //____________________________________________________________________________
  93.  
  94. template<class T> class TComRefBase {
  95.   public:
  96.          operator T far*() {return I;}
  97.          operator T far* far*() {TComRefBase::~TComRefBase(); return &I;}
  98.     int  operator !() {return I==0;}
  99.     void operator delete(void* p) {((TComRefBase<T> far*)p)->I=0;}
  100.   protected:
  101.     TComRefBase(const TComRefBase<T>& i) : I(i.I) {I->AddRef();}
  102.     TComRefBase(T far* i) : I(i) {}
  103.     TComRefBase() : I(0) {}
  104.    ~TComRefBase() {if (I) I->Release(); I = 0;}
  105.     T* I;
  106.   private:
  107.     void* operator new(size_t) {return 0;}  // prohibit use of new
  108. };
  109.  
  110. template<class T> class TComRef : public TComRefBase<T> {
  111.   public:
  112.     TComRef() : TComRefBase<T>() {}
  113.     TComRef(T far* iface) : TComRefBase<T>(iface) {}
  114.     TComRef(const TComRef<T>& i) : TComRefBase<T>(i) {}
  115.     T far* operator =(T far* iface) {if(I)I->Release(); return I = iface;}
  116.     T far* operator =(const TComRef<T>& i) {if(I)I->Release(); return I=i.I;}
  117.     T far* operator->() {return I;} // should throw exception if I==0
  118. };
  119.  
  120. //____________________________________________________________________________
  121. //
  122. // TBSTR - BASIC global string encapsulation
  123. //____________________________________________________________________________
  124.  
  125. class TBSTR {
  126.   public:
  127.     TBSTR() : P(0) {}
  128.     TBSTR(BSTR p) : P(p) {}
  129.    ~TBSTR() {::SysFreeString(P);}
  130.     BSTR   operator =(BSTR p) {if(P)::SysFreeString(P); return P = p;}
  131.     TBSTR& operator =(const TBSTR& p){if(P)::SysFreeString(P);P=p.P;return *this;}
  132.            operator BSTR() {return P;}
  133.            operator BSTR far*() {if(P)::SysFreeString(P); return &P;}
  134.     int    operator !() {return P==0;}
  135.     void   operator ~() {if (P)::SysFreeString(P); P = 0;}
  136.   protected:
  137.     BSTR P;
  138.   private:
  139.     void* operator new(size_t) {return 0;} // prohibit use of new, delete, etc
  140.     void  operator delete(void*) {}
  141. };
  142.  
  143. //____________________________________________________________________________
  144. //
  145. // TOleAllocator - object to initialize OLE and access memory manager
  146. //____________________________________________________________________________
  147.  
  148. class TOleAllocator {
  149.   public:
  150.     TOleAllocator();            // gets allocator, does not initialize OLE
  151.     TOleAllocator(IMalloc* mem);// use 0 to initialize with OLE task allocator
  152.    ~TOleAllocator();
  153.     void far* Alloc(unsigned long size);
  154.     void Free(void far* pv);
  155.     IMalloc* Mem;
  156.   private:
  157.     bool Initialized;
  158. };
  159.  
  160. inline
  161. TOleAllocator::TOleAllocator(IMalloc* mem) : Initialized(true)
  162. {
  163.   OLECALL(OleInitialize(mem), "OleInitialize");
  164.   OLECALL(CoGetMalloc(MEMCTX_TASK, &Mem), "CoGetMalloc");
  165. }
  166.  
  167. inline
  168. TOleAllocator::TOleAllocator() : Initialized(false)
  169. {
  170.   OLECALL(CoGetMalloc(MEMCTX_TASK, &Mem), "CoGetMalloc");
  171. }
  172.  
  173. inline
  174. TOleAllocator::~TOleAllocator()
  175. {
  176.   if (Mem)
  177.     Mem->Release();
  178.   if (Initialized)
  179.     ::OleUninitialize();
  180. }
  181.  
  182. inline void
  183. TOleAllocator::Free(void far* pv)
  184. {
  185.   Mem->Free(pv);
  186. }
  187.  
  188. //____________________________________________________________________________
  189. //
  190. // TClassId - GUID/IID/CLSID management
  191. //____________________________________________________________________________
  192.  
  193. class far TClassId {
  194.   public:
  195.     enum TGenerate {Generate};
  196.     TClassId(const GUID far& guid);
  197.     TClassId(const char far* idtxt);
  198.     TClassId(const TClassId& copy);
  199.     TClassId(TGenerate);
  200.     TClassId & operator =(const TClassId& copy);
  201.     TClassId(const GUID far& guid, int offset);
  202.    ~TClassId();
  203.     operator GUID&();
  204.     operator const char*();
  205.  
  206.   protected:
  207.     TClassId();
  208.     GUID Guid;
  209.     const char* Text;
  210. };
  211.  
  212. inline TClassId::TClassId(const GUID far& guid) : Text(0) { Guid = guid; }
  213. inline TClassId::TClassId(const TClassId& copy) : Guid(copy.Guid), Text(0) {}
  214. inline TClassId::TClassId() : Text(0) {}  // Guid must be set by derived class
  215. inline TClassId::operator GUID&() { return Guid; }
  216. inline TClassId& TClassId::operator =(const TClassId& copy)
  217.                                      {Guid = copy.Guid; Text=0; return *this;}
  218.  
  219. class TBaseClassId : public TClassId {
  220.   public:
  221.     TBaseClassId(TRegList& regInfo, int maxAlloc = 256);
  222.     TBaseClassId(const GUID far& guid, int maxAlloc = 256);
  223.     TBaseClassId(const char far* idtxt, int maxAlloc = 256);
  224.     TBaseClassId(TGenerate, int maxAlloc = 256);
  225.     TClassId operator [](int offset);
  226.     int AllocId();
  227.     int GetOffset(const GUID far& guid); // returns -1 if not within range
  228.   private:
  229.     int Offset;    // last offset given out by AllocId(), creator reserves 0
  230.     int MaxAlloc;
  231. };
  232.  
  233. //____________________________________________________________________________
  234. //
  235. // Fast GUID compare functions, assume that low word has already matched OK
  236. //____________________________________________________________________________
  237.  
  238. void CmpGuid12(IUnknown* This, REFIID req, REFIID ref, void far*far* pif);
  239.  
  240. void CmpGuidOle(IUnknown* This, REFIID req, void far*far* pif);
  241.  
  242. //____________________________________________________________________________
  243. //
  244. // TUnknown - Standard implementation of a controlling IUnknown for an object,
  245. //            to be inherited with other COM interfaces into an implementation
  246. //            class whose IUnknown implementation delegates to TUnknown::Outer.
  247. //____________________________________________________________________________
  248.  
  249. class _ICLASS TUnknown {
  250.   public:
  251.     operator IUnknown&() {return *Outer;}
  252.     operator IUnknown*() {Outer->AddRef(); return Outer;}
  253.     IUnknown* SetOuter(IUnknown* outer = 0);
  254.     IUnknown* GetOuter() {return Outer;}
  255.     unsigned long GetRefCount();
  256.     unsigned long AdjustRefCount(int i);
  257.     IUnknown& Aggregate(TUnknown& inner);  // returns outermost IUnknown
  258.  
  259.   protected:
  260.     IUnknown& ThisUnknown() {return I;}
  261.     IUnknown* Outer;
  262.     TUnknown();
  263.     virtual ~TUnknown();
  264.     virtual HRESULT QueryObject(const GUID far& iid, void far* far* pif);
  265.  
  266.   private:
  267.     class _ICLASS TUnknownI : public IUnknown {
  268.       public:
  269.         HRESULT       _IFUNC QueryInterface(const GUID far& iid, void far*far* pif);
  270.         unsigned long _IFUNC AddRef();
  271.         unsigned long _IFUNC Release();
  272.         TUnknownI() : RefCnt(0), Inner(0) {}
  273.        ~TUnknownI();
  274.         unsigned  RefCnt;  // object's reference count, remains 1 if aggregated
  275.         TUnknown* Inner;   // chain of TUnknown-aggregated objects
  276.       private:
  277.         TUnknown& Host();
  278.     } I;
  279.   friend class TUnknownI;
  280. };
  281.  
  282. inline IUnknown* TUnknown::SetOuter(IUnknown* outer)
  283. {
  284.   if (outer) {
  285.     Outer = outer;
  286.     if (I.Inner)
  287.       I.Inner->SetOuter(outer);
  288.   }
  289.   return &I;
  290. }
  291.  
  292. inline TUnknown& TUnknown::TUnknownI::Host()
  293. {
  294.   return *(TUnknown*)((char*)this-(int)(&((TUnknown*)0)->I));
  295. }
  296.  
  297. inline unsigned long TUnknown::AdjustRefCount(int i)
  298. {
  299.   return (unsigned long)(I.RefCnt += i);
  300. }
  301.  
  302. //____________________________________________________________________________
  303. //
  304. // Macros to generate COM mixin classes for use with TUnknown
  305. //      Each base class must have an inline QueryInterface wrapper defined.
  306. //
  307. // DECLARE_COMBASES1(classname, base)    // declares support for 1 interface
  308. // DECLARE_COMBASES2(classname, base, base)      // mixes in for 2 interfaces
  309. //  .......
  310. // DEFINE_COMBASES1(classname, base)  // implements IUnknown for 1 interface
  311. // DEFINE_COMBASES2(classname, base, base)   // implements for 2 interfaces
  312. //  ......
  313. //
  314. // Macros to generate inline QueryInterface wrappers for interfaces/delegates
  315. //    (low GUID word may specify an explicit integer or an IID_whatever.Data1)
  316. //    For efficiency they are void functions; check result pointer for success
  317. //
  318. // DEFINE_QI_BASE(cls, low)      // Inherited COM interface with IUnknown base
  319. // DEFINE_QI_OLEBASE(cls, low)   // Inherited OLE interface using an OLE GUID
  320. // DEFINE_QI_DERIVED(cls, base, low)     // COM interface derived from another
  321. // DEFINE_QI_OLEDERIVED(cls, base, low)  // OLE interface derived from another
  322. // DEFINE_QI_DELEGATE(cls, member)       // Inherited object with COM member
  323. // DEFINE_QI_DELEGATE_TEST(cls, member)  // Object whose COM member may be 0
  324. // DEFINE_QI_MEMBER(name, member)        // Used inside object with COM member
  325. // DEFINE_QI_MEMBER_TEST(name, member)   // Where object's COM member may be 0
  326. //
  327. // Macro to invoke inline QueryInterface wrappers and return if successful
  328. //    A list of these is generated by the DEFINE_COMBASESn(...) macro
  329. //
  330. // COMBASEQUERY(name) // Calls name_QueryInterface(), returns OK if success
  331. //
  332. // Macro to provide standard IUnknown implementation which forwards to Outer
  333. //    This macro is automatically invoked by the DEFINE_COMBASESn(...) macro
  334. //
  335. // IUNKNOWN_FORWARD(cls, outer) // cls IUnknown implementation forwards to outer
  336. //
  337. // Example of user-written COM class inheriting from macro-generated mixin
  338. //
  339. //  class TSample : public classname {
  340. //   public:
  341. //    TSample(IUnknown* outer, IUnknown*far* pif) { *pif = SetOuter(outer); }
  342. //  };
  343. //____________________________________________________________________________
  344.  
  345. #define COMBASES_D(cls, bases)     \
  346.   class cls : public TUnknown, bases { \
  347.   protected:                        \
  348.     virtual HRESULT _IFUNC QueryInterface(const GUID far& iid, void far*far* pif); \
  349.     virtual unsigned long _IFUNC AddRef();  \
  350.     virtual unsigned long _IFUNC Release(); \
  351.     virtual HRESULT QueryObject(const GUID far& iid, void far*far* pif); \
  352.             HRESULT QueryBases(const GUID far& iid, void far*far* pif) \
  353.                                {return cls::QueryObject(iid, pif);} \
  354.   }; // QueryBases() is an inline wrapper to this QueryObject() implementation
  355.  
  356. #define COMQRY1BASES(i1)             protected i1
  357. #define COMQRY2BASES(i1,i2)          protected i1, COMQRY1BASES(i2)
  358. #define COMQRY3BASES(i1,i2,i3)       protected i1, COMQRY2BASES(i2,i3)
  359. #define COMQRY4BASES(i1,i2,i3,i4)    protected i1, COMQRY3BASES(i2,i3,i4)
  360. #define COMQRY5BASES(i1,i2,i3,i4,i5) protected i1, COMQRY4BASES(i2,i3,i4,i5)
  361.  
  362. #define DECLARE_COMBASES1(cls,i1) \
  363.   COMBASES_D(cls,COMQRY1BASES(i1))
  364. #define DECLARE_COMBASES2(cls,i1,i2) \
  365.   COMBASES_D(cls,COMQRY2BASES(i1,i2))
  366. #define DECLARE_COMBASES3(cls,i1,i2,i3) \
  367.   COMBASES_D(cls,COMQRY3BASES(i1,i2,i3))
  368. #define DECLARE_COMBASES4(cls,i1,i2,i3,i4) \
  369.   COMBASES_D(cls,COMQRY4BASES(i1,i2,i3,i4))
  370. #define DECLARE_COMBASES5(cls,i1,i2,i3,i4,i5) \
  371.   COMBASES_D(cls,COMQRY5BASES(i1,i2,i3,i4,i5))
  372.  
  373. #define IUNKNOWN_FORWARD(cls, outer) \
  374.   HRESULT _IFUNC cls::QueryInterface(const GUID far& iid, void far* far* pif)\
  375.                                  { return outer->QueryInterface(iid, pif); } \
  376.   unsigned long _IFUNC cls::AddRef()  { return outer->AddRef(); } \
  377.   unsigned long _IFUNC cls::Release() { return outer->Release(); }
  378.  
  379. #define COMBASES_I(cls, tests) \
  380.   IUNKNOWN_FORWARD(cls, Outer) \
  381.   HRESULT cls::QueryObject(const GUID far& iid, void far*far* pif) \
  382.          { *pif = 0; tests return ResultFromScode(E_NOINTERFACE); }
  383.  
  384. #define COMBASEQUERY(cls) \
  385.   cls##_QueryInterface(this,iid,pif); if(*pif) return NOERROR;
  386.  
  387. #define COMQRY1TEST(i1)             COMBASEQUERY(i1)
  388. #define COMQRY2TEST(i1,i2)          COMBASEQUERY(i1) COMQRY1TEST(i2)
  389. #define COMQRY3TEST(i1,i2,i3)       COMBASEQUERY(i1) COMQRY2TEST(i2,i3)
  390. #define COMQRY4TEST(i1,i2,i3,i4)    COMBASEQUERY(i1) COMQRY3TEST(i2,i3,i4)
  391. #define COMQRY5TEST(i1,i2,i3,i4,i5) COMBASEQUERY(i1) COMQRY3TEST(i2,i3,i4,i5)
  392.  
  393. #define DEFINE_COMBASES1(cls,i1) \
  394.   COMBASES_I(cls,COMQRY1TEST(i1))
  395. #define DEFINE_COMBASES2(cls,i1,i2) \
  396.   COMBASES_I(cls,COMQRY2TEST(i1,i2))
  397. #define DEFINE_COMBASES3(cls,i1,i2,i3) \
  398.   COMBASES_I(cls,COMQRY3TEST(i1,i2,i3))
  399. #define DEFINE_COMBASES4(cls,i1,i2,i3,i4) \
  400.   COMBASES_I(cls,COMQRY4TEST(i1,i2,i3,i4))
  401. #define DEFINE_COMBASES5(cls,i1,i2,i3,i4,i5) \
  402.   COMBASES_I(cls,COMQRY5TEST(i1,i2,i3,i4,i5))
  403.  
  404. #define DEFINE_QI_BASE(cls, low) \
  405.   inline void cls##_QueryInterface(cls* obj, REFIID iid, void FAR* FAR* pif) \
  406.   {if (iid.Data1==low) CmpGuid12(obj, iid, IID_##cls, pif);}
  407.  
  408. #define DEFINE_QI_OLEBASE(cls, low) \
  409.   inline void cls##_QueryInterface(cls* obj, REFIID iid, void FAR* FAR* pif) \
  410.   {if (iid.Data1==low) CmpGuidOle(obj, iid, pif);}
  411.  
  412. #define DEFINE_QI_DERIVED(cls, base, low) \
  413.   inline void cls##_QueryInterface(cls* obj, REFIID iid, void FAR* FAR* pif) \
  414.   {if (iid.Data1==low) CmpGuid12(obj, iid, IID_##cls, pif); \
  415.   else base##_QueryInterface(obj, iid, pif);}
  416.  
  417. #define DEFINE_QI_OLEDERIVED(cls, base, low) \
  418.   inline void cls##_QueryInterface(cls* obj, REFIID iid, void FAR* FAR* pif) \
  419.   {if (iid.Data1==low) CmpGuidOle(obj, iid, pif); \
  420.   else base##_QueryInterface(obj, iid, pif);}
  421.  
  422. #define DEFINE_QI_DELEGATE(cls, member) \
  423.   inline void cls##_QueryInterface(cls* obj, REFIID iid, void FAR* FAR* pif) \
  424.   {obj->member->QueryInterface(iid, pif);}
  425.  
  426. #define DEFINE_QI_DELEGATE_TEST(cls, member) \
  427.   inline void cls##_QueryInterface(cls* obj, REFIID iid, void FAR* FAR* pif) \
  428.   {if (obj->member) obj->member->QueryInterface(iid, pif);}
  429.  
  430. #define DEFINE_QI_MEMBER(name, member) \
  431.   void name##_QueryInterface(void far*, REFIID iid, void FAR* FAR* pif) \
  432.   {member->QueryInterface(iid, pif);}
  433.  
  434. #define DEFINE_QI_MEMBER_TEST(name, member) \
  435.   void name##_QueryInterface(void far*, REFIID iid, void FAR* FAR* pif) \
  436.   {if (member) member->QueryInterface(iid, pif);}
  437.  
  438. #define DEFINE_COMBASE_DELEGATE(cls, ifc, member) \
  439.   struct _ICLASS cls { \
  440.     cls() : member(0) {} \
  441.     ifc* member; \
  442.     DEFINE_QI_MEMBER_TEST(cls, member) \
  443.   };
  444.  
  445. #endif  //  OCF_OLEUTIL_H
  446.  
  447.  
  448.