From 23da585729242bc135e7a6da0dc5bf699e6c9b54 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 19 Apr 2015 21:12:24 +0000 Subject: - all strings operations were rewritten using CMString instead of ugly self-made buffers; - CComPtr<> introduced to simplify COM calls processing; - version bump. git-svn-id: http://svn.miranda-ng.org/main/trunk@12946 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- include/msapi/comptr.h | 277 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 include/msapi/comptr.h (limited to 'include/msapi/comptr.h') diff --git a/include/msapi/comptr.h b/include/msapi/comptr.h new file mode 100644 index 0000000000..ba8e54ffc1 --- /dev/null +++ b/include/msapi/comptr.h @@ -0,0 +1,277 @@ +// This is a part of the Active Template Library. +// Copyright (C) Microsoft Corporation +// All rights reserved. + +#ifndef __ATLCOMCLI_H__ +#define __ATLCOMCLI_H__ + +#pragma once + +#include +#include +#include + +#pragma warning (push) +#pragma warning (disable: 4127) // conditional expression constant +#pragma warning (disable: 4571) //catch(...) blocks compiled with /EHs do NOT catch or re-throw Structured Exceptions + +template +class _NoAddRefReleaseOnCComPtr : + public T +{ +private: + STDMETHOD_(ULONG, AddRef)() = 0; + STDMETHOD_(ULONG, Release)() = 0; +}; + +template +class CComPtrBase +{ +protected: + CComPtrBase() throw() + { + p = NULL; + } + CComPtrBase(_Inout_opt_ T* lp) throw() + { + p = lp; + if (p != NULL) + p->AddRef(); + } +public: + typedef T _PtrClass; + ~CComPtrBase() throw() + { + if (p) + p->Release(); + } + operator T*() const throw() + { + return p; + } + T& operator*() const + { + return *p; + } + T** operator&() throw() + { + return &p; + } + _NoAddRefReleaseOnCComPtr* operator->() const throw() + { + return (_NoAddRefReleaseOnCComPtr*)p; + } + bool operator!() const throw() + { + return (p == NULL); + } + bool operator<(_In_opt_ T* pT) const throw() + { + return p < pT; + } + bool operator!=(_In_opt_ T* pT) const + { + return !operator==(pT); + } + bool operator==(_In_opt_ T* pT) const throw() + { + return p == pT; + } + + // Release the interface and set to NULL + void Release() throw() + { + T* pTemp = p; + if (pTemp) + { + p = NULL; + pTemp->Release(); + } + } + // Compare two objects for equivalence + bool IsEqualObject(_Inout_opt_ IUnknown* pOther) throw() + { + 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 punk1; + CComPtr punk2; + p->QueryInterface(__uuidof(IUnknown), (void**)&punk1); + pOther->QueryInterface(__uuidof(IUnknown), (void**)&punk2); + return punk1 == punk2; + } + // Attach to an existing interface (does not AddRef) + void Attach(_In_opt_ T* p2) throw() + { + if (p) + p->Release(); + p = p2; + } + // Detach the interface (does not Release) + T* Detach() throw() + { + T* pt = p; + p = NULL; + return pt; + } + _Check_return_ HRESULT CopyTo(_Deref_out_opt_ T** ppT) throw() + { + ASSERT(ppT != NULL); + if (ppT == NULL) + return E_POINTER; + *ppT = p; + if (p) + p->AddRef(); + return S_OK; + } + _Check_return_ HRESULT SetSite(_Inout_opt_ IUnknown* punkParent) throw() + { + return AtlSetChildSite(p, punkParent); + } + _Check_return_ HRESULT Advise( + _Inout_ IUnknown* pUnk, + _In_ const IID& iid, + _Out_ LPDWORD pdw) throw() + { + return AtlAdvise(p, pUnk, iid, pdw); + } + _Check_return_ HRESULT CoCreateInstance( + _In_ REFCLSID rclsid, + _Inout_opt_ LPUNKNOWN pUnkOuter = NULL, + _In_ DWORD dwClsContext = CLSCTX_ALL) throw() + { + return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p); + } + _Check_return_ HRESULT CoCreateInstance( + _In_z_ LPCOLESTR szProgID, + _Inout_opt_ LPUNKNOWN pUnkOuter = NULL, + _In_ DWORD dwClsContext = CLSCTX_ALL) throw() + { + CLSID clsid; + HRESULT hr = CLSIDFromProgID(szProgID, &clsid); + if (SUCCEEDED(hr)) + hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p); + return hr; + } + template + _Check_return_ HRESULT QueryInterface(_Deref_out_ Q** pp) const throw() + { + return p->QueryInterface(__uuidof(Q), (void**)pp); + } + T* p; +}; + +template +class CComPtr : + public CComPtrBase +{ +public: + CComPtr() throw() + { + } + CComPtr(_Inout_opt_ T* lp) throw() : + CComPtrBase(lp) + { + } + CComPtr(_Inout_ const CComPtr& lp) throw() : + CComPtrBase(lp.p) + { + } + T* operator=(_Inout_opt_ T* lp) throw() + { + if(*this!=lp) + { + return static_cast(AtlComPtrAssign((IUnknown**)&p, lp)); + } + return *this; + } + template + T* operator=(_Inout_ const CComPtr& lp) throw() + { + if( !IsEqualObject(lp) ) + { + return static_cast(AtlComQIPtrAssign((IUnknown**)&p, lp, __uuidof(T))); + } + return *this; + } + T* operator=(_Inout_ const CComPtr& lp) throw() + { + if(*this!=lp) + { + return static_cast(AtlComPtrAssign((IUnknown**)&p, lp)); + } + return *this; + } + CComPtr(_Inout_ CComPtr&& lp) throw() : + CComPtrBase() + { + p = lp.p; + lp.p = NULL; + } + T* operator=(_Inout_ CComPtr&& lp) throw() + { + if (*this != lp) + { + if (p != NULL) + p->Release(); + + p = lp.p; + lp.p = NULL; + } + return *this; + } +}; + +template +class CComQIPtr : + public CComPtr +{ +public: + CComQIPtr() throw() + { + } + CComQIPtr(_Inout_opt_ T* lp) throw() : + CComPtr(lp) + { + } + CComQIPtr(_Inout_ const CComQIPtr& lp) throw() : + CComPtr(lp.p) + { + } + CComQIPtr(_Inout_opt_ IUnknown* lp) throw() + { + if (lp != NULL) + lp->QueryInterface(*piid, (void **)&p); + } + T* operator=(_Inout_opt_ T* lp) throw() + { + if(*this!=lp) + { + return static_cast(AtlComPtrAssign((IUnknown**)&p, lp)); + } + return *this; + } + T* operator=(_Inout_ const CComQIPtr& lp) throw() + { + if(*this!=lp) + { + return static_cast(AtlComPtrAssign((IUnknown**)&p, lp.p)); + } + return *this; + } + T* operator=(_Inout_opt_ IUnknown* lp) throw() + { + if(*this!=lp) + { + return static_cast(AtlComQIPtrAssign((IUnknown**)&p, lp, *piid)); + } + return *this; + } +}; + +#pragma warning (pop) + +#endif // __ATLCOMCLI_H__ -- cgit v1.2.3