michael@0: // MyCom.h michael@0: michael@0: #ifndef __MYCOM_H michael@0: #define __MYCOM_H michael@0: michael@0: #include "MyWindows.h" michael@0: michael@0: #define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; } michael@0: michael@0: template michael@0: class CMyComPtr michael@0: { michael@0: T* _p; michael@0: public: michael@0: // typedef T _PtrClass; michael@0: CMyComPtr() { _p = NULL;} michael@0: CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); } michael@0: CMyComPtr(const CMyComPtr& lp) michael@0: { michael@0: if ((_p = lp._p) != NULL) michael@0: _p->AddRef(); michael@0: } michael@0: ~CMyComPtr() { if (_p) _p->Release(); } michael@0: void Release() { if (_p) { _p->Release(); _p = NULL; } } michael@0: operator T*() const { return (T*)_p; } michael@0: // T& operator*() const { return *_p; } michael@0: T** operator&() { return &_p; } michael@0: T* operator->() const { return _p; } michael@0: T* operator=(T* p) michael@0: { michael@0: if (p != 0) michael@0: p->AddRef(); michael@0: if (_p) michael@0: _p->Release(); michael@0: _p = p; michael@0: return p; michael@0: } michael@0: T* operator=(const CMyComPtr& lp) { return (*this = lp._p); } michael@0: bool operator!() const { return (_p == NULL); } michael@0: // bool operator==(T* pT) const { return _p == pT; } michael@0: // Compare two objects for equivalence michael@0: void Attach(T* p2) michael@0: { michael@0: Release(); michael@0: _p = p2; michael@0: } michael@0: T* Detach() michael@0: { michael@0: T* pt = _p; michael@0: _p = NULL; michael@0: return pt; michael@0: } michael@0: #ifdef _WIN32 michael@0: HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) michael@0: { michael@0: return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p); michael@0: } michael@0: #endif michael@0: /* michael@0: HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) michael@0: { michael@0: CLSID clsid; michael@0: HRESULT hr = CLSIDFromProgID(szProgID, &clsid); michael@0: ATLASSERT(_p == NULL); michael@0: if (SUCCEEDED(hr)) michael@0: hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p); michael@0: return hr; michael@0: } michael@0: */ michael@0: template michael@0: HRESULT QueryInterface(REFGUID iid, Q** pp) const michael@0: { michael@0: return _p->QueryInterface(iid, (void**)pp); michael@0: } michael@0: }; michael@0: michael@0: ////////////////////////////////////////////////////////// michael@0: michael@0: class CMyComBSTR michael@0: { michael@0: public: michael@0: BSTR m_str; michael@0: CMyComBSTR() { m_str = NULL; } michael@0: CMyComBSTR(LPCOLESTR pSrc) { m_str = ::SysAllocString(pSrc); } michael@0: // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); } michael@0: // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); } michael@0: CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); } michael@0: /* michael@0: CMyComBSTR(REFGUID src) michael@0: { michael@0: LPOLESTR szGuid; michael@0: StringFromCLSID(src, &szGuid); michael@0: m_str = ::SysAllocString(szGuid); michael@0: CoTaskMemFree(szGuid); michael@0: } michael@0: */ michael@0: ~CMyComBSTR() { ::SysFreeString(m_str); } michael@0: CMyComBSTR& operator=(const CMyComBSTR& src) michael@0: { michael@0: if (m_str != src.m_str) michael@0: { michael@0: if (m_str) michael@0: ::SysFreeString(m_str); michael@0: m_str = src.MyCopy(); michael@0: } michael@0: return *this; michael@0: } michael@0: CMyComBSTR& operator=(LPCOLESTR pSrc) michael@0: { michael@0: ::SysFreeString(m_str); michael@0: m_str = ::SysAllocString(pSrc); michael@0: return *this; michael@0: } michael@0: unsigned int Length() const { return ::SysStringLen(m_str); } michael@0: operator BSTR() const { return m_str; } michael@0: BSTR* operator&() { return &m_str; } michael@0: BSTR MyCopy() const michael@0: { michael@0: int byteLen = ::SysStringByteLen(m_str); michael@0: BSTR res = ::SysAllocStringByteLen(NULL, byteLen); michael@0: memmove(res, m_str, byteLen); michael@0: return res; michael@0: } michael@0: void Attach(BSTR src) { m_str = src; } michael@0: BSTR Detach() michael@0: { michael@0: BSTR s = m_str; michael@0: m_str = NULL; michael@0: return s; michael@0: } michael@0: void Empty() michael@0: { michael@0: ::SysFreeString(m_str); michael@0: m_str = NULL; michael@0: } michael@0: bool operator!() const { return (m_str == NULL); } michael@0: }; michael@0: michael@0: michael@0: ////////////////////////////////////////////////////////// michael@0: michael@0: class CMyUnknownImp michael@0: { michael@0: public: michael@0: ULONG __m_RefCount; michael@0: CMyUnknownImp(): __m_RefCount(0) {} michael@0: }; michael@0: michael@0: #define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \ michael@0: (REFGUID iid, void **outObject) { michael@0: michael@0: #define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \ michael@0: { *outObject = (void *)(i *)this; AddRef(); return S_OK; } michael@0: michael@0: #define MY_QUERYINTERFACE_END return E_NOINTERFACE; } michael@0: michael@0: #define MY_ADDREF_RELEASE \ michael@0: STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \ michael@0: STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \ michael@0: return __m_RefCount; delete this; return 0; } michael@0: michael@0: #define MY_UNKNOWN_IMP_SPEC(i) \ michael@0: MY_QUERYINTERFACE_BEGIN \ michael@0: i \ michael@0: MY_QUERYINTERFACE_END \ michael@0: MY_ADDREF_RELEASE michael@0: michael@0: michael@0: #define MY_UNKNOWN_IMP STDMETHOD(QueryInterface)(REFGUID, void **) { \ michael@0: MY_QUERYINTERFACE_END \ michael@0: MY_ADDREF_RELEASE michael@0: michael@0: #define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \ michael@0: MY_QUERYINTERFACE_ENTRY(i) \ michael@0: ) michael@0: michael@0: #define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \ michael@0: MY_QUERYINTERFACE_ENTRY(i1) \ michael@0: MY_QUERYINTERFACE_ENTRY(i2) \ michael@0: ) michael@0: michael@0: #define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \ michael@0: MY_QUERYINTERFACE_ENTRY(i1) \ michael@0: MY_QUERYINTERFACE_ENTRY(i2) \ michael@0: MY_QUERYINTERFACE_ENTRY(i3) \ michael@0: ) michael@0: michael@0: #define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \ michael@0: MY_QUERYINTERFACE_ENTRY(i1) \ michael@0: MY_QUERYINTERFACE_ENTRY(i2) \ michael@0: MY_QUERYINTERFACE_ENTRY(i3) \ michael@0: MY_QUERYINTERFACE_ENTRY(i4) \ michael@0: ) michael@0: michael@0: #define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \ michael@0: MY_QUERYINTERFACE_ENTRY(i1) \ michael@0: MY_QUERYINTERFACE_ENTRY(i2) \ michael@0: MY_QUERYINTERFACE_ENTRY(i3) \ michael@0: MY_QUERYINTERFACE_ENTRY(i4) \ michael@0: MY_QUERYINTERFACE_ENTRY(i5) \ michael@0: ) michael@0: michael@0: #endif