|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: NOUTIL.hxx
//
// Contents: Definitions of utility stuff for use
//
// Classes: StdClassFactory
//
// Functions:
//
// Macros:
//
// History:
//
//----------------------------------------------------------------------------
#ifndef _NOUTIL_HXX_
#define _NOUTIL_HXX_
#include <formtrck.hxx>
//+---------------------------------------------------------------------
//
// Generally useful #defines and inline functions for OLE2.
//
//------------------------------------------------------------------------
// These are the major and minor version returned by OleBuildVersion
#define OLE_MAJ_VER 0x0003
#define OLE_MIN_VER 0x003A
//---------------------------------------------------------------
// SCODE and HRESULT macros
//---------------------------------------------------------------
#define OK(r) (SUCCEEDED(r))
#define NOTOK(r) (FAILED(r))
//---------------------------------------------------------------
// IUnknown
//---------------------------------------------------------------
#define ADsIncrement(__ul) InterlockedIncrement((long *) &__ul)
#define ADsDecrement(__ul) InterlockedDecrement((long *) &__ul)
#define DECLARE_ADs_IUNKNOWN_METHODS \
STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppv); \ STDMETHOD_(ULONG, AddRef) (void); \ STDMETHOD_(ULONG, Release) (void);
#define DECLARE_ADs_STANDARD_IUNKNOWN(cls) \
STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppv); \ ULONG _ulRefs; \ STDMETHOD_(ULONG, AddRef) (void) \ { \ ADsIncrement(_ulRefs); \ return _ulRefs; \ } \ STDMETHOD_(ULONG, Release) (void) \ { \ if (!ADsDecrement(_ulRefs)) \ { \ ADsIncrement(_ulRefs); \ delete this; \ return 0; \ } \ return _ulRefs; \ }
#define DECLARE_ADs_DELEGATING_IUNKNOWN(cls) \
IUnknown * _pUnkOuter; \ STDMETHOD(QueryInterface) (REFIID iid, LPVOID * ppv) \ { return _pUnkOuter->QueryInterface(iid, ppv); } \ STDMETHOD_(ULONG, AddRef) (void) \ { return _pUnkOuter->AddRef(); } \ STDMETHOD_(ULONG, Release) (void) \ { return _pUnkOuter->Release(); }
#define DECLARE_DELEGATING_REFCOUNTING \
IUnknown * _pUnkOuter; \ STDMETHOD_(ULONG, AddRef) (void) \ { return _pUnkOuter->AddRef(); } \ STDMETHOD_(ULONG, Release) (void) \ { return _pUnkOuter->Release(); }
#if DBG == 0
//
// Retail versions of these macros
//
#define DECLARE_ADs_PRIVATE_IUNKNOWN(cls) \
class PrivateUnknown : public IUnknown \ { \ private: \ ULONG _ulRefs; \ cls * My##cls(void) \ { return CONTAINING_RECORD(this, cls, _PrivUnk); } \ \ public: \ PrivateUnknown(void) \ { _ulRefs = 1; } \ \ DECLARE_ADs_IUNKNOWN_METHODS \ }; \ friend class PrivateUnknown; \ PrivateUnknown _PrivUnk;
#define IMPLEMENT_ADs_PRIVATE_IUNKNOWN(cls) \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \ { \ ADsIncrement(_ulRefs); \ return _ulRefs; \ } \ STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \ { \ if (!ADsDecrement(_ulRefs)) \ { \ ADsIncrement(_ulRefs); \ delete My##cls(); \ return 0; \ } \ return _ulRefs; \ }
#define DECLARE_ADs_COMPOUND_IUNKNOWN(cls) \
class PrivateUnknown : public IUnknown \ { \ friend class cls; \ \ public: \ PrivateUnknown(void) \ { _ulRefs = 1; _ulAllRefs = 1; } \ \ DECLARE_ADs_IUNKNOWN_METHODS \ \ private: \ ULONG _ulRefs; \ ULONG _ulAllRefs; \ \ cls * My##cls(void) \ { return CONTAINING_RECORD(this, cls, _PrivUnk); } \ }; \ friend class PrivateUnknown; \ PrivateUnknown _PrivUnk; \ \ ULONG SubAddRef(void); \ ULONG SubRelease(void);
#define IMPLEMENT_ADs_COMPOUND_IUNKNOWN(cls) \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \ { \ ADsIncrement(_ulAllRefs); \ ADsIncrement(_ulRefs); \ return _ulRefs; \ } \ STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \ { \ if (!ADsDecrement(_ulRefs)) \ { \ My##cls()->Passivate(); \ } \ if (!ADsDecrement(_ulAllRefs)) \ { \ ADsIncrement(_ulAllRefs); \ delete My##cls(); \ return 0; \ } \ return _ulRefs; \ } \ ULONG cls::SubAddRef( ) \ { \ return ADsIncrement(_PrivUnk._ulAllRefs); \ } \ ULONG cls::SubRelease( ) \ { \ ULONG ul; \ \ ul = ADsDecrement(_PrivUnk._ulAllRefs); \ if (!ul) \ { \ ADsIncrement(_PrivUnk._ulAllRefs); \ delete this; \ } \ \ return ul; \ }
#else // DBG == 0
//
// Debug versions of these macros
//
#define DECLARE_ADs_PRIVATE_IUNKNOWN(cls) \
class PrivateUnknown : protected ObjectTracker, \ public IUnknown \ { \ private: \ cls * My##cls(void) \ { return CONTAINING_RECORD(this, cls, _PrivUnk); } \ \ public: \ PrivateUnknown(void) \ { _ulRefs = 1; TrackClassName(#cls); } \ \ DECLARE_ADs_IUNKNOWN_METHODS \ }; \ friend class PrivateUnknown; \ PrivateUnknown _PrivUnk;
#define IMPLEMENT_ADs_PRIVATE_IUNKNOWN(cls) \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \ { \ StdAddRef(); \ return _ulRefs; \ } \ STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \ { \ if (!StdRelease()) \ { \ ADsIncrement(_ulRefs); \ delete My##cls(); \ return 0; \ } \ return _ulRefs; \ }
#define DECLARE_ADs_COMPOUND_IUNKNOWN(cls) \
class PrivateUnknown : protected ObjectTracker, \ public IUnknown \ { \ friend class cls; \ \ public: \ PrivateUnknown(void) \ { _ulNRefs = 1; _ulRefs = 1; TrackClassName(#cls); } \ \ DECLARE_ADs_IUNKNOWN_METHODS \ \ private: \ ULONG _ulNRefs; \ \ cls * My##cls(void) \ { return CONTAINING_RECORD(this, cls, _PrivUnk); } \ }; \ friend class PrivateUnknown; \ PrivateUnknown _PrivUnk; \ \ ULONG SubAddRef(void); \ ULONG SubRelease(void);
#define IMPLEMENT_ADs_COMPOUND_IUNKNOWN(cls) \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \ { \ StdAddRef(); \ ADsIncrement(_ulNRefs); \ return _ulNRefs; \ } \ STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \ { \ if (!ADsDecrement(_ulNRefs)) \ { \ My##cls()->Passivate(); \ } \ if (!StdRelease()) \ { \ ADsIncrement(_ulRefs); \ delete My##cls(); \ return 0; \ } \ return _ulNRefs; \ } \ ULONG cls::SubAddRef( ) \ { \ return _PrivUnk.StdAddRef(); \ } \ ULONG cls::SubRelease( ) \ { \ ULONG ul; \ \ ul = _PrivUnk.StdRelease(); \ if (!ul) \ { \ ADsIncrement(_PrivUnk._ulRefs); \ delete this; \ } \ \ return ul; \ }
#endif // DBG == 0
// The Detach method is no longer useful, now that we've
// removed the parent class pointer
#define DECLARE_ADs_SUBOBJECT_IUNKNOWN(cls, parent_cls, member) \
DECLARE_ADs_IUNKNOWN_METHODS \ parent_cls * My##parent_cls(void); \ void Detach(void) \ { ; }
#define IMPLEMENT_ADs_SUBOBJECT_IUNKNOWN(cls, parent_cls, member) \
inline parent_cls * cls::My##parent_cls(void) \ { \ return CONTAINING_RECORD(this, parent_cls, member); \ } \ STDMETHODIMP_(ULONG) cls::AddRef( ) \ { return My##parent_cls()->SubAddRef(); } \ STDMETHODIMP_(ULONG) cls::Release( ) \ { return My##parent_cls()->SubRelease(); }
//+------------------------------------------------------------------------
//
// NO_COPY *declares* the constructors and assignment operator for copying.
// By not *defining* these functions, you can prevent your class from
// accidentally being copied or assigned -- you will be notified by
// a linkage error.
//
//-------------------------------------------------------------------------
#define NO_COPY(cls) \
cls(const cls&); \ cls& operator=(const cls&);
//+---------------------------------------------------------------------
//
// Miscellaneous useful OLE helper and debugging functions
//
//----------------------------------------------------------------------
//
// Some convenient OLE-related definitions and declarations
//
typedef unsigned short far * LPUSHORT;
//REVIEW we are experimenting with a non-standard OLEMISC flag.
#define OLEMISC_STREAMABLE 1024
#include "misc.hxx"
#if DBG == 1
STDAPI_(void) PrintIID(DWORD dwFlags, REFIID riid);
#define TRACEIID(iid) PrintIID(DEB_TRACE, iid)
#else // DBG == 0
#define TRACEIID(iid)
#endif // DBG
//+---------------------------------------------------------------------
//
// Interface wrapper for tracing method invocations
//
//----------------------------------------------------------------------
#if DBG == 1
LPVOID WatchInterface(REFIID riid, LPVOID pv, LPWSTR lpstr); #define WATCHINTERFACE(iid, p, lpstr) WatchInterface(iid, p, lpstr)
#else // DBG == 0
#define WATCHINTERFACE(iid, p, lpstr) (p)
#endif // DBG
//+---------------------------------------------------------------------
//
// Standard IClassFactory implementation
//
//----------------------------------------------------------------------
//+---------------------------------------------------------------
//
// Class: StdClassFactory
//
// Purpose: Standard implementation of a class factory object
//
// Notes: **************!!!!!!!!!!!!!!!!!*************
// TAKE NOTE --- The implementation of Release on this
// class does not perform a delete. This is so you can
// make the class factory a global static variable.
// Use the CDynamicCF class below for an object
// which is not global static data.
//
// ALSO - The refcount is initialized to 0, NOT 1!
//
//---------------------------------------------------------------
class StdClassFactory: public IClassFactory { public: StdClassFactory(void) : _ulRefs(1) {};
// IUnknown methods
DECLARE_ADs_IUNKNOWN_METHODS;
// IClassFactory methods
STDMETHOD(LockServer) (BOOL fLock);
// CreateInstance is left pure virtual.
protected: ULONG _ulRefs; };
//+---------------------------------------------------------------------------
//
// Class: CDynamicCF (DYNCF)
//
// Purpose: Class factory which exists on the heap, and whose Release
// method does the normal thing.
//
// Interface: DECLARE_ADs_STANDARD_IUNKNOWN -- IUnknown methods
//
// LockServer -- Per IClassFactory.
// CDynamicCF -- ctor.
// ~CDynamicCF -- dtor.
//
// History: 6-22-94 adams Created
// 7-13-94 adams Moved from ADs\inc\dyncf.hxx
//
//----------------------------------------------------------------------------
class CDynamicCF: public IClassFactory { public: // IUnknown methods
DECLARE_ADs_STANDARD_IUNKNOWN(CDynamicCF)
// IClassFactory methods
STDMETHOD(LockServer) (BOOL fLock);
protected: CDynamicCF(void); virtual ~CDynamicCF(void); };
#endif //__NOUTILS_HXX_
|