home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / activexcontrol / basectl / include / unknown.h < prev    next >
C/C++ Source or Header  |  1997-10-05  |  5KB  |  157 lines

  1. //=--------------------------------------------------------------------------=
  2. // Unknown.H
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1997 Microsoft Corporation.  All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // a class definition for an IUnknown super-class that will support
  13. // aggregation.
  14. //
  15. #ifndef _UNKNOWN_H_
  16.  
  17. //=--------------------------------------------------------------------------=
  18. // UNKNOWNOBJECTINFO
  19. //
  20. // if you want a simple co-creatable object, with no other guarantees about
  21. // it, then you need to put the following entry in the global table of objects.
  22. // other object types that are more complex, such as automation objects, and
  23. // controls, will also use this information...
  24. //
  25. typedef struct {
  26.  
  27.     const CLSID *rclsid;                    // CLSID of your object.      ONLY USE IF YOU'RE CoCreatable!
  28.     LPCSTR       pszObjectName;             // Name of your object.       ONLY USE IF YOU'RE CoCreatable!
  29.     IUnknown    *(*pfnCreate)(IUnknown *);  // pointer to creation fn.    ONLY USE IF YOU'RE CoCreatable!
  30.  
  31. } UNKNOWNOBJECTINFO;
  32.  
  33. #define NAMEOFOBJECT(index)       (((UNKNOWNOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->pszObjectName)
  34. #define CLSIDOFOBJECT(index)      (*(((UNKNOWNOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->rclsid))
  35. #define CREATEFNOFOBJECT(index)   (((UNKNOWNOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->pfnCreate)
  36.  
  37. #ifndef INITOBJECTS
  38.  
  39. #define DEFINE_UNKNOWNOBJECT(name, clsid, objname, fn) \
  40. extern UNKNOWNOBJECTINFO name##Object \
  41.  
  42. #else
  43. #define DEFINE_UNKNOWNOBJECT(name, clsid, objname, fn) \
  44.     UNKNOWNOBJECTINFO name##Object = { clsid, objname, fn } \
  45.  
  46. #endif // INITOBJECTS
  47.  
  48.  
  49. //=--------------------------------------------------------------------------=
  50. // DECLARE_STANDARD_UNKNOWN
  51. //
  52. // All objects that are going to inherit from CUnknown for their IUnknown
  53. // implementation should put this in their class declaration instead of the
  54. // three IUnknown methods.
  55. //
  56. #define DECLARE_STANDARD_UNKNOWN() \
  57.     STDMETHOD(QueryInterface)(REFIID riid, void **ppvObjOut) { \
  58.         return ExternalQueryInterface(riid, ppvObjOut); \
  59.     } \
  60.     STDMETHOD_(ULONG, AddRef)(void) { \
  61.         return ExternalAddRef(); \
  62.     } \
  63.     STDMETHOD_(ULONG, Release)(void) { \
  64.         return ExternalRelease(); \
  65.     } \
  66.  
  67. // global variable where we store the current lock count on our DLL.  This resides
  68. // in InProcServer.Cpp
  69. //
  70. extern LONG g_cLocks;
  71.  
  72.  
  73.  
  74. //=--------------------------------------------------------------------------=
  75. // this class doesn't inherit from IUnknown since people inheriting from it
  76. // are going to do so, and just delegate their IUnknown calls to the External*
  77. // member functions on this object.  the internal private unknown object does
  78. // need to inherit from IUnknown, since it will be used directly as an IUnknown
  79. // object.
  80. //
  81. class CUnknownObject {
  82.  
  83.   public:
  84.     CUnknownObject(IUnknown *pUnkOuter, void *pvInterface)
  85.         : m_pvInterface(pvInterface),
  86.           m_pUnkOuter((pUnkOuter) ? pUnkOuter : &m_UnkPrivate)
  87.         {  InterlockedIncrement(&g_cLocks); }
  88.  
  89.     virtual ~CUnknownObject() { InterlockedDecrement(&g_cLocks); }
  90.  
  91.     // these are all protected so that classes that inherit from this can
  92.     // at get at them.
  93.     //
  94.   protected:
  95.     // IUnknown methods.  these just delegate to the controlling
  96.     // unknown.
  97.     //
  98.     HRESULT ExternalQueryInterface(REFIID riid, void **ppvObjOut) {
  99.         return m_pUnkOuter->QueryInterface(riid, ppvObjOut);
  100.     }
  101.     ULONG ExternalAddRef(void) {
  102.         return m_pUnkOuter->AddRef();
  103.     }
  104.     ULONG ExternalRelease(void) {
  105.         return m_pUnkOuter->Release();
  106.     }
  107.  
  108.     // people should use this during creation to return their private
  109.     // unknown
  110.     //
  111.     inline IUnknown *PrivateUnknown (void) {
  112.         return &m_UnkPrivate;
  113.     }
  114.  
  115.     virtual HRESULT InternalQueryInterface(REFIID riid, void **ppvObjOut);
  116.  
  117.     IUnknown *m_pUnkOuter;            // outer controlling Unknown
  118.     void     *m_pvInterface;          // the real interface we're working with.
  119.  
  120.   private:
  121.     // the inner, private unknown implementation is for the aggregator
  122.     // to control the lifetime of this object, and for those cases where
  123.     // this object isn't aggregated.
  124.     //
  125.     class CPrivateUnknownObject : public IUnknown {
  126.       public:
  127.         STDMETHOD(QueryInterface)(REFIID riid, void **ppvObjOut);
  128.         STDMETHOD_(ULONG, AddRef)(void);
  129.         STDMETHOD_(ULONG, Release)(void);
  130.  
  131.         // constructor is remarkably trivial
  132.         //
  133.         CPrivateUnknownObject() : m_cRef(1) {}
  134.  
  135.       private:
  136.         CUnknownObject *m_pMainUnknown();
  137.         ULONG m_cRef;
  138.     } m_UnkPrivate;
  139.  
  140.     // so they can reference themselves in CUnknownObject from pMainUnknown()
  141.     //
  142.     friend class CPrivateUnknownObject;
  143.  
  144.     // by overriding this, people inheriting from this unknown can implement
  145.     // additional interfaces.  declared as private here so they have to use their
  146.     // own version.
  147.     //
  148. };
  149.  
  150.  
  151.  
  152.  
  153. #define _UNKNOWN_H_
  154. #endif // _UNKNOWN_H_
  155.  
  156.  
  157.