template <class T> class CComPtr { public: typedef T _PtrClass; CComPtr() { p=NULL; } CComPtr(T* lp) { if ((p = lp) != NULL) p->AddRef(); } CComPtr(const CComPtr<T>& lp) { if ((p = lp.p) != NULL) p->AddRef(); } ~CComPtr() { if (p) p->Release(); } void Release() { IUnknown* pTemp = p; if (pTemp) { p = NULL; pTemp->Release(); } } operator T*() const { return (T*)p; } T& operator*() const { ATLASSERT(p!=NULL); return *p; } //The assert on operator& usually indicates a bug. If this is really //what is needed, however, take the address of the p member explicitly. T** operator&() { ATLASSERT(p==NULL); return &p; } _NoAddRefReleaseOnCComPtr<T>* operator->() const { ATLASSERT(p!=NULL); return (_NoAddRefReleaseOnCComPtr<T>*)p; } T* operator=(T* lp) { return (T*)AtlComPtrAssign((IUnknown**)&p, lp); } T* operator=(const CComPtr<T>& lp) { return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p); } bool operator!() const { return (p == NULL); } bool operator<(T* pT) const { return p < pT; } bool operator==(T* pT) const { return p == pT; } // Compare two objects for equivalence bool IsEqualObject(IUnknown* pOther) { if (p == NULL && pOther == NULL) return true; // They are both NULL objects if (p == NULL || pOther == NULL) return false; // One is NULL the other is not CComPtr<IUnknown> punk1; CComPtr<IUnknown> punk2; p->QueryInterface(IID_IUnknown, (void**)&punk1); pOther->QueryInterface(IID_IUnknown, (void**)&punk2); return punk1 == punk2; } void Attach(T* p2) { if (p) p->Release(); p = p2; } T* Detach() { T* pt = p; p = NULL; return pt; } HRESULT CopyTo(T** ppT) { ATLASSERT(ppT != NULL); if (ppT == NULL) return E_POINTER; *ppT = p; if (p) p->AddRef(); return S_OK; } HRESULT SetSite(IUnknown* punkParent) { return AtlSetChildSite(p, punkParent); } HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw) { return AtlAdvise(p, pUnk, iid, pdw); } HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) { ATLASSERT(p == NULL); return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p); } HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) { CLSID clsid; HRESULT hr = CLSIDFromProgID(szProgID, &clsid); ATLASSERT(p == NULL); if (SUCCEEDED(hr)) hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p); return hr; } template <class Q> HRESULT QueryInterface(Q** pp) const { ATLASSERT(pp != NULL && *pp == NULL); return p->QueryInterface(__uuidof(Q), (void**)pp); } T* p; };