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