#ifndef __MYCOM_H
#define __MYCOM_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) {
if
((_p = p) != NULL) p->AddRef(); }
CMyComPtr(
const
CMyComPtr<T>& lp)
{
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&() {
return
&_p; }
T* operator->()
const
{
return
_p; }
T* operator=(T* p)
{
if
(p != 0)
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); }
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
template
<
class
Q>
HRESULT
QueryInterface(REFGUID iid, Q** pp)
const
{
return
_p->QueryInterface(iid, (
void
**)pp);
}
};
inline
HRESULT
StringToBstr(LPCOLESTR src, BSTR *bstr)
{
*bstr = ::SysAllocString(src);
return
(*bstr != 0) ? S_OK : E_OUTOFMEMORY;
}
class
CMyComBSTR
{
public
:
BSTR m_str;
CMyComBSTR(): m_str(NULL) {}
CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); }
CMyComBSTR(
const
CMyComBSTR& src) { m_str = src.MyCopy(); }
~CMyComBSTR() { ::SysFreeString(m_str); }
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
int
Length()
const
{
return
::SysStringLen(m_str); }
operator BSTR()
const
{
return
m_str; }
BSTR* operator&() {
return
&m_str; }
BSTR MyCopy()
const
{
int
byteLen = ::SysStringByteLen(m_str);
BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
memcpy
(res, m_str, byteLen);
return
res;
}
void
Empty()
{
::SysFreeString(m_str);
m_str = NULL;
}
bool
operator!()
const
{
return
(m_str == NULL); }
};
class
CMyUnknownImp
{
public
:
ULONG
__m_RefCount;
CMyUnknownImp(): __m_RefCount(0) {}
};
#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
(REFGUID iid,
void
**outObject) {
#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
{ *outObject = (
void
*)(i *)
this
; AddRef();
return
S_OK; }
#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \
{ *outObject = (
void
*)(IUnknown *)(i *)
this
; AddRef();
return
S_OK; }
#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
MY_QUERYINTERFACE_ENTRY(i)
#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
#define MY_ADDREF_RELEASE \
STDMETHOD_(
ULONG
, AddRef)() {
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) \
)
#endif