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
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 explicit CComBstrObj(LPCOLESTR q) { p = SysAllocString(q); }
00151 CComBstrObj(const CComBstrObj &q) : p(NULL) { if(q.p) { p = SysAllocStringLen(q, q.Length()); } }
00152 CComBstrObj(CComBstrObj &&q) { p = q.p; q.p = NULL; }
00153 ~CComBstrObj() { if(p) SysFreeString(p); }
00154
00155 const CComBstrObj &operator=(const CComBstrObj &q) { if(p) SysFreeString(p);
00156 p = SysAllocStringLen(q, q.Length()); return *this; }
00157 CComBstrObj& operator=(CComBstrObj&& q) {
00158 if (p) SysFreeString(p);
00159 p = q.p;
00160 q.p = NULL;
00161 return *this;
00162 }
00163 operator BSTR() const { return p; }
00164 unsigned int Length() const { return p ? SysStringLen(p) : 0; }
00165 void Empty() { if( p ) { SysFreeString(p); p = NULL; } }
00166
00167 int Compare(BSTR q) const;
00168 bool operator==(BSTR q) const { return Compare(q) == 0; }
00169 bool operator!=(BSTR q) const { return Compare(q) != 0; }
00170 bool operator<(BSTR q) const { return Compare(q) < 0; }
00171 bool operator>(BSTR q) const { return Compare(q) > 0; }
00172 bool operator<=(BSTR q) const { return Compare(q) <= 0; }
00173 bool operator>=(BSTR q) const { return Compare(q) >= 0; }
00174
00175 BSTR Detach() { BSTR q = p; p = NULL; return q; }
00176 void Attach(BSTR q) { if(p) SysFreeString(p); p = q; }
00177
00178 public:
00179 BSTR p;
00180 };
00181
00182 inline BSTR *PutOut(CComBstrObj &s) { ASSERT( s.p == NULL ); return &s.p; }
00183 inline BSTR *PutInOut(CComBstrObj &s) { return &s.p; }
00184
00185
00186
00187
00188 inline void CopyTo(BSTR p, BSTR *q)
00189 {
00190 ASSERT( q != NULL );
00191
00192 if (*q)
00193 SysFreeString(*q);
00194 *q = SysAllocStringLen(p, SysStringLen(p));
00195 if (*q == NULL && p != NULL)
00196 COMTHROW(E_OUTOFMEMORY);
00197 }
00198
00199 inline void CopyTo(const CComBstrObj &b, BSTR *q) { CopyTo(b.p, q); }
00200 inline void CopyTo(BSTR p, CComBstrObj &b) { CopyTo(p, &b.p); }
00201
00202 inline void MoveTo(BSTR *p, BSTR *q)
00203 {
00204 ASSERT( p != NULL );
00205 ASSERT( q != NULL );
00206
00207 if(*q) SysFreeString(*q);
00208 (*q) = (*p); (*p) = NULL;
00209 }
00210
00211 inline void MoveTo(CComBstrObj &b, BSTR *q) { MoveTo(&b.p, q); }
00212 inline void MoveTo(BSTR *p, CComBstrObj &b) { MoveTo(p, &b.p); }
00213
00214
00215
00216 void CopyTo(const char *p, int len, BSTR *b, UINT codepage=CP_ACP);
00217
00218
00219 int GetCharLength(const OLECHAR *p, int olelen, UINT codepage=CP_ACP);
00220
00221 void CopyTo(const OLECHAR *p, int olelen, char *s, int charlen, UINT codepage=CP_ACP);
00222
00223 void CopyTo(const OLECHAR *p, GUID &guid);
00224 void CopyTo(const GUID &guid, BSTR *p);
00225
00226
00227
00228 inline void CopyTo(const char *p, int len, CComBstrObj &b) { CopyTo(p, len, &b.p); }
00229 inline int GetCharLength(BSTR p) { return GetCharLength(p, SysStringLen(p)); }
00230 inline void CopyTo(BSTR p, char *s, int charlen, UINT codepage=CP_ACP) { CopyTo(p, SysStringLen(p), s, charlen, codepage); }
00231 inline void CopyTo(const GUID &guid, CComBstrObj &b) { CopyTo(guid, &b.p); }
00232
00233
00234
00235 inline void CopyTo(const CComBSTR &b, BSTR *q) { CopyTo(b.m_str, q); }
00236 inline void CopyTo(BSTR p, CComBSTR &b) { CopyTo(p, &b.m_str); }
00237
00238 inline void MoveTo(CComBSTR &b, BSTR *q) { MoveTo(&b.m_str, q); }
00239 inline void MoveTo(BSTR *p, CComBSTR &b) { MoveTo(p, &b.m_str); }
00240
00241
00242
00243 class CComSafeArray
00244 {
00245 public:
00246 CComSafeArray() { p = NULL; }
00247 ~CComSafeArray() { if( p ) SafeArrayDestroy(p); }
00248 operator SAFEARRAY*() { return p; }
00249
00250 public:
00251 SAFEARRAY *p;
00252 };
00253
00254 inline SAFEARRAY **PutOut(CComSafeArray &a) { ASSERT( a.p == NULL ); return &a.p; }
00255 inline SAFEARRAY **PutInOut(CComSafeArray &a) { return &a.p; }
00256
00257
00258
00259
00260
00261
00262 void CopyTo(const CComBstrObj *start, const CComBstrObj *end, SAFEARRAY **p);
00263 void CopyTo(const unsigned char *start, const unsigned char *end, SAFEARRAY **p);
00264 void CopyTo(const long *start, const long *end, SAFEARRAY **p);
00265 void CopyTo(const GUID *start, const GUID *end, SAFEARRAY **p);
00266
00267 void MoveTo(CComBstrObj *start, CComBstrObj *end, SAFEARRAY **p);
00268
00269 long GetArrayLength(SAFEARRAY *p);
00270
00271
00272 void GetArrayStart(SAFEARRAY *p, CComBstrObj *&start);
00273 void GetArrayStart(SAFEARRAY *p, unsigned char *&start);
00274 void GetArrayStart(SAFEARRAY *p, long *&start);
00275 void GetArrayStart(SAFEARRAY *p, GUID *&start);
00276
00277 void CopyTo(SAFEARRAY *p, CComBstrObj *start, CComBstrObj *end);
00278 void CopyTo(SAFEARRAY *p, unsigned char *start, unsigned char *end);
00279 void CopyTo(SAFEARRAY *p, long *start, long *end);
00280 void CopyTo(SAFEARRAY *p, GUID *start, GUID *end);
00281
00282 void MoveTo(SAFEARRAY *p, CComBstrObj *start, CComBstrObj *end);
00283
00284
00285
00286 inline VARIANT *PutOut(CComVariant &v) { ASSERT( v.vt == VT_EMPTY ); return &v; }
00287 inline VARIANT *PutInOut(CComVariant &v) { return &v; }
00288
00289
00290
00291
00292
00293
00294
00295
00296 void CopyTo(unsigned char a, VARIANT *v);
00297 void CopyTo(short a, VARIANT *v);
00298 void CopyTo(long a, VARIANT *v);
00299 void CopyTo(double a, VARIANT *v);
00300 void CopyTo(BSTR a, VARIANT *v);
00301 void CopyTo(IDispatch *p, VARIANT *v);
00302
00303 template<class T>
00304 void CopyTo(const CComObjPtr<T> &p, VARIANT *v) { CopyTo(p.p, v); }
00305
00306 void CopyTo(const VARIANT &v, unsigned char &a);
00307 void CopyTo(const VARIANT &v, short &a);
00308 void CopyTo(const VARIANT &v, long &a);
00309 void CopyTo(const VARIANT &v, double &a);
00310 void CopyTo(const VARIANT &v, BSTR *a);
00311
00312 void MoveTo(BSTR b, VARIANT *v);
00313 void MoveTo(const VARIANT &v, BSTR *b);
00314
00315 void MoveTo(IDispatch **p, VARIANT *v);
00316
00317 template<class T>
00318 void MoveTo(const CComObjPtr<T> &p, VARIANT *v) { MoveTo(p.p, v); }
00319
00320 inline void MoveTo(VARIANT *p, VARIANT *q)
00321 {
00322 ASSERT( p != NULL );
00323 ASSERT( q != NULL );
00324
00325 (*q) = (*p);
00326 p->vt = VT_EMPTY;
00327 }
00328
00329
00330
00331 void CopyTo(const char *p, int len, VARIANT *v);
00332
00333
00334
00335 int GetCharLength(VARIANT &v);
00336
00337 void CopyTo(const VARIANT &v, char *s, int charlen);
00338
00339
00340
00341 void CopyTo(const CComBstrObj *start, const CComBstrObj *end, VARIANT *v);
00342 void CopyTo(const unsigned char *start, const unsigned char *end, VARIANT *v);
00343 void CopyTo(const long *start, const long *end, VARIANT *v);
00344
00345 void MoveTo(CComBstrObj *start, CComBstrObj *end, VARIANT *v);
00346
00347 long GetArrayLength(const VARIANT &v);
00348
00349
00350 void GetArrayStart(const VARIANT &v, CComBstrObj *&start);
00351 void GetArrayStart(const VARIANT &v, unsigned char *&start);
00352 void GetArrayStart(const VARIANT &v, long *&start);
00353
00354 void CopyTo(const VARIANT &v, CComBstrObj *start, CComBstrObj *end);
00355 void CopyTo(const VARIANT &v, unsigned char *start, unsigned char *end);
00356 void CopyTo(const VARIANT &v, long *start, long *end);
00357
00358 void MoveTo(VARIANT *v, CComBstrObj *start, CComBstrObj *end);
00359
00360 void CopyTo(const VARIANT &v, GUID &guid);
00361
00362
00363
00364 inline void CopyTo(const unsigned char *start, int len, VARIANT *p) { CopyTo(start, start + len, p); }
00365 inline void CopyTo(const long *start, int len, VARIANT *p) { CopyTo(start, start + len, p); }
00366
00367 inline void CopyTo(const GUID &guid, VARIANT *v) { CopyTo((unsigned char*)&guid, sizeof(GUID), v); }
00368 inline void CopyTo(const OBJECTID &objid, VARIANT *v) { CopyTo((unsigned char*)&objid, sizeof(OBJECTID), v); }
00369
00370 inline void CopyTo(const VARIANT &v, CComBstrObj &b) { CopyTo(v, &b.p); }
00371
00372 template<class T>
00373 void CopyTo(T t, CComVariant &v) { CopyTo(t, &v); }
00374
00375 template<class T, class S>
00376 void CopyTo(T t, S s, CComVariant &v) { CopyTo(t, s, &v); }
00377
00378
00379
00380
00381
00382 bool IsEqualObject(IUnknown *p, IUnknown *q);
00383
00384
00385
00386 class PutInVariant
00387 {
00388 public:
00389 template<class T>
00390 PutInVariant(T t) { CopyTo(t, v); }
00391
00392 template<> PutInVariant(int a) : v(a) { }
00393 template<> PutInVariant(short a) : v(a) { }
00394 template<> PutInVariant(unsigned char a) : v(a) { }
00395 template<> PutInVariant(IDispatch *p) : v(p) { }
00396 template<> PutInVariant(BSTR p) : v(p) { }
00397
00398 operator VARIANT () { return v; }
00399 operator CComVariant &() { return v; }
00400
00401 CComVariant v;
00402 };
00403
00404
00405
00406 class PutInBstr
00407 {
00408 public:
00409 template<class T>
00410 PutInBstr(T t) { CopyTo(t, b); }
00411
00412 template<> PutInBstr(BSTR a) : b(a) { }
00413
00414 operator BSTR () { return b; }
00415
00416 CComBstrObj b;
00417 };
00418
00419
00420
00421 template <class BASE>
00422 class CComPartObject : public BASE
00423 {
00424 public:
00425 typedef BASE _BaseClass;
00426
00427 CComPartObject(void* pv)
00428 {
00429 ATLASSERT( pv != NULL );
00430 m_pOuterUnknown = (IUnknown*)pv;
00431 }
00432
00433 ~CComPartObject()
00434 {
00435 FinalRelease();
00436 #ifdef _ATL_DEBUG_INTERFACES
00437 _Module.DeleteNonAddRefThunk(_GetRawUnknown());
00438 #endif
00439 }
00440
00441 STDMETHOD_(ULONG, AddRef)() { return OuterAddRef(); }
00442 STDMETHOD_(ULONG, Release)() { return OuterRelease(); }
00443
00444 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
00445 { return _InternalQueryInterface(iid, ppvObject); }
00446
00447 template <class Q>
00448 HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)
00449 {
00450 return QueryInterface(__uuidof(Q), (void**)pp);
00451 }
00452
00453 IUnknown* GetControllingUnknown()
00454 {
00455 #ifdef _ATL_DEBUG_INTERFACES
00456 IUnknown* p;
00457 _Module.AddNonAddRefThunk(m_pOuterUnknown, _T("CComContainedObject"), &p);
00458 return p;
00459 #else
00460 return m_pOuterUnknown;
00461 #endif
00462 }
00463
00464 static HRESULT WINAPI CreateInstance(LPUNKNOWN pUnkOuter, CComPartObject<BASE>** pp)
00465 {
00466 ATLASSERT(pp != NULL);
00467 HRESULT hRes = E_OUTOFMEMORY;
00468 CComPartObject<BASE>* p = NULL;
00469 ATLTRY(p = new CComPartObject<BASE>(pUnkOuter))
00470 if (p != NULL)
00471 {
00472 p->SetVoid(NULL);
00473 hRes = p->FinalConstruct();
00474 if (hRes != S_OK)
00475 {
00476 delete p;
00477 p = NULL;
00478 }
00479 }
00480 *pp = p;
00481 return hRes;
00482 }
00483 };
00484
00485 #endif//MGA_COMMONSMART_H