GME
13
|
00001 00002 #ifndef MGA_COMMONSMART_H 00003 #define MGA_COMMONSMART_H 00004 00005 #ifndef MGA_COMMONERROR_H 00006 #include "CommonError.h" 00007 #endif 00008 00009 #ifndef __ATLBASE_H__ 00010 #include <AtlBase.h> 00011 #endif 00012 00013 #include<string> 00014 00015 // --------------------------- CComObjPtr 00016 00017 // in containers we need the default "operator &", 00018 // so we don't use the built in ATL CComPtr class 00019 00020 template<class T> 00021 class CComObjPtr 00022 { 00023 public: 00024 CComObjPtr() { p = NULL; } 00025 CComObjPtr(T *q) { if ((p = q) != NULL) q->AddRef(); } 00026 CComObjPtr(const CComObjPtr<T> &q) { if((p = q.p) != NULL) p->AddRef(); } 00027 CComObjPtr(CComObjPtr<T>&& q) 00028 { 00029 p = q.p; 00030 q.p = NULL; 00031 } 00032 CComObjPtr& operator=(CComObjPtr<T>&& q) 00033 { 00034 if (p) 00035 p->Release(); 00036 p = q.p; 00037 q.p = NULL; 00038 return *this; 00039 } 00040 #ifdef _DEBUG 00041 ~CComObjPtr() { if(p) p->Release(); p = NULL; } 00042 #else 00043 ~CComObjPtr() { if(p) p->Release(); } 00044 #endif 00045 void Release() { if(p) { p->Release(); p = NULL; } } 00046 00047 operator T*() const { return p; } 00048 T& operator*() const { ASSERT( p != NULL ); return *p; } 00049 T* operator->() const { ASSERT( p != NULL ); return p; } 00050 T* operator=(T *q) { if(q) q->AddRef(); if(p) p->Release(); p = q; return q; } 00051 T* operator=(const CComObjPtr<T> &q) { return operator=(q.p); } 00052 bool operator==(T *q) const { return p == q; } 00053 bool operator!=(T *q) const { return p != q; } 00054 00055 T* Detach() { T* r = p; p = NULL; return r; } 00056 void Attach(T* q) { if(p) p->Release(); p = q; } 00057 00058 template<class Q> 00059 HRESULT QueryInterface(CComObjPtr<Q> &q) const 00060 { 00061 ASSERT( p != NULL && q == NULL ); 00062 return p->QueryInterface(__uuidof(Q), (void**)&q.p); 00063 } 00064 00065 HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) 00066 { 00067 ASSERT( p == NULL ); 00068 return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p); 00069 } 00070 00071 HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) 00072 { 00073 CLSID clsid; 00074 HRESULT hr = CLSIDFromProgID(szProgID, &clsid); 00075 ASSERT(p == NULL); 00076 if (SUCCEEDED(hr)) 00077 hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p); 00078 return hr; 00079 } 00080 00081 public: 00082 T *p; 00083 }; 00084 00085 // use these inline functions to pass CComObjPtr arguments to COM functions 00086 // like in role->get_Kind(PutOut(kind)) 00087 00088 template<class T> 00089 T **PutOut(CComObjPtr<T> &p) { ASSERT( p == NULL ); return &p.p; } 00090 00091 template<class T> 00092 T **PutInOut(CComObjPtr<T> &p) { return &p.p; } 00093 00094 // use these inline functions to transfer ownership to another COM pointer 00095 00096 template<class T, class Q> 00097 void MoveTo(CComObjPtr<T> &p, Q **q) 00098 { ASSERT( q != NULL ); if(*q) (*q)->Release(); *q = p.p; p.p = NULL; } 00099 00100 template<class T, class Q> 00101 void MoveTo(CComObjPtr<T> &p, CComObjPtr<Q> &q) { q.Attach(p.p); p.p = NULL; } 00102 00103 // use these inline functions to copy COM pointers 00104 00105 template<class T, class Q> 00106 void CopyTo(T *p, Q **q) 00107 { ASSERT( q != NULL ); if(p) p->AddRef(); if(*q) (*q)->Release(); *q = p; } 00108 00109 template<class T, class Q> 00110 void CopyTo(const CComObjPtr<T> &p, Q **q) 00111 { ASSERT( q != NULL ); if(p) p->AddRef(); if(*q) (*q)->Release(); *q = p; } 00112 00113 // global QueryInterface 00114 00115 template<class T> 00116 inline HRESULT QueryInterface(IUnknown *p, T **q) 00117 { ASSERT( p != NULL ); return p->QueryInterface(__uuidof(T), (void**)q); } 00118 00119 template<class T> 00120 inline HRESULT QueryInterface(IUnknown *p, CComObjPtr<T> &q) 00121 { ASSERT( p != NULL ); return p->QueryInterface(__uuidof(T), (void**)PutOut(q)); } 00122 00123 // note: T should not be derived from CComObject 00124 template<class T> 00125 inline void CreateComObject(CComObjPtr<T> &p) 00126 { 00127 CComObject<T> *q = NULL; 00128 COMTHROW( CComObject<T>::CreateInstance(&q) ); 00129 ASSERT( q != NULL ); 00130 00131 p = q; 00132 } 00133 00134 // note: T should not be derived from CComPartObject 00135 template<class T> 00136 inline void CreateComPartObject(LPUNKNOWN pUnkOuter, CComObjPtr<T> &p) 00137 { 00138 CComPartObject<T> *q = NULL; 00139 COMTHROW( CComPartObject<T>::CreateInstance(pUnkOuter, &q) ); 00140 ASSERT( q != NULL ); 00141 00142 p = q; 00143 } 00144 00145 // --------------------------- CComPtr 00146 00147 // note: T should not be derived from CComObject 00148 template<class T> 00149 inline void CreateComObject(CComPtr<T> &p) 00150 { 00151 CComObject<T> *q = NULL; 00152 COMTHROW( CComObject<T>::CreateInstance(&q) ); 00153 ASSERT( q != NULL ); 00154 00155 q->AddRef(); 00156 p.Attach(q); 00157 } 00158 00159 // --------------------------- CComBstrObj 00160 00161 class CComBstrObj 00162 { 00163 public: 00164 CComBstrObj() : p(NULL) { } 00165 explicit CComBstrObj(LPCOLESTR q) { p = SysAllocString(q); } 00166 CComBstrObj(const CComBstrObj &q) : p(NULL) { if(q.p) { p = SysAllocStringLen(q, q.Length()); } } 00167 CComBstrObj(CComBstrObj &&q) { p = q.p; q.p = NULL; } 00168 ~CComBstrObj() { if(p) SysFreeString(p); } 00169 00170 const CComBstrObj &operator=(const CComBstrObj &q) { if(p) SysFreeString(p); 00171 p = SysAllocStringLen(q, q.Length()); return *this; } 00172 CComBstrObj& operator=(CComBstrObj&& q) { 00173 if (p) SysFreeString(p); 00174 p = q.p; 00175 q.p = NULL; 00176 return *this; 00177 } 00178 operator BSTR() const { return p; } 00179 unsigned int Length() const { return p ? SysStringLen(p) : 0; } 00180 void Empty() { if( p ) { SysFreeString(p); p = NULL; } } 00181 00182 int Compare(BSTR q) const; 00183 bool operator==(BSTR q) const { return Compare(q) == 0; } 00184 bool operator!=(BSTR q) const { return Compare(q) != 0; } 00185 bool operator<(BSTR q) const { return Compare(q) < 0; } 00186 bool operator>(BSTR q) const { return Compare(q) > 0; } 00187 bool operator<=(BSTR q) const { return Compare(q) <= 0; } 00188 bool operator>=(BSTR q) const { return Compare(q) >= 0; } 00189 00190 BSTR Detach() { BSTR q = p; p = NULL; return q; } 00191 void Attach(BSTR q) { if(p) SysFreeString(p); p = q; } 00192 00193 public: 00194 BSTR p; 00195 }; 00196 00197 inline BSTR *PutOut(CComBstrObj &s) { ASSERT( s.p == NULL ); return &s.p; } 00198 inline BSTR *PutInOut(CComBstrObj &s) { return &s.p; } 00199 00200 // we use "BSTR" for [in], and "BSTR *" for [in, out] 00201 // we use "const CComBstrObj &" for [in] and "CComBstrObj &" for [in, out] 00202 00203 inline void CopyTo(BSTR p, BSTR *q) 00204 { 00205 ASSERT( q != NULL ); 00206 00207 if (*q) 00208 SysFreeString(*q); 00209 *q = SysAllocStringLen(p, SysStringLen(p)); 00210 if (*q == NULL && p != NULL) 00211 COMTHROW(E_OUTOFMEMORY); 00212 } 00213 00214 inline void CopyTo(const CComBstrObj &b, BSTR *q) { CopyTo(b.p, q); } 00215 inline void CopyTo(BSTR p, CComBstrObj &b) { CopyTo(p, &b.p); } 00216 00217 inline void MoveTo(BSTR *p, BSTR *q) 00218 { 00219 ASSERT( p != NULL ); 00220 ASSERT( q != NULL ); 00221 00222 if(*q) SysFreeString(*q); 00223 (*q) = (*p); (*p) = NULL; 00224 } 00225 00226 inline void MoveTo(CComBstrObj &b, BSTR *q) { MoveTo(&b.p, q); } 00227 inline void MoveTo(BSTR *p, CComBstrObj &b) { MoveTo(p, &b.p); } 00228 00229 // these THROW exceptions 00230 00231 void CopyTo(const char *p, int len, BSTR *b, UINT codepage=CP_ACP); 00232 00233 // if olelen is -1, then OLECHAR is NULL terminated and the charlen includes this NULL 00234 int GetCharLength(const OLECHAR *p, int olelen, UINT codepage=CP_ACP); 00235 00236 void CopyTo(const OLECHAR *p, int olelen, char *s, int charlen, UINT codepage=CP_ACP); 00237 00238 void CopyTo(const OLECHAR *p, GUID &guid); 00239 void CopyTo(const GUID &guid, BSTR *p); 00240 00241 // ------- inlines 00242 00243 inline void CopyTo(const char *p, int len, CComBstrObj &b) { CopyTo(p, len, &b.p); } 00244 inline int GetCharLength(BSTR p) { return GetCharLength(p, SysStringLen(p)); } 00245 inline void CopyTo(BSTR p, char *s, int charlen, UINT codepage=CP_ACP) { CopyTo(p, SysStringLen(p), s, charlen, codepage); } 00246 inline void CopyTo(const GUID &guid, CComBstrObj &b) { CopyTo(guid, &b.p); } 00247 00248 // --------------------------- CComBSTR 00249 00250 inline void CopyTo(const CComBSTR &b, BSTR *q) { CopyTo(b.m_str, q); } 00251 inline void CopyTo(BSTR p, CComBSTR &b) { CopyTo(p, &b.m_str); } 00252 00253 inline void MoveTo(CComBSTR &b, BSTR *q) { MoveTo(&b.m_str, q); } 00254 inline void MoveTo(BSTR *p, CComBSTR &b) { MoveTo(p, &b.m_str); } 00255 00256 // --------------------------- CComSafeArray 00257 00258 class CComSafeArray 00259 { 00260 public: 00261 CComSafeArray() { p = NULL; } 00262 ~CComSafeArray() { if( p ) SafeArrayDestroy(p); } 00263 operator SAFEARRAY*() { return p; } 00264 00265 public: 00266 SAFEARRAY *p; 00267 }; 00268 00269 inline SAFEARRAY **PutOut(CComSafeArray &a) { ASSERT( a.p == NULL ); return &a.p; } 00270 inline SAFEARRAY **PutInOut(CComSafeArray &a) { return &a.p; } 00271 00272 // we use "SAFEARRAY *" for [in], "SAFEARRAY **" for [out], and "SAFEARRAY *" for [in, out] 00273 // we use "const CComSafeArray &" for [in] and "CComSafeArray &" for [in, out] 00274 00275 // these THROW exceptions 00276 00277 void CopyTo(const CComBstrObj *start, const CComBstrObj *end, SAFEARRAY **p); 00278 void CopyTo(const unsigned char *start, const unsigned char *end, SAFEARRAY **p); 00279 void CopyTo(const long *start, const long *end, SAFEARRAY **p); 00280 void CopyTo(const GUID *start, const GUID *end, SAFEARRAY **p); 00281 00282 void MoveTo(CComBstrObj *start, CComBstrObj *end, SAFEARRAY **p); 00283 00284 long GetArrayLength(SAFEARRAY *p); 00285 00286 // not safe for multiple access 00287 void GetArrayStart(SAFEARRAY *p, CComBstrObj *&start); 00288 void GetArrayStart(SAFEARRAY *p, unsigned char *&start); 00289 void GetArrayStart(SAFEARRAY *p, long *&start); 00290 void GetArrayStart(SAFEARRAY *p, GUID *&start); 00291 00292 void CopyTo(SAFEARRAY *p, CComBstrObj *start, CComBstrObj *end); 00293 void CopyTo(SAFEARRAY *p, unsigned char *start, unsigned char *end); 00294 void CopyTo(SAFEARRAY *p, long *start, long *end); 00295 void CopyTo(SAFEARRAY *p, GUID *start, GUID *end); 00296 00297 void MoveTo(SAFEARRAY *p, CComBstrObj *start, CComBstrObj *end); 00298 00299 // --------------------------- CComVariant 00300 00301 inline VARIANT *PutOut(CComVariant &v) { ASSERT( v.vt == VT_EMPTY ); return &v; } 00302 inline VARIANT *PutInOut(CComVariant &v) { return &v; } 00303 00304 // we use "const VARIANT &" for [in] and "VARIANT *" for [in, out] 00305 // we use "const CComVariant &" for [in] and "CComVariant &" for [in, out] 00306 00307 // these THROW exceptions 00308 00309 // ------- scalar 00310 00311 void CopyTo(unsigned char a, VARIANT *v); 00312 void CopyTo(short a, VARIANT *v); 00313 void CopyTo(long a, VARIANT *v); 00314 void CopyTo(double a, VARIANT *v); 00315 void CopyTo(BSTR a, VARIANT *v); 00316 void CopyTo(IDispatch *p, VARIANT *v); 00317 00318 template<class T> 00319 void CopyTo(const CComObjPtr<T> &p, VARIANT *v) { CopyTo(p.p, v); } 00320 00321 void CopyTo(const VARIANT &v, unsigned char &a); 00322 void CopyTo(const VARIANT &v, short &a); 00323 void CopyTo(const VARIANT &v, long &a); 00324 void CopyTo(const VARIANT &v, double &a); 00325 void CopyTo(const VARIANT &v, BSTR *a); 00326 00327 void MoveTo(BSTR b, VARIANT *v); 00328 void MoveTo(const VARIANT &v, BSTR *b); 00329 00330 void MoveTo(IDispatch **p, VARIANT *v); 00331 00332 template<class T> 00333 void MoveTo(const CComObjPtr<T> &p, VARIANT *v) { MoveTo(p.p, v); } 00334 00335 inline void MoveTo(VARIANT *p, VARIANT *q) 00336 { 00337 ASSERT( p != NULL ); 00338 ASSERT( q != NULL ); 00339 00340 (*q) = (*p); 00341 p->vt = VT_EMPTY; 00342 } 00343 00344 // ------- string conversion 00345 00346 void CopyTo(const char *p, int len, VARIANT *v); 00347 00348 // we cannot use "const VARIANT &", we might have to change 00349 // the type of the variant from VT_DISPATCH to VT_BSTR 00350 int GetCharLength(VARIANT &v); 00351 00352 void CopyTo(const VARIANT &v, char *s, int charlen); 00353 00354 // ------- array conversion 00355 00356 void CopyTo(const CComBstrObj *start, const CComBstrObj *end, VARIANT *v); 00357 void CopyTo(const unsigned char *start, const unsigned char *end, VARIANT *v); 00358 void CopyTo(const long *start, const long *end, VARIANT *v); 00359 00360 void MoveTo(CComBstrObj *start, CComBstrObj *end, VARIANT *v); 00361 00362 long GetArrayLength(const VARIANT &v); 00363 00364 // not safe for multiple access 00365 void GetArrayStart(const VARIANT &v, CComBstrObj *&start); 00366 void GetArrayStart(const VARIANT &v, unsigned char *&start); 00367 void GetArrayStart(const VARIANT &v, long *&start); 00368 00369 void CopyTo(const VARIANT &v, CComBstrObj *start, CComBstrObj *end); 00370 void CopyTo(const VARIANT &v, unsigned char *start, unsigned char *end); 00371 void CopyTo(const VARIANT &v, long *start, long *end); 00372 00373 void MoveTo(VARIANT *v, CComBstrObj *start, CComBstrObj *end); 00374 00375 void CopyTo(const VARIANT &v, GUID &guid); 00376 00377 // ------- inlines 00378 00379 inline void CopyTo(const unsigned char *start, int len, VARIANT *p) { CopyTo(start, start + len, p); } 00380 inline void CopyTo(const long *start, int len, VARIANT *p) { CopyTo(start, start + len, p); } 00381 00382 inline void CopyTo(const GUID &guid, VARIANT *v) { CopyTo((unsigned char*)&guid, sizeof(GUID), v); } 00383 inline void CopyTo(const OBJECTID &objid, VARIANT *v) { CopyTo((unsigned char*)&objid, sizeof(OBJECTID), v); } 00384 00385 inline void CopyTo(const VARIANT &v, CComBstrObj &b) { CopyTo(v, &b.p); } 00386 00387 template<class T> 00388 void CopyTo(T t, CComVariant &v) { CopyTo(t, &v); } 00389 00390 template<class T, class S> 00391 void CopyTo(T t, S s, CComVariant &v) { CopyTo(t, s, &v); } 00392 00393 // --------------------------- COM Helper functions 00394 00395 // these THROW exceptions 00396 00397 bool IsEqualObject(IUnknown *p, IUnknown *q); 00398 00399 // --------------------------- PutInVariant 00400 00401 class PutInVariant 00402 { 00403 public: 00404 template<class T> 00405 PutInVariant(T t) { CopyTo(t, v); } 00406 00407 template<> PutInVariant(int a) : v(a) { } 00408 template<> PutInVariant(short a) : v(a) { } 00409 template<> PutInVariant(unsigned char a) : v(a) { } 00410 template<> PutInVariant(IDispatch *p) : v(p) { } 00411 template<> PutInVariant(BSTR p) : v(p) { } 00412 00413 operator VARIANT () { return v; } 00414 operator CComVariant &() { return v; } 00415 00416 CComVariant v; 00417 }; 00418 00419 // --------------------------- PutInBstr 00420 00421 class PutInBstr 00422 { 00423 public: 00424 template<class T> 00425 PutInBstr(const T& t) { CopyTo(t, b); } 00426 00427 template<> PutInBstr(const BSTR& a) : b(a) { } 00428 00429 template<> PutInBstr(const std::wstring& t) { 00430 b.p = SysAllocStringLen(t.c_str(), t.length()); 00431 } 00432 00433 operator BSTR () { return b; } 00434 00435 CComBstrObj b; 00436 }; 00437 00438 // --------------------------- CComPartObject 00439 00440 template <class BASE> 00441 class CComPartObject : public BASE 00442 { 00443 public: 00444 typedef BASE _BaseClass; 00445 00446 CComPartObject(void* pv) 00447 { 00448 ATLASSERT( pv != NULL ); 00449 m_pOuterUnknown = (IUnknown*)pv; 00450 } 00451 00452 ~CComPartObject() 00453 { 00454 FinalRelease(); 00455 #ifdef _ATL_DEBUG_INTERFACES 00456 _Module.DeleteNonAddRefThunk(_GetRawUnknown()); 00457 #endif 00458 } 00459 00460 STDMETHOD_(ULONG, AddRef)() { return OuterAddRef(); } 00461 STDMETHOD_(ULONG, Release)() { return OuterRelease(); } 00462 00463 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) 00464 { return _InternalQueryInterface(iid, ppvObject); } 00465 00466 template <class Q> 00467 HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp) 00468 { 00469 return QueryInterface(__uuidof(Q), (void**)pp); 00470 } 00471 00472 IUnknown* GetControllingUnknown() 00473 { 00474 #ifdef _ATL_DEBUG_INTERFACES 00475 IUnknown* p; 00476 _Module.AddNonAddRefThunk(m_pOuterUnknown, _T("CComContainedObject"), &p); 00477 return p; 00478 #else 00479 return m_pOuterUnknown; 00480 #endif 00481 } 00482 00483 static HRESULT WINAPI CreateInstance(LPUNKNOWN pUnkOuter, CComPartObject<BASE>** pp) 00484 { 00485 ATLASSERT(pp != NULL); 00486 HRESULT hRes = E_OUTOFMEMORY; 00487 CComPartObject<BASE>* p = NULL; 00488 ATLTRY(p = new CComPartObject<BASE>(pUnkOuter)) 00489 if (p != NULL) 00490 { 00491 p->SetVoid(NULL); 00492 hRes = p->FinalConstruct(); 00493 if (hRes != S_OK) 00494 { 00495 delete p; 00496 p = NULL; 00497 } 00498 } 00499 *pp = p; 00500 return hRes; 00501 } 00502 }; 00503 00504 #endif//MGA_COMMONSMART_H