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