1 // MyCom.h 2 3 #ifndef __MYCOM_H 4 #define __MYCOM_H 5 6 #include "MyWindows.h" 7 8 #ifndef RINOK 9 #define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; } 10 #endif 11 12 template <class T> 13 class CMyComPtr 14 { 15 T* _p; 16 public: 17 // typedef T _PtrClass; 18 CMyComPtr() { _p = NULL;} 19 CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); } 20 CMyComPtr(const CMyComPtr<T>& lp) 21 { 22 if ((_p = lp._p) != NULL) 23 _p->AddRef(); 24 } 25 ~CMyComPtr() { if (_p) _p->Release(); } 26 void Release() { if (_p) { _p->Release(); _p = NULL; } } 27 operator T*() const { return (T*)_p; } 28 // T& operator*() const { return *_p; } 29 T** operator&() { return &_p; } 30 T* operator->() const { return _p; } 31 T* operator=(T* p) 32 { 33 if (p != 0) 34 p->AddRef(); 35 if (_p) 36 _p->Release(); 37 _p = p; 38 return p; 39 } 40 T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); } 41 bool operator!() const { return (_p == NULL); } 42 // bool operator==(T* pT) const { return _p == pT; } 43 // Compare two objects for equivalence 44 void Attach(T* p2) 45 { 46 Release(); 47 _p = p2; 48 } 49 T* Detach() 50 { 51 T* pt = _p; 52 _p = NULL; 53 return pt; 54 } 55 #ifdef _WIN32 56 HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) 57 { 58 return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p); 59 } 60 #endif 61 /* 62 HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) 63 { 64 CLSID clsid; 65 HRESULT hr = CLSIDFromProgID(szProgID, &clsid); 66 ATLASSERT(_p == NULL); 67 if (SUCCEEDED(hr)) 68 hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p); 69 return hr; 70 } 71 */ 72 template <class Q> 73 HRESULT QueryInterface(REFGUID iid, Q** pp) const 74 { 75 return _p->QueryInterface(iid, (void**)pp); 76 } 77 }; 78 79 ////////////////////////////////////////////////////////// 80 81 inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr) 82 { 83 *bstr = ::SysAllocString(src); 84 return (*bstr != 0) ? S_OK : E_OUTOFMEMORY; 85 } 86 87 class CMyComBSTR 88 { 89 public: 90 BSTR m_str; 91 CMyComBSTR(): m_str(NULL) {} 92 CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); } 93 // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); } 94 // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); } 95 CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); } 96 /* 97 CMyComBSTR(REFGUID src) 98 { 99 LPOLESTR szGuid; 100 StringFromCLSID(src, &szGuid); 101 m_str = ::SysAllocString(szGuid); 102 CoTaskMemFree(szGuid); 103 } 104 */ 105 ~CMyComBSTR() { ::SysFreeString(m_str); } 106 CMyComBSTR& operator=(const CMyComBSTR& src) 107 { 108 if (m_str != src.m_str) 109 { 110 if (m_str) 111 ::SysFreeString(m_str); 112 m_str = src.MyCopy(); 113 } 114 return *this; 115 } 116 CMyComBSTR& operator=(LPCOLESTR src) 117 { 118 ::SysFreeString(m_str); 119 m_str = ::SysAllocString(src); 120 return *this; 121 } 122 unsigned int Length() const { return ::SysStringLen(m_str); } 123 operator BSTR() const { return m_str; } 124 BSTR* operator&() { return &m_str; } 125 BSTR MyCopy() const 126 { 127 int byteLen = ::SysStringByteLen(m_str); 128 BSTR res = ::SysAllocStringByteLen(NULL, byteLen); 129 memcpy(res, m_str, byteLen); 130 return res; 131 } 132 /* 133 void Attach(BSTR src) { m_str = src; } 134 BSTR Detach() 135 { 136 BSTR s = m_str; 137 m_str = NULL; 138 return s; 139 } 140 */ 141 void Empty() 142 { 143 ::SysFreeString(m_str); 144 m_str = NULL; 145 } 146 bool operator!() const { return (m_str == NULL); } 147 }; 148 149 ////////////////////////////////////////////////////////// 150 151 class CMyUnknownImp 152 { 153 public: 154 ULONG __m_RefCount; 155 CMyUnknownImp(): __m_RefCount(0) {} 156 }; 157 158 #define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \ 159 (REFGUID iid, void **outObject) { 160 161 #define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \ 162 { *outObject = (void *)(i *)this; AddRef(); return S_OK; } 163 164 #define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \ 165 { *outObject = (void *)(IUnknown *)(i *)this; AddRef(); return S_OK; } 166 167 #define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \ 168 MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \ 169 MY_QUERYINTERFACE_ENTRY(i) 170 171 #define MY_QUERYINTERFACE_END return E_NOINTERFACE; } 172 173 #define MY_ADDREF_RELEASE \ 174 STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \ 175 STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \ 176 return __m_RefCount; delete this; return 0; } 177 178 #define MY_UNKNOWN_IMP_SPEC(i) \ 179 MY_QUERYINTERFACE_BEGIN \ 180 i \ 181 MY_QUERYINTERFACE_END \ 182 MY_ADDREF_RELEASE 183 184 185 #define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \ 186 MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \ 187 MY_QUERYINTERFACE_END \ 188 MY_ADDREF_RELEASE 189 190 #define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \ 191 MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \ 192 MY_QUERYINTERFACE_ENTRY(i) \ 193 ) 194 195 #define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \ 196 MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ 197 MY_QUERYINTERFACE_ENTRY(i1) \ 198 MY_QUERYINTERFACE_ENTRY(i2) \ 199 ) 200 201 #define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \ 202 MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ 203 MY_QUERYINTERFACE_ENTRY(i1) \ 204 MY_QUERYINTERFACE_ENTRY(i2) \ 205 MY_QUERYINTERFACE_ENTRY(i3) \ 206 ) 207 208 #define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \ 209 MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ 210 MY_QUERYINTERFACE_ENTRY(i1) \ 211 MY_QUERYINTERFACE_ENTRY(i2) \ 212 MY_QUERYINTERFACE_ENTRY(i3) \ 213 MY_QUERYINTERFACE_ENTRY(i4) \ 214 ) 215 216 #define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \ 217 MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ 218 MY_QUERYINTERFACE_ENTRY(i1) \ 219 MY_QUERYINTERFACE_ENTRY(i2) \ 220 MY_QUERYINTERFACE_ENTRY(i3) \ 221 MY_QUERYINTERFACE_ENTRY(i4) \ 222 MY_QUERYINTERFACE_ENTRY(i5) \ 223 ) 224 225 #endif 226