Source code

Revision control

Copy as Markdown

Other Tools

// MyCom.h↩
#ifndef __MY_COM_H↩
#define __MY_COM_H↩
#include "MyWindows.h"
#ifndef RINOK↩
#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; }↩
#endif
template <class T>↩
class CMyComPtr↩
{↩
T* _p;↩
public:↩
CMyComPtr(): _p(NULL) {}↩
CMyComPtr(T* p) throw() { if ((_p = p) != NULL) p->AddRef(); }↩
CMyComPtr(const CMyComPtr<T>& lp) throw() { if ((_p = lp._p) != NULL) _p->AddRef(); }↩
~CMyComPtr() { if (_p) _p->Release(); }↩
void Release() { if (_p) { _p->Release(); _p = NULL; } }↩
operator T*() const { return (T*)_p; }↩
// T& operator*() const { return *_p; }↩
T** operator&() { return &_p; }↩
T* operator->() const { return _p; }↩
T* operator=(T* p)↩
{↩
if (p)↩
p->AddRef();↩
if (_p)↩
_p->Release();↩
_p = p;↩
return p;↩
}↩
T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }↩
bool operator!() const { return (_p == NULL); }↩
// bool operator==(T* pT) const { return _p == pT; }↩
void Attach(T* p2)↩
{↩
Release();↩
_p = p2;↩
}↩
T* Detach()↩
{↩
T* pt = _p;↩
_p = NULL;↩
return pt;↩
}↩
#ifdef _WIN32↩
HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)↩
{↩
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);↩
}↩
#endif
/*↩
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(REFGUID iid, Q** pp) const throw()↩
{↩
return _p->QueryInterface(iid, (void**)pp);↩
}↩
};↩
//////////////////////////////////////////////////////////↩
inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr)↩
{↩
*bstr = ::SysAllocString(src);↩
return (*bstr) ? S_OK : E_OUTOFMEMORY;↩
}↩
class CMyComBSTR↩
{↩
BSTR m_str;↩
public:↩
CMyComBSTR(): m_str(NULL) {}↩
~CMyComBSTR() { ::SysFreeString(m_str); }↩
BSTR* operator&() { return &m_str; }↩
operator LPCOLESTR() const { return m_str; }↩
// operator bool() const { return m_str != NULL; }↩
// bool operator!() const { return m_str == NULL; }↩
private:↩
// operator BSTR() const { return m_str; }↩
CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); }↩
// CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }↩
// CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }↩
CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }↩
/*↩
CMyComBSTR(REFGUID src)↩
{↩
LPOLESTR szGuid;↩
StringFromCLSID(src, &szGuid);↩
m_str = ::SysAllocString(szGuid);↩
CoTaskMemFree(szGuid);↩
}↩
*/
CMyComBSTR& operator=(const CMyComBSTR& src)↩
{↩
if (m_str != src.m_str)↩
{↩
if (m_str)↩
::SysFreeString(m_str);↩
m_str = src.MyCopy();↩
}↩
return *this;↩
}↩
CMyComBSTR& operator=(LPCOLESTR src)↩
{↩
::SysFreeString(m_str);↩
m_str = ::SysAllocString(src);↩
return *this;↩
}↩
unsigned Len() const { return ::SysStringLen(m_str); }↩
BSTR MyCopy() const
{↩
// We don't support Byte BSTRs here↩
return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));↩
/*↩
UINT byteLen = ::SysStringByteLen(m_str);↩
BSTR res = ::SysAllocStringByteLen(NULL, byteLen);↩
if (res && byteLen != 0 && m_str)↩
memcpy(res, m_str, byteLen);↩
return res;↩
*/
}↩
/*↩
void Attach(BSTR src) { m_str = src; }↩
BSTR Detach()↩
{↩
BSTR s = m_str;↩
m_str = NULL;↩
return s;↩
}↩
*/
void Empty()↩
{↩
::SysFreeString(m_str);↩
m_str = NULL;↩
}↩
};↩
/*↩
If CMyUnknownImp doesn't use virtual destructor, the code size is smaller.↩
But if some class_1 derived from CMyUnknownImp↩
uses MY_ADDREF_RELEASE and IUnknown::Release()↩
and some another class_2 is derived from class_1,↩
then class_1 must use virtual destructor:↩
virtual ~class_1();↩
In that case, class_1::Release() calls correct destructor of class_2.↩
Also you can use virtual ~CMyUnknownImp(), if you want to disable warning↩
"class has virtual functions, but destructor is not virtual".↩
*/
class CMyUnknownImp↩
{↩
public:↩
ULONG __m_RefCount;↩
CMyUnknownImp(): __m_RefCount(0) {}↩
// virtual↩
~CMyUnknownImp() {}↩
};↩
#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \↩
(REFGUID iid, void **outObject) throw() { *outObject = NULL;↩
#define MY_QUERYINTERFACE_ENTRY(i) else if (iid == IID_ ## i) \↩
{ *outObject = (void *)(i *)this; }↩
#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \↩
{ *outObject = (void *)(IUnknown *)(i *)this; }↩
#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \↩
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \↩
MY_QUERYINTERFACE_ENTRY(i)↩
#define MY_QUERYINTERFACE_END else return E_NOINTERFACE; ++__m_RefCount; /* AddRef(); */ return S_OK; }↩
#define MY_ADDREF_RELEASE \↩
STDMETHOD_(ULONG, AddRef)() throw() { return ++__m_RefCount; } \↩
STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \↩
return __m_RefCount; delete this; return 0; }↩
#define MY_UNKNOWN_IMP_SPEC(i) \↩
MY_QUERYINTERFACE_BEGIN \↩
i \↩
MY_QUERYINTERFACE_END \↩
MY_ADDREF_RELEASE↩
#define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \↩
MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \↩
MY_QUERYINTERFACE_END \↩
MY_ADDREF_RELEASE↩
#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \↩
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \↩
MY_QUERYINTERFACE_ENTRY(i) \↩
)↩
#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \↩
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \↩
MY_QUERYINTERFACE_ENTRY(i1) \↩
MY_QUERYINTERFACE_ENTRY(i2) \↩
)↩
#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \↩
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \↩
MY_QUERYINTERFACE_ENTRY(i1) \↩
MY_QUERYINTERFACE_ENTRY(i2) \↩
MY_QUERYINTERFACE_ENTRY(i3) \↩
)↩
#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \↩
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \↩
MY_QUERYINTERFACE_ENTRY(i1) \↩
MY_QUERYINTERFACE_ENTRY(i2) \↩
MY_QUERYINTERFACE_ENTRY(i3) \↩
MY_QUERYINTERFACE_ENTRY(i4) \↩
)↩
#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \↩
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \↩
MY_QUERYINTERFACE_ENTRY(i1) \↩
MY_QUERYINTERFACE_ENTRY(i2) \↩
MY_QUERYINTERFACE_ENTRY(i3) \↩
MY_QUERYINTERFACE_ENTRY(i4) \↩
MY_QUERYINTERFACE_ENTRY(i5) \↩
)↩
#define MY_UNKNOWN_IMP6(i1, i2, i3, i4, i5, i6) MY_UNKNOWN_IMP_SPEC( \↩
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \↩
MY_QUERYINTERFACE_ENTRY(i1) \↩
MY_QUERYINTERFACE_ENTRY(i2) \↩
MY_QUERYINTERFACE_ENTRY(i3) \↩
MY_QUERYINTERFACE_ENTRY(i4) \↩
MY_QUERYINTERFACE_ENTRY(i5) \↩
MY_QUERYINTERFACE_ENTRY(i6) \↩
)↩
#define MY_UNKNOWN_IMP7(i1, i2, i3, i4, i5, i6, i7) MY_UNKNOWN_IMP_SPEC( \↩
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \↩
MY_QUERYINTERFACE_ENTRY(i1) \↩
MY_QUERYINTERFACE_ENTRY(i2) \↩
MY_QUERYINTERFACE_ENTRY(i3) \↩
MY_QUERYINTERFACE_ENTRY(i4) \↩
MY_QUERYINTERFACE_ENTRY(i5) \↩
MY_QUERYINTERFACE_ENTRY(i6) \↩
MY_QUERYINTERFACE_ENTRY(i7) \↩
)↩
const HRESULT k_My_HRESULT_WritingWasCut = 0x20000010;↩
#endif