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