00001
00002 #ifndef __COMHELP_H
00003 #define __COMHELP_H
00004
00005 #ifndef __AFXTEMPL_H__
00006 #include <afxtempl.h>
00007 #endif
00008
00009 #ifndef __unknwn_h__
00010 #include <unknwn.h>
00011 #endif
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 inline void COMASSERT(HRESULT hr)
00022 {
00023 ASSERT(SUCCEEDED(hr));
00024 }
00025
00026
00027
00028 class CBstr
00029 {
00030 public:
00031 CBstr() : s(NULL) { }
00032 CBstr(const CString &str) : s(str.AllocSysString()) { }
00033 ~CBstr() { Free(); }
00034
00035 void operator = (const CString &str) { Free(); s = str.AllocSysString(); }
00036
00037 void Free() { SysFreeString(s); }
00038
00039 BSTR Send() { return s; }
00040 operator BSTR* () { return &s; }
00041 operator CString () { return s; }
00042
00043 private:
00044 BSTR s;
00045 };
00046
00047 class CBstrRef
00048 {
00049 public:
00050 CBstrRef(BSTR str) : s(str) { }
00051
00052 void operator = (const CString& str) { Free(); s = str.AllocSysString(); }
00053
00054 void Free() { SysFreeString(s); }
00055
00056 operator BSTR () { return s; }
00057 operator CString () { return s; }
00058
00059 private:
00060 BSTR &s;
00061 };
00062
00063 class CBstrIn
00064 {
00065 public:
00066 CBstrIn(const CString &str) : s(str.AllocSysString()) { }
00067 ~CBstrIn() { SysFreeString(s); }
00068
00069 operator BSTR () { return s; }
00070
00071 private:
00072 BSTR s;
00073 };
00074
00075
00076
00077 class CIUnknownPtrList : public CList<IUnknown*, IUnknown*>
00078 {
00079 public:
00080 CIUnknownPtrList() { };
00081
00082 void Load(SAFEARRAY** ppsa);
00083 void Copy(SAFEARRAY* ppsa);
00084 SAFEARRAY* Store();
00085
00086 void AddRefAll();
00087 void ReleaseAll();
00088 };
00089
00090
00091
00092
00093
00094 template<class TYPE>
00095 class CInterfacePtrList : public CIUnknownPtrList
00096 {
00097 public:
00098
00099 CInterfacePtrList() : CIUnknownPtrList() { };
00100
00101 template<class SOURCE>
00102 void AddInterfaces(SOURCE &source)
00103 {
00104 POSITION pos = source.GetHeadPosition();
00105 while(pos)
00106 {
00107 TYPE i = source.GetNext(pos)->GetInterface();
00108 ASSERT(i);
00109 AddTail(i);
00110 }
00111 }
00112
00113
00114 TYPE& GetHead()
00115 { return (TYPE&)CIUnknownPtrList::GetHead(); }
00116 TYPE GetHead() const
00117 { return (TYPE)CIUnknownPtrList::GetHead(); }
00118 TYPE& GetTail()
00119 { return (TYPE&)CIUnknownPtrList::GetTail(); }
00120 TYPE GetTail() const
00121 { return (TYPE)CIUnknownPtrList::GetTail(); }
00122
00123
00124 TYPE RemoveHead()
00125 { return (TYPE)CIUnknownPtrList::RemoveHead(); }
00126 TYPE RemoveTail()
00127 { return (TYPE)CIUnknownPtrList::RemoveTail(); }
00128
00129
00130 POSITION AddHead(TYPE newElement)
00131 { return CIUnknownPtrList::AddHead(newElement); }
00132 POSITION AddTail(TYPE newElement)
00133 { return CIUnknownPtrList::AddTail(newElement); }
00134
00135
00136 void AddHead(CInterfacePtrList<TYPE>* pNewList)
00137 { CIUnknownPtrList::AddHead(pNewList); }
00138 void AddTail(CInterfacePtrList<TYPE>* pNewList)
00139 { CIUnknownPtrList::AddTail(pNewList); }
00140
00141
00142 TYPE& GetNext(POSITION& rPosition)
00143 { return (TYPE&)CIUnknownPtrList::GetNext(rPosition); }
00144 TYPE GetNext(POSITION& rPosition) const
00145 { return (TYPE)CIUnknownPtrList::GetNext(rPosition); }
00146 TYPE& GetPrev(POSITION& rPosition)
00147 { return (TYPE&)CIUnknownPtrList::GetPrev(rPosition); }
00148 TYPE GetPrev(POSITION& rPosition) const
00149 { return (TYPE)CIUnknownPtrList::GetPrev(rPosition); }
00150
00151
00152 TYPE& GetAt(POSITION position)
00153 { return (TYPE&)CIUnknownPtrList::GetAt(position); }
00154 TYPE GetAt(POSITION position) const
00155 { return (TYPE)CIUnknownPtrList::GetAt(position); }
00156 void SetAt(POSITION pos, TYPE newElement)
00157 { CIUnknownPtrList::SetAt(pos, newElement); }
00158
00159 };
00160
00161
00162
00163
00164 template<class TYPE, class SOURCE>
00165 SAFEARRAY* CreateInterfaceSafeArray(SOURCE &source)
00166 {
00167 SAFEARRAY *psa;
00168
00169 psa = SafeArrayCreateVector(VT_UNKNOWN, 0, source.GetCount());
00170 ASSERT(psa);
00171
00172 IUnknown* *p;
00173 COMVERIFY(SafeArrayAccessData(psa,(void**)&p));
00174
00175 POSITION pos = source.GetHeadPosition();
00176 while(pos)
00177 {
00178 TYPE i = source.GetNext(pos)->GetInterface();
00179 ASSERT(i);
00180 i->AddRef();
00181 *(p++) = i;
00182 }
00183
00184 COMVERIFY(SafeArrayUnaccessData(psa));
00185
00186 return psa;
00187 }
00188
00189 HRESULT SafeArrayDestroyNoRelease(SAFEARRAY* psa);
00190 void LoadBstrSafeArray(CStringList& dest, SAFEARRAY** ppsa);
00191 SAFEARRAY* StoreBstrSafeArray(CStringList& source);
00192
00193 typedef CList<float, float&> FloatList;
00194 void LoadFloatSafeArray(FloatList& dest, SAFEARRAY** ppsa);
00195 SAFEARRAY* StoreFloatSafeArray(FloatList& source);
00196
00197
00198
00199
00200
00201
00202
00203
00204 #include <atlbase.h>
00205
00206 template<class INTERFACE>
00207 class CComPtrList : public CList< CAdapt< CComPtr<INTERFACE> >, CAdapt< CComPtr<INTERFACE> >& >
00208 {
00209 public:
00210 typedef CComPtr<INTERFACE> COMPTR;
00211 typedef CAdapt<COMPTR> CADAPT;
00212 typedef CList<CADAPT, CADAPT&> BASE;
00213 typedef CComPtrList<INTERFACE> SELF;
00214
00215 static CADAPT &CastPtr(INTERFACE *&ptr) { return *(CADAPT*)&ptr; }
00216
00217
00218 COMPTR &GetHead() { return BASE::GetHead(); }
00219 COMPTR GetHead() const { return BASE::GetHead(); }
00220 COMPTR &GetTail() { return BASE::GetTail(); }
00221 COMPTR GetTail() const { return BASE::GetTail(); }
00222
00223
00224 COMPTR RemoveHead() { return BASE::RemoveHead(); }
00225 COMPTR RemoveTail() { return BASE::RemoveTail(); }
00226
00227
00228 POSITION AddHead(INTERFACE *newElement) { return BASE::AddHead(CastPtr(newElement)); }
00229 POSITION AddTail(INTERFACE *newElement) { return BASE::AddTail(CastPtr(newElement)); }
00230
00231
00232 COMPTR &GetNext(POSITION& rPosition) { return BASE::GetNext(rPosition); }
00233 COMPTR GetNext(POSITION& rPosition) const { return BASE::GetNext(rPosition); }
00234 COMPTR &GetPrev(POSITION& rPosition) { return BASE::GetPrev(rPosition); }
00235 COMPTR GetPrev(POSITION& rPosition) const { return BASE::GetPrev(rPosition); }
00236
00237
00238 COMPTR &GetAt(POSITION position) { return BASE::GetAt(position); }
00239 COMPTR GetAt(POSITION position) const { return BASE::GetAt(position); }
00240 void SetAt(POSITION pos, INTERFACE *newElement) { BASE::SetAt(pos, CastPtr(newElement)); }
00241
00242
00243 POSITION InsertBefore(POSITION position, INTERFACE *newElement)
00244 { return BASE::InsertBefore(position, CastPtr(newElement)); }
00245 POSITION InsertAfter(POSITION position, INTERFACE *newElement)
00246 { return BASE::InsertAfter(position, CastPtr(newElement)); }
00247
00248
00249 POSITION Find(INTERFACE *searchValue, POSITION startAfter = NULL) const
00250 { return BASE::Find(CastPtr(searchValue), startAfter); }
00251
00252 };
00253
00254
00255
00256 template<class INTERFACE>
00257 class CComPtrArray : public CArray< CAdapt< CComPtr<INTERFACE> >, CComPtr<INTERFACE>& >
00258 {
00259 public:
00260 typedef CComPtr<INTERFACE> COMPTR;
00261 typedef CAdapt<COMPTR> CADAPT;
00262 typedef CArray<CADAPT, COMPTR&> BASE;
00263 typedef CComPtrArray<INTERFACE> SELF;
00264
00265 static COMPTR &CastPtr(INTERFACE *&ptr) { return *(COMPTR*)&ptr; }
00266
00267
00268 COMPTR GetAt(int nIndex) const { return BASE::GetAt(nIndex); }
00269 COMPTR& ElementAt(int nIndex) { return BASE::ElementAt(nIndex); }
00270
00271
00272 const COMPTR* GetData() const { return BASE::GetData(); }
00273 COMPTR* GetData() { return BASE::GetData(); }
00274
00275
00276 void SetAtGrow(int nIndex, INTERFACE *newElement)
00277 { BASE::SetAtGrow(nIndex, CastPtr(newElement)); }
00278 int Add(INTERFACE *newElement) { return BASE::Add(CastPtr(newElement)); }
00279
00280
00281 COMPTR operator[](int nIndex) const { return BASE::operator[](nIndex); }
00282 COMPTR &operator[](int nIndex) { return BASE::operator[](nIndex); }
00283
00284
00285 void InsertAt(int nIndex, INTERFACE *newElement, int nCount = 1)
00286 { BASE::InsertAt(nIndex, CastPtr(newElement), nCount); }
00287 };
00288
00289
00290
00291 template<class INTERFACE>
00292 void CopyTo(SAFEARRAY* psa, CComPtrList<INTERFACE> &container)
00293 {
00294 ASSERT(psa);
00295 container.RemoveAll();
00296
00297 INTERFACE* *p;
00298 COMVERIFY(SafeArrayAccessData(psa, (void**)&p));
00299 ASSERT(p);
00300
00301 long bound;
00302
00303 ASSERT( (psa)->fFeatures | FADF_UNKNOWN );
00304 ASSERT( (psa)->cbElements == sizeof(IUnknown*) );
00305 ASSERT( SafeArrayGetDim(psa) == 1 );
00306 COMASSERT(SafeArrayGetLBound(psa, 1, &bound));
00307 ASSERT( bound == 0 );
00308
00309 COMVERIFY(SafeArrayGetUBound(psa, 1, &bound));
00310 ASSERT( bound >= -1 );
00311
00312 while( bound-- >= 0 )
00313 container.AddTail(*(p++));
00314
00315 COMVERIFY(SafeArrayUnaccessData(psa));
00316 }
00317
00318 template<class INTERFACE>
00319 void MoveTo(SAFEARRAY** ppsa, CComPtrList<INTERFACE> &container)
00320 {
00321 ASSERT(ppsa && *ppsa);
00322
00323 container.RemoveAll();
00324
00325 INTERFACE* *p;
00326 COMVERIFY(SafeArrayAccessData(*ppsa, (void**)&p));
00327 ASSERT(p);
00328
00329 long bound;
00330
00331 ASSERT( (*ppsa)->fFeatures | FADF_UNKNOWN );
00332 ASSERT( (*ppsa)->cbElements == sizeof(IUnknown*) );
00333 ASSERT( SafeArrayGetDim(*ppsa) == 1 );
00334 COMASSERT(SafeArrayGetLBound(*ppsa, 1, &bound));
00335 ASSERT( bound == 0 );
00336
00337 COMVERIFY(SafeArrayGetUBound(*ppsa, 1, &bound));
00338 ASSERT( bound >= -1 );
00339
00340 while( bound-- >= 0 )
00341 {
00342 container.AddTail(NULL);
00343 container.GetTail().p = *(p++);
00344 }
00345
00346 COMVERIFY(SafeArrayUnaccessData(*ppsa));
00347
00348 COMVERIFY(SafeArrayDestroyNoRelease(*ppsa));
00349 *ppsa = NULL;
00350 }
00351
00352 template<class INTERFACE>
00353 void CopyTo(CComPtrList<INTERFACE> &container, SAFEARRAY **ppsa)
00354 {
00355 ASSERT( *ppsa == NULL );
00356
00357 *ppsa = SafeArrayCreateVector(VT_UNKNOWN, 0, container.GetCount());
00358 ASSERT(*ppsa);
00359
00360 IUnknown* *p;
00361 COMVERIFY(SafeArrayAccessData(*ppsa,(void**)&p));
00362
00363 POSITION pos = container.GetHeadPosition();
00364 while(pos)
00365 {
00366 INTERFACE *a = container.GetNext(pos).p;
00367 a->AddRef();
00368 *(p++) = a;
00369 }
00370
00371 COMVERIFY(SafeArrayUnaccessData(*ppsa));
00372 }
00373
00374 template<class INTERFACE>
00375 void MoveTo(CComPtrList<INTERFACE> &container, SAFEARRAY **ppsa)
00376 {
00377 ASSERT( *ppsa == NULL );
00378
00379 *ppsa = SafeArrayCreateVector(VT_UNKNOWN, 0, container.GetCount());
00380 ASSERT(*ppsa);
00381
00382 IUnknown* *p;
00383 COMVERIFY(SafeArrayAccessData(*ppsa,(void**)&p));
00384
00385 POSITION pos = container.GetHeadPosition();
00386 while(pos)
00387 {
00388 CComPtr<INTERFACE> &a = container.GetNext(pos);
00389 *(p++) = a;
00390 a.p = NULL;
00391 }
00392
00393 COMVERIFY(SafeArrayUnaccessData(*ppsa));
00394
00395 container.RemoveAll();
00396 }
00397
00398 #endif//__COMHELP_H