|
|
#ifndef COMPTR_H
#define COMPTR_H
#if _MSC_VER >= 1100
#pragma warning(disable:4800)
#include <comdef.h>
#define CIP_RETYPEDEF(I) typedef I##Ptr I##CIP;
#define CIP_TYPEDEF(I) _COM_SMARTPTR_TYPEDEF(I, IID_##I); CIP_RETYPEDEF(I);
#define DEFINE_CIP(x)\
CIP_TYPEDEF(x)
#define DECLARE_CIP(x) DEFINE_CIP(x) x##CIP
CIP_RETYPEDEF(IUnknown); CIP_RETYPEDEF(IDataObject); CIP_RETYPEDEF(IStorage); CIP_RETYPEDEF(IStream); CIP_RETYPEDEF(IPersistStorage); CIP_RETYPEDEF(IPersistStream); CIP_RETYPEDEF(IPersistStreamInit); CIP_RETYPEDEF(IDispatch);
#else // _MSC_VER < 1100
#define USE_OLD_COMPILER (_MSC_VER<1100)
#define USE_INTERMEDIATE_COMPILER (USE_OLD_COMPILER && (_MSC_VER>1020))
// This avoids "warning C4290: C++ Exception Specification ignored"
// JonN 12/16/96
#pragma warning(4:4290)
#ifndef BOOL_H
#include <bool.h>
#endif
#ifndef __wtypes_h__
#include <wtypes.h>
#endif
template<typename _Interface, const IID* _IID/*=&__uuidof(_Interface)*/> class CIID // Provide Interface to IID association
{ public: typedef _Interface Interface;
public: static _Interface* GetInterfacePtr() throw() { return NULL; }
public: static _Interface& GetInterface() throw() { return *GetInterfacePtr(); }
public: static const IID& GetIID() throw() { return *_IID; } }; // class CIID
template<typename _CIID> class CIP { #if USE_OLD_COMPILER
private: class _IUnknown: public IUnknown {}; // Unique type used to provide for operations between different pointer
// types.
#endif // USE_OLD_COMPILER
// Declare interface type so that the type may be available outside
// the scope of this template.
public: typedef _CIID ThisCIID; public: typedef _CIID::Interface Interface;
public: static const IID& GetIID() throw() // When the compiler supports references in template params,
// _CLSID will be changed to a reference. To avoid conversion
// difficulties this function should be used to obtain the
// CLSID.
{ return ThisCIID::GetIID(); }
//REVIEW: add support for assignment of nonpointer interfaces
// i.e. IUnknown, instead of simple IUnknown*
public: CIP() throw() // Construct empty in preperation for assignment.
: _pInterface(NULL) { }
public: CIP(int null) throw() // This constructor is provided to allow NULL assignment. It will assert
// if any value other than null is assigned to the object.
: _pInterface(NULL) { ASSERT(!null); }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
template<typename _InterfacePtr> CIP(_InterfacePtr p) throw() // Queries for this interface.
#else
public: CIP(_IUnknown& p) throw() : _pInterface(NULL) { if (&p) { const HRESULT hr = _QueryInterface(&p); ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE); } else _pInterface = NULL; }
public: CIP(IUnknown* p) throw() #endif // !USE_OLD_COMPILER
: _pInterface(NULL) { if (p) { const HRESULT hr = _QueryInterface(p); ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE); } else _pInterface = NULL; }
public: CIP(const CIP& cp) throw() // Copy the pointer and AddRef().
: _pInterface(cp._pInterface) { _AddRef(); }
public: CIP(Interface* pInterface) throw() // Saves the interface
: _pInterface(pInterface) { _AddRef(); }
public: CIP(Interface* pInterface, bool bAddRef) throw() // Copies the pointer. If bAddRef is TRUE, the interface will
// be AddRef()ed.
: _pInterface(pInterface) { if (bAddRef) { ASSERT(!pInterface); if (pInterface) _AddRef(); } }
public: CIP(const CLSID& clsid, DWORD dwClsContext = CLSCTX_ALL) explicit throw() // Calls CoCreateClass with the provided CLSID.
: _pInterface(NULL) { const HRESULT hr = CreateInstance(clsid, dwClsContext); ASSERT(SUCCEEDED(hr)); }
public: CIP(LPOLESTR str, DWORD dwClsContext = CLSCTX_ALL) explicit throw() // Calls CoCreateClass with the provided CLSID retrieved from
// the string.
: _pInterface(NULL) { const HRESULT hr = CreateInstance(str, dwClsContext); ASSERT(SUCCEEDED(hr)); }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
public: template<typename _InterfacePtr> CIP& operator=(_InterfacePtr& p) throw() // Queries for interface.
#else
public: CIP& operator=(_IUnknown& p) throw() { return operator=(static_cast<IUnknown*>(&p)); }
public: CIP& operator=(IUnknown* p) throw() #endif // !USE_OLD_COMPILER
{ const HRESULT hr = _QueryInterface(p); ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE); return *this; }
public: CIP& operator=(Interface* pInterface) throw() // Saves the interface.
{ if (_pInterface != pInterface) { Interface* pOldInterface = _pInterface; _pInterface = pInterface; _AddRef(); if (pOldInterface) pOldInterface->Release(); } return *this; }
public: CIP& operator=(const CIP& cp) throw() // Copies and AddRef()'s the interface.
{ return operator=(cp._pInterface); }
public: CIP& operator=(int null) throw() // This operator is provided to permit the assignment of NULL to the class.
// It will assert if any value other than NULL is assigned to it.
{ ASSERT(!null); return operator=(reinterpret_cast<Interface*>(NULL)); }
public: ~CIP() throw() // If we still have an interface then Release() it. The interface
// may be NULL if Detach() has previosly been called, or if it was
// never set.
{ _Release(); }
public: void Attach(Interface* pInterface) throw() // Saves/sets the interface without AddRef()ing. This call
// will release any previously aquired interface.
{ _Release(); _pInterface = pInterface; }
public: void Attach(Interface* pInterface, bool bAddRef) throw() // Saves/sets the interface only AddRef()ing if bAddRef is TRUE.
// This call will release any previously aquired interface.
{ _Release(); _pInterface = pInterface; if (bAddRef) { ASSERT(pInterface); if (pInterface) pInterface->AddRef(); } }
public: Interface* Detach() throw() // Simply NULL the interface pointer so that it isn't Released()'ed.
{ Interface* const old=_pInterface; _pInterface = NULL; return old; }
public: operator Interface*() const throw() // Return the interface. This value may be NULL
{ return _pInterface; }
public: Interface& operator*() const throw() // Allows an instance of this class to act as though it were the
// actual interface. Also provides minimal assertion verification.
{ ASSERT(_pInterface); return *_pInterface; }
public: Interface** operator&() throw() // Returns the address of the interface pointer contained in this
// class. This is useful when using the COM/OLE interfaces to create
// this interface.
{ _Release(); _pInterface = NULL; return &_pInterface; }
public: Interface* operator->() const throw() // Allows this class to be used as the interface itself.
// Also provides simple assertion verification.
{ ASSERT(_pInterface); return _pInterface; }
public: operator bool() const throw() // This operator is provided so that simple boolean expressions will
// work. For example: "if (p) ...".
// Returns TRUE if the pointer is not NULL.
{ return _pInterface; }
public: bool operator!() throw() // Returns TRUE if the interface is NULL.
// This operator will be removed when support for type bool
// is added to the compiler.
{ return !_pInterface; }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
public: template<typename _InterfacePtr> bool operator==(_InterfacePtr p) throw() // Compare to pointers
#else
public: bool operator==(_IUnknown& p) throw() { return operator==(static_cast<IUnknown*>(&p)); }
public: bool operator==(IUnknown* p) throw() #endif // !USE_OLD_COMPILER
{ return !_CompareUnknown(p); }
public: bool operator==(Interface* p) throw() // Compare with other interface
{ return (_pInterface == p) ? true : !_CompareUnknown(p); }
public: bool operator==(CIP& p) throw() // Compares 2 CIPs
{ return operator==(p._pInterface); }
public: bool operator==(int null) throw() // For comparison to NULL
{ ASSERT(!null); return !_pInterface; }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
public: template<typename _InterfacePtr> bool operator!=(_InterfacePtr p) throw() // Compare to pointers
#else
public: bool operator!=(_IUnknown& p) throw() { return operator!=(static_cast<IUnknown*>(&p)); }
public: bool operator!=(IUnknown* p) throw() #endif // !USE_OLD_COMPILER
{ return _CompareUnknown(p); }
public: bool operator!=(Interface* p) throw() // Compare with other interface
{ return (_pInterface!=p)?true:_CompareUnknown(p); }
public: bool operator!=(CIP& p) throw() // Compares 2 CIPs
{ return operator!=(p._pInterface); }
public: bool operator!=(int null) throw() // For comparison to NULL
{ ASSERT(!null); return _pInterface; }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
public: template<typename _InterfacePtr> bool operator<(_InterfacePtr p) throw() // Compare to pointers
#else
public: bool operator<(_IUnknown& p) throw() { return operator<(static_cast<IUnknown*>(&p)); }
public: bool operator<(IUnknown* p) throw() #endif // !USE_OLD_COMPILER
{ return _CompareUnknown(p)<0; }
public: bool operator<(Interface* p) throw() // Compare with other interface
{ return (_pInterface<p) ? true : _CompareUnknown(p) < 0; }
public: bool operator<(CIP& p) throw() // Compares 2 CIPs
{ return operator<(p._pInterface); }
public: bool operator<(int null) throw() // For comparison with NULL
{ ASSERT(!null); return _pInterface<NULL; }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
public: template<typename _InterfacePtr> bool operator>(_InterfacePtr p) throw() // Compare to pointers
#else
public: bool operator>(_IUnknown& p) throw() { return operator>(static_cast<IUnknown*>(&p)); }
public: bool operator>(IUnknown* p) throw() #endif // !USE_OLD_COMPILER
{ return _CompareUnknown(p) > 0; }
public: bool operator>(Interface* p) throw() // Compare with other interface
{ return (_pInterface>p) ? true : _CompareUnknown(p) > 0; }
public: bool operator>(CIP& p) throw() // Compares 2 CIPs
{ return operator>(p._pInterface); }
public: bool operator>(int null) throw() // For comparison with NULL
{ ASSERT(!null); return _pInterface > NULL; }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
public: template<typename _InterfacePtr> bool operator<=(_InterfacePtr p) throw() // Compare to pointers
#else
public: bool operator<=(_IUnknown& p) throw() { return operator<=(static_cast<IUnknown*>(&p)); }
public: bool operator<=(IUnknown* p) throw() #endif // !USE_OLD_COMPILER
{ return _CompareUnknown(p)<=0; }
public: bool operator<=(Interface* p) throw() // Compare with other interface
{ return (_pInterface<=p) ? true : _CompareUnknown(p) <= 0; }
public: bool operator<=(CIP& p) throw() // Compares 2 CIPs
{ return operator<=(p._pInterface); }
public: bool operator<=(int null) throw() // For comparison with NULL
{ ASSERT(!null); return _pInterface <= NULL; }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
public: template<typename _InterfacePtr> bool operator>=(_InterfacePtr p) throw() // Compare to pointers
#else
public: bool operator>=(_IUnknown& p) throw() { return operator>=(static_cast<IUnknown*>(&p)); }
public: bool operator>=(IUnknown* p) throw() #endif // !USE_OLD_COMPILER
{ return _CompareUnknown(p) >= 0; }
public: bool operator>=(Interface* p) throw() // Compare with other interface
{ return (_pInterface>=p) ? true : _CompareUnknown(p) >= 0; }
public: bool operator>=(CIP& p) throw() // Compares 2 CIPs
{ return operator>=(p._pInterface); }
public: bool operator>=(int null) throw() // For comparison with NULL
{ ASSERT(!null); return _pInterface >= NULL; }
#if USE_OLD_COMPILER
public: operator _IUnknown&() const throw() // Provided for casts between different pointer types.
{ return *reinterpret_cast<_IUnknown*>(static_cast<IUnknown*>(_pInterface)); } #endif // USE_OLD_COMPILER
public: void Release() throw() // Provides assertion verified, Release()ing of this interface.
{ ASSERT(_pInterface); if (_pInterface) { _pInterface->Release(); _pInterface = NULL; } }
public: void AddRef() throw() // Provides assertion verified AddRef()ing of this interface.
{ ASSERT(_pInterface); if (_pInterface) _pInterface->AddRef(); }
public: Interface* GetInterfacePtr() const throw() // Another way to get the interface pointer without casting.
{ return _pInterface; }
public: HRESULT CreateInstance( const CLSID& clsid, DWORD dwClsContext=CLSCTX_ALL) throw() // Loads an interface for the provided CLSID.
// Returns an HRESULT. Any previous interface is released.
{ _Release(); const HRESULT hr = CoCreateInstance(clsid, NULL, dwClsContext, GetIID(), reinterpret_cast<void**>(&_pInterface)); ASSERT(SUCCEEDED(hr)); return hr; }
public: HRESULT CreateInstance( LPOLESTR clsidString, DWORD dwClsContext=CLSCTX_ALL) throw() // Creates the class specified by clsidString. clsidString may
// contain a class id, or a prog id string.
{ // ISSUE-2002/03/29-JonN Should handle NULL case
ASSERT(clsidString); CLSID clsid; HRESULT hr; if (clsidString[0] == '{') hr = CLSIDFromString(clsidString, &clsid); else hr = CLSIDFromProgID(clsidString, &clsid); ASSERT(SUCCEEDED(hr)); if (FAILED(hr)) return hr; return CreateInstance(clsid, dwClsContext); }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
public: template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType*& p) throw() // Perfoms the QI for the specified IID and returns it in p.
// As with all QIs, the interface will be AddRef'd.
#else
public: HRESULT QueryInterface(const IID& iid, IUnknown*& p) throw() #endif // !USE_OLD_COMPILER
{ return _pInterface ? _pInterface->QueryInterface(iid, reinterpret_cast<void**>(&p)) : E_NOINTERFACE; }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
public: template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType** p) throw() // Perfoms the QI for the specified IID and returns it in p.
// As with all QIs, the interface will be AddRef'd.
#else
public: HRESULT QueryInterface(const IID& iid, IUnknown** p) throw() #endif // !USE_OLD_COMPILER
{ return QueryInterface(iid, *p); }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
public: template<typename _InterfaceType> _InterfaceType* QueryInterface(const IID& iid) throw() // Perfoms the QI for the specified IID and returns it.
// As with all QIs, the interface will be AddRef'd.
#else
public: IUnknown* QueryInterface(const IID& iid) throw() #endif // !USE_OLD_COMPILER
{ #if USE_OLD_COMPILER
typedef IUnknown _InterfaceType; #endif // USE_OLD_COMPILER
_InterfaceType* pInterface; QueryInterface(iid, pInterface); return pInterface; }
private: Interface* _pInterface; // The Interface.
private: void _Release() throw() // Releases only if the interface is not null.
// The interface is not set to NULL.
{ if (_pInterface) _pInterface->Release(); }
private: void _AddRef() throw() // AddRefs only if the interface is not NULL
{ if (_pInterface) _pInterface->AddRef(); }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
private: template<typename _InterfacePtr> HRESULT _QueryInterface(_InterfacePtr p) throw() // Performs a QI on pUnknown for the interface type returned
// for this class. The interface is stored. If pUnknown is
// NULL, or the QI fails, E_NOINTERFACE is returned and
// _pInterface is set to NULL.
#else
private: HRESULT _QueryInterface(IUnknown* p) throw() #endif // !USE_OLD_COMPILER
{ if (!p) // Can't QI NULL
{ operator=(static_cast<Interface*>(NULL)); return E_NOINTERFACE; }
// Query for this interface
Interface* pInterface; const HRESULT hr = p->QueryInterface(GetIID(), reinterpret_cast<void**>(&pInterface)); if (FAILED(hr)) { // If failed intialize interface to NULL and return HRESULT.
Attach(NULL); return hr; }
// Save the interface without AddRef()ing.
Attach(pInterface); return hr; }
#if !USE_OLD_COMPILER //REVIEW: remove after v5
private: template<typename _InterfacePtr> int _CompareUnknown(_InterfacePtr& p) throw() // Compares the provided pointer with this by obtaining IUnknown interfaces
// for each pointer and then returning the difference.
#else
private: int _CompareUnknown(IUnknown* p) throw() #endif // !USE_OLD_COMPILER
{ IUnknown* pu1; if (_pInterface) { const HRESULT hr = QueryInterface(IID_IUnknown, pu1); ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE); if (pu1) pu1->Release(); } else pu1=NULL;
IUnknown* pu2; if (p) { const HRESULT hr = p->QueryInterface(IID_IUnknown, reinterpret_cast<void**>(&pu2)); ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE); if (pu2) pu2->Release(); } else pu2 = NULL; return pu1 - pu2; } }; // class CIP
// Reverse comparison operators for CIP
template<typename _Interface> bool operator==(int null, CIP<_Interface>& p) { ASSERT(!null); return p == NULL; }
template<typename _Interface, typename _InterfacePtr> bool operator==(_Interface* i, CIP<_InterfacePtr>& p) { return p == i; }
template<typename _Interface> bool operator!=(int null, CIP<_Interface>& p) { ASSERT(!null); return p != NULL; }
template<typename _Interface, typename _InterfacePtr> bool operator!=(_Interface* i, CIP<_InterfacePtr>& p) { return p != i; }
template<typename _Interface> bool operator<(int null, CIP<_Interface>& p) { ASSERT(!null); return p < NULL; }
template<typename _Interface, typename _InterfacePtr> bool operator<(_Interface* i, CIP<_InterfacePtr>& p) { return p < i; }
template<typename _Interface> bool operator>(int null, CIP<_Interface>& p) { ASSERT(!null); return p > NULL; }
template<typename _Interface, typename _InterfacePtr> bool operator>(_Interface* i, CIP<_InterfacePtr>& p) { return p > i; }
template<typename _Interface> bool operator<=(int null, CIP<_Interface>& p) { ASSERT(!null); return p <= NULL; }
template<typename _Interface, typename _InterfacePtr> bool operator<=(_Interface* i, CIP<_InterfacePtr>& p) { return p <= i; }
template<typename _Interface> bool operator>=(int null, CIP<_Interface>& p) { ASSERT(!null); return p >= NULL; }
template<typename _Interface, typename _InterfacePtr> bool operator>=(_Interface* i, CIP<_InterfacePtr>& p) { return p >= i; }
#define DEFINE_CIP(x)\
typedef CIID<x, &IID_##x> x##IID;\ typedef CIP<x##IID> x##CIP;
#define DECLARE_CIP(x) DEFINE_CIP(x) x##CIP
DEFINE_CIP(IUnknown);
#if USE_OLD_COMPILER
#if USE_INTERMEDIATE_COMPILER
template<> #endif
class CIP<IUnknownIID> { private: #if USE_OLD_COMPILER
// Unique type used to provide for operations between different pointer
// types.
class _IUnknown: public IUnknown {}; #endif // USE_OLD_COMPILER
public: // Declare interface type so that the type may be available outside
// the scope of this template.
typedef IUnknownIID ThisCIID; typedef IUnknown Interface;
// When the compiler supports references in template params,
// _CLSID will be changed to a reference. To avoid conversion
// difficulties this function should be used to obtain the
// CLSID.
static const IID& GetIID() throw() { return ThisCIID::GetIID(); }
// Construct empty in preperation for assignment.
CIP() throw() : _pInterface(NULL) { }
// This constructor is provided to allow NULL assignment. It will assert
// if any value other than null is assigned to the object.
CIP(int null) throw() : _pInterface(NULL) { ASSERT(!null); }
CIP(_IUnknown& p) throw() : _pInterface(NULL) { if (&p) { const HRESULT hr=_QueryInterface(&p); ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE); } else _pInterface=NULL; }
// Copy the pointer and AddRef().
CIP(const CIP& cp) throw() : _pInterface(cp._pInterface) { _AddRef(); }
// Saves the interface
CIP(Interface* pInterface) throw() : _pInterface(pInterface) { _AddRef(); }
// Copies the pointer. If bAddRef is TRUE, the interface will
// be AddRef()ed.
CIP(Interface* pInterface, bool bAddRef) throw() : _pInterface(pInterface) { if (bAddRef) { ASSERT(!pInterface); _AddRef(); } }
// Calls CoCreateClass with the provided CLSID.
CIP(const CLSID& clsid, DWORD dwClsContext = CLSCTX_ALL) explicit throw() : _pInterface(NULL) { const HRESULT hr = CreateInstance(clsid, dwClsContext); ASSERT(SUCCEEDED(hr)); }
// Calls CoCreateClass with the provided CLSID retrieved from
// the string.
CIP(LPOLESTR str, DWORD dwClsContext = CLSCTX_ALL) explicit throw() : _pInterface(NULL) { const HRESULT hr = CreateInstance(str, dwClsContext); ASSERT(SUCCEEDED(hr)); }
CIP& operator=(_IUnknown& p) throw() { return operator=(static_cast<IUnknown*>(&p)); }
// Saves the interface.
CIP& operator=(Interface* pInterface) throw() { if (_pInterface != pInterface) { Interface* pOldInterface = _pInterface; _pInterface = pInterface; _AddRef(); if (pOldInterface) pOldInterface->Release(); } return *this; }
// Copies and AddRef()'s the interface.
CIP& operator=(const CIP& cp) throw() { return operator=(cp._pInterface); }
// This operator is provided to permit the assignment of NULL to the class.
// It will assert if any value other than NULL is assigned to it.
CIP& operator=(int null) throw() { ASSERT(!null); return operator=(reinterpret_cast<Interface*>(NULL)); }
// If we still have an interface then Release() it. The interface
// may be NULL if Detach() has previosly been called, or if it was
// never set.
~CIP() throw() { _Release(); }
// Saves/sets the interface without AddRef()ing. This call
// will release any previously aquired interface.
void Attach(Interface* pInterface) throw() { _Release(); _pInterface = pInterface; }
// Saves/sets the interface only AddRef()ing if bAddRef is TRUE.
// This call will release any previously aquired interface.
void Attach(Interface* pInterface, bool bAddRef) throw() { _Release(); _pInterface = pInterface; if (bAddRef) { ASSERT(pInterface); if (pInterface) pInterface->AddRef(); } }
// Simply NULL the interface pointer so that it isn't Released()'ed.
IUnknown* Detach() throw() { ASSERT(_pInterface); IUnknown* const old = _pInterface; _pInterface = NULL; return old; }
// Return the interface. This value may be NULL
operator Interface*() const throw() { return _pInterface; }
// Queries for the unknown and return it
// Provides minimal level assertion before use.
operator Interface&() const throw() { ASSERT(_pInterface); return *_pInterface; }
// Allows an instance of this class to act as though it were the
// actual interface. Also provides minimal assertion verification.
Interface& operator*() const throw() { ASSERT(_pInterface); return *_pInterface; }
// Returns the address of the interface pointer contained in this
// class. This is useful when using the COM/OLE interfaces to create
// this interface.
Interface** operator&() throw() { _Release(); _pInterface = NULL; return &_pInterface; }
// Allows this class to be used as the interface itself.
// Also provides simple assertion verification.
Interface* operator->() const throw() { ASSERT(_pInterface); return _pInterface; }
// This operator is provided so that simple boolean expressions will
// work. For example: "if (p) ...".
// Returns TRUE if the pointer is not NULL.
operator bool() const throw() { return _pInterface; }
// Returns TRUE if the interface is NULL.
// This operator will be removed when support for type bool
// is added to the compiler.
bool operator!() throw() { return !_pInterface; }
bool operator==(_IUnknown& p) throw() { return operator==(static_cast<IUnknown*>(&p)); }
// Compare with other interface
bool operator==(Interface* p) throw() { return (_pInterface==p)?true:!_CompareUnknown(p); }
// Compares 2 CIPs
bool operator==(CIP& p) throw() { return operator==(p._pInterface); }
// For comparison to NULL
bool operator==(int null) throw() { ASSERT(!null); return !_pInterface; }
bool operator!=(_IUnknown& p) throw() { return operator!=(static_cast<IUnknown*>(&p)); }
// Compare with other interface
bool operator!=(Interface* p) throw() { return (_pInterface!=p)?true:_CompareUnknown(p); }
// Compares 2 CIPs
bool operator!=(CIP& p) throw() { return operator!=(p._pInterface); }
// For comparison to NULL
bool operator!=(int null) throw() { ASSERT(!null); return _pInterface; }
bool operator<(_IUnknown& p) throw() { return operator<(static_cast<IUnknown*>(&p)); }
// Compare with other interface
bool operator<(Interface* p) throw() { return (_pInterface<p)?true:_CompareUnknown(p)<0; }
// Compares 2 CIPs
bool operator<(CIP& p) throw() { return operator<(p._pInterface); }
// For comparison with NULL
bool operator<(int null) throw() { ASSERT(!null); return _pInterface<NULL; }
bool operator>(_IUnknown& p) throw() { return operator>(static_cast<IUnknown*>(&p)); }
// Compare with other interface
bool operator>(Interface* p) throw() { return (_pInterface>p)?true:_CompareUnknown(p)>0; }
// Compares 2 CIPs
bool operator>(CIP& p) throw() { return operator>(p._pInterface); }
// For comparison with NULL
bool operator>(int null) throw() { ASSERT(!null); return _pInterface>NULL; }
bool operator<=(_IUnknown& p) throw() { return operator<=(static_cast<IUnknown*>(&p)); }
// Compare with other interface
bool operator<=(Interface* p) throw() { return (_pInterface<=p)?true:_CompareUnknown(p)<=0; }
// Compares 2 CIPs
bool operator<=(CIP& p) throw() { return operator<=(p._pInterface); }
// For comparison with NULL
bool operator<=(int null) throw() { ASSERT(!null); return _pInterface<=NULL; }
bool operator>=(_IUnknown& p) throw() { return operator>=(static_cast<IUnknown*>(&p)); }
// Compare with other interface
bool operator>=(Interface* p) throw() { return (_pInterface>=p)?true:_CompareUnknown(p)>=0; }
// Compares 2 CIPs
bool operator>=(CIP& p) throw() { return operator>=(p._pInterface); }
// For comparison with NULL
bool operator>=(int null) throw() { ASSERT(!null); return _pInterface>=NULL; }
// Provided for casts between different pointer types.
operator _IUnknown&() const throw() { return *reinterpret_cast<_IUnknown*>(static_cast<IUnknown*>(_pInterface)); }
// Provides assertion verified, Release()ing of this interface.
void Release() throw() { ASSERT(_pInterface); if (_pInterface) { _pInterface->Release(); _pInterface = NULL; } }
// Provides assertion verified AddRef()ing of this interface.
void AddRef() throw() { ASSERT(_pInterface); if (_pInterface) _pInterface->AddRef(); }
// Another way to get the interface pointer without casting.
Interface* GetInterfacePtr() const throw() { return _pInterface; }
// Loads an interface for the provided CLSID.
// Returns an HRESULT. Any previous interface is released.
HRESULT CreateInstance( const CLSID& clsid, DWORD dwClsContext=CLSCTX_ALL) throw() { _Release(); const HRESULT hr = CoCreateInstance(clsid, NULL, dwClsContext, GetIID(), reinterpret_cast<void**>(&_pInterface)); ASSERT(SUCCEEDED(hr)); return hr; }
// Creates the class specified by clsidString. clsidString may
// contain a class id, or a prog id string.
HRESULT CreateInstance( LPOLESTR clsidString, DWORD dwClsContext=CLSCTX_ALL) throw() { // ISSUE-2002/03/29-JonN Should handle NULL case
ASSERT(clsidString); CLSID clsid; HRESULT hr; if (clsidString[0] == '{') hr = CLSIDFromString(clsidString, &clsid); else hr = CLSIDFromProgID(clsidString, &clsid); ASSERT(SUCCEEDED(hr)); if (FAILED(hr)) return hr; return CreateInstance(clsid, dwClsContext); }
HRESULT QueryInterface(const IID& iid, IUnknown*& p) throw() { return _pInterface ? _pInterface->QueryInterface(iid, reinterpret_cast<void**>(&p)) : E_NOINTERFACE; }
HRESULT QueryInterface(const IID& iid, IUnknown** p) throw() { return QueryInterface(iid, *p); }
// Perfoms the QI for the specified IID and returns it.
// As with all QIs, the interface will be AddRef'd.
IUnknown* QueryInterface(const IID& iid) throw() { typedef IUnknown _InterfaceType; _InterfaceType* pInterface; QueryInterface(iid, pInterface); return pInterface; }
private: // The Interface.
Interface* _pInterface;
// Releases only if the interface is not null.
// The interface is not set to NULL.
void _Release() throw() { if (_pInterface) _pInterface->Release(); }
// AddRefs only if the interface is not NULL
void _AddRef() throw() { if (_pInterface) _pInterface->AddRef(); }
// Performs a QI on pUnknown for the interface type returned
// for this class. The interface is stored. If pUnknown is
// NULL, or the QI fails, E_NOINTERFACE is returned and
// _pInterface is set to NULL.
HRESULT _QueryInterface(IUnknown* p) throw() { if (!p) // Can't QI NULL
{ operator=(static_cast<Interface*>(NULL)); return E_NOINTERFACE; }
// Query for this interface
Interface* pInterface; const HRESULT hr = p->QueryInterface(GetIID(), reinterpret_cast<void**>(&pInterface)); if (FAILED(hr)) { // If failed intialize interface to NULL and return HRESULT.
Attach(NULL); return hr; }
// Save the interface without AddRef()ing.
Attach(pInterface); return hr; }
// Compares the provided pointer with this by obtaining IUnknown interfaces
// for each pointer and then returning the difference.
int _CompareUnknown(IUnknown* p) throw() { IUnknown* pu1; if (_pInterface) { const HRESULT hr=QueryInterface(IID_IUnknown, pu1); ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE); if (pu1) pu1->Release(); } else pu1=NULL;
IUnknown* pu2; if (p) { const HRESULT hr=p->QueryInterface(IID_IUnknown, reinterpret_cast<void**>(&pu2)); ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE); if (pu2) pu2->Release(); } else pu2=NULL; return pu1-pu2; } }; // class CIP
#endif // USE_OLD_COMPILER
#endif // _MSC_VER < 1100
#endif // COMPTR_H
|