00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00048 #ifndef ATLSTL_INCL_ATLSTL_AUTOMATION_HPP_AUTOMATION_COLLECTIONS
00049 #define ATLSTL_INCL_ATLSTL_AUTOMATION_HPP_AUTOMATION_COLLECTIONS
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define ATLSTL_VER_ATLSTL_AUTOMATION_HPP_AUTOMATION_COLLECTIONS_MAJOR 3
00053 # define ATLSTL_VER_ATLSTL_AUTOMATION_HPP_AUTOMATION_COLLECTIONS_MINOR 2
00054 # define ATLSTL_VER_ATLSTL_AUTOMATION_HPP_AUTOMATION_COLLECTIONS_REVISION 2
00055 # define ATLSTL_VER_ATLSTL_AUTOMATION_HPP_AUTOMATION_COLLECTIONS_EDIT 107
00056 #endif
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #ifndef ATLSTL_INCL_ATLSTL_HPP_ATLSTL
00073 # include <atlstl/atlstl.hpp>
00074 #endif
00075
00076 #ifndef STLSOFT_INCL_SYS_H_ATLCOM
00077 # define STLSOFT_INCL_SYS_H_ATLCOM
00078 # include <atlcom.h>
00079 #endif
00080
00081
00082
00083
00084
00085 #ifndef _ATLSTL_NO_NAMESPACE
00086 # if defined(_STLSOFT_NO_NAMESPACE) || \
00087 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00088
00089 namespace atlstl
00090 {
00091 # else
00092
00093
00094 namespace stlsoft
00095 {
00096
00097 namespace atlstl_project
00098 {
00099
00100 # endif
00101 #endif
00102
00103
00104
00105
00106
00107
00108 template< ss_typename_param_k D
00109 , ss_typename_param_k ThreadModel
00110 , ss_typename_param_k I
00111 , int DispidCount
00112 >
00113 class generic_collection_base
00114 : public I
00115 , public CComObjectRootEx<ThreadModel>
00116 {
00119 public:
00120 typedef D derived_class_type;
00121
00122 typedef generic_collection_base<D, ThreadModel, I, DispidCount> class_type;
00124
00127 protected:
00128 generic_collection_base()
00129 {}
00131
00134 protected:
00135 BEGIN_COM_MAP(generic_collection_base)
00136 COM_INTERFACE_ENTRY(IDispatch)
00137 END_COM_MAP()
00139
00142 protected:
00143 STDMETHOD(GetTypeInfoCount)(UINT* pctinfo)
00144 {
00145 *pctinfo = 0;
00146
00147 return S_OK;
00148 }
00149 STDMETHOD(GetTypeInfo)(UINT iTInfo, LCID , ITypeInfo** ppTInfo)
00150 {
00151 if(0 != iTInfo)
00152 {
00153 return DISP_E_BADINDEX;
00154 }
00155 else if(NULL == ppTInfo)
00156 {
00157 return E_POINTER;
00158 }
00159 else
00160 {
00161 *ppTInfo = NULL;
00162
00163 return S_FALSE;
00164 }
00165 }
00166 STDMETHOD(GetIDsOfNames)( REFIID
00167 , LPOLESTR* rgszNames
00168 , UINT cNames
00169 , LCID
00170 , DISPID* rgDispId)
00171 {
00172 if(1 == cNames)
00173 {
00174 if(0 == ::wcscmp(rgszNames[0], L"Count"))
00175 {
00176 derived_class_type* pThis = static_cast<derived_class_type*>(this);
00177 HRESULT hr = pThis->SupportsCount();
00178
00179 if(S_OK == hr)
00180 {
00181 rgDispId[0] = DispidCount;
00182
00183 return hr;
00184 }
00185 }
00186 }
00187
00188 return DISP_E_UNKNOWNNAME;
00189 }
00190 STDMETHOD(Invoke)( DISPID dispidMember
00191 , REFIID
00192 , LCID
00193 , WORD
00194 , DISPPARAMS* pDispParams
00195 , VARIANT* pVarResult
00196 , EXCEPINFO*
00197 , UINT* )
00198 {
00199 if(DISPID_NEWENUM == dispidMember)
00200 {
00201 derived_class_type* pThis = static_cast<derived_class_type*>(this);
00202
00203 if(0 != pDispParams->cArgs)
00204 {
00205 return DISP_E_BADPARAMCOUNT;
00206 }
00207 else
00208 {
00209 LPUNKNOWN punkEnumerator;
00210 HRESULT hr;
00211
00212 ::VariantInit(pVarResult);
00213
00214
00215 hr = pThis->get__NewEnum(&punkEnumerator);
00216
00217 if(SUCCEEDED(hr))
00218 {
00219 pVarResult->vt = VT_UNKNOWN;
00220 pVarResult->punkVal = punkEnumerator;
00221 }
00222
00223 return hr;
00224 }
00225 }
00226 else if(DispidCount == dispidMember)
00227 {
00228 derived_class_type* pThis = static_cast<derived_class_type*>(this);
00229 HRESULT hr;
00230
00231 ::VariantInit(pVarResult);
00232
00233 hr = pThis->get_Count(&pVarResult->lVal);
00234
00235 if(SUCCEEDED(hr))
00236 {
00237 pVarResult->vt = VT_I4;
00238 }
00239
00240 return hr;
00241 }
00242 else
00243 {
00244 return DISP_E_MEMBERNOTFOUND;
00245 }
00246 }
00248 };
00249
00250
00251 template< ss_typename_param_k I1
00252 , ss_typename_param_k I2
00253 , ss_typename_param_k I3
00254 >
00255 inline LPUNKNOWN get_clone(I1* instance, HRESULT (STDAPICALLTYPE I3::*pfn)(I2**), HRESULT &hr)
00256 {
00257 I2* clone;
00258
00259 hr = (instance->*pfn)(&clone);
00260
00261 if(FAILED(hr))
00262 {
00263 clone = NULL;
00264 }
00265
00266 return clone;
00267 }
00268
00271
00272 template< ss_typename_param_k E
00273 , ss_typename_param_k ThreadModel = CComObjectThreadModel
00274 , ss_typename_param_k I = IDispatch
00275 , int DispidCount = 20001
00276 >
00277 class generic_automation_collection
00278 : public generic_collection_base<generic_automation_collection<E, ThreadModel, I, DispidCount>, ThreadModel, I, DispidCount>
00279 {
00280 public:
00281 typedef E enumerator_type;
00282 typedef generic_automation_collection<E, ThreadModel, I, DispidCount> class_type;
00283
00284 public:
00285 generic_automation_collection()
00286 : m_enumerator(NULL)
00287 , m_count(static_cast<as_size_t>(~0))
00288 {}
00289 void SetEnumerator(enumerator_type* enumerator, as_bool_t bAddRef)
00290 {
00291 ATLSTL_ASSERT(NULL != enumerator);
00292 ATLSTL_ASSERT(NULL == m_enumerator);
00293
00294 m_enumerator = enumerator;
00295 if(bAddRef)
00296 {
00297 m_enumerator->AddRef();
00298 }
00299 }
00300 void SetCount(as_size_t count)
00301 {
00302 m_count = count;
00303 }
00304 ~generic_automation_collection()
00305 {
00306 m_enumerator->Release();
00307 }
00308
00309 HRESULT SupportsCount() const
00310 {
00311 return (static_cast<as_size_t>(~0) == m_count) ? S_FALSE : S_OK;
00312 }
00313
00314 public:
00315 template< ss_typename_param_k ITER
00316 , ss_typename_param_k ITF
00317 , ss_typename_param_k N
00318 >
00319 HRESULT Init(ITER begin, ITER end, ITF* owner, N flags)
00320 {
00321 ATLSTL_ASSERT(NULL != m_enumerator);
00322
00323 return m_enumerator->Init(begin, end, owner, flags);
00324 }
00325 template< ss_typename_param_k ITER
00326 , ss_typename_param_k ITF
00327 >
00328 HRESULT Init(ITER begin, ITER end, ITF* owner)
00329 {
00330 ATLSTL_ASSERT(NULL != m_enumerator);
00331
00332 return m_enumerator->Init(begin, end, owner);
00333 }
00334
00335 public:
00336 HRESULT get__NewEnum(LPUNKNOWN* punk)
00337 {
00338 ATLSTL_ASSERT(NULL != m_enumerator);
00339
00340 HRESULT hr;
00341
00342 *punk = get_clone(m_enumerator, &enumerator_type::Clone, hr);
00343
00344 #if 0
00345 typedef HRESULT (STDAPICALLTYPE enumerator_type::_CComEnumBase::*pfn_t)(LPUNKNOWN*);
00346 typedef HRESULT (STDAPICALLTYPE enumerator_type::_CComEnumBase::*pfnv_t)(void*);
00347
00348 union
00349 {
00350 pfn_t pfn;
00351 pfnv_t pfnv;
00352 } u;
00353
00354 u.pfnv = (pfnv_t)(&enumerator_type::Clone);
00355
00356 return (m_enumerator->*u.pfn)(punk);
00357 #else
00358 return hr;
00359 #endif
00360 }
00361 HRESULT get_Count(long* pVal)
00362 {
00363 ATLSTL_ASSERT(NULL != pVal);
00364
00365 if(static_cast<as_size_t>(~0) == m_count)
00366 {
00367 return E_UNEXPECTED;
00368 }
00369 else
00370 {
00371 *pVal = static_cast<long>(m_count);
00372
00373 return S_OK;
00374 }
00375 }
00376
00379 private:
00380 enumerator_type* m_enumerator;
00381 as_size_t m_count;
00383
00384 private:
00385 generic_automation_collection(class_type const&);
00386 class_type& operator =(class_type const&);
00387 };
00388
00389 #if 0
00390 template< ss_typename_param_k C
00391 , ss_typename_param_k E
00392 , ss_typename_param_k T
00393 , ss_typename_param_k XXXXXXXXX
00394 >
00395 class simple_automation_collection
00396 {
00397 };
00398 #endif
00399
00401
00402
00403 #ifdef STLSOFT_UNITTEST
00404 # include "./unittest/automation_collections_unittest_.h"
00405 #endif
00406
00407
00408
00409 #ifndef _ATLSTL_NO_NAMESPACE
00410 # if defined(_STLSOFT_NO_NAMESPACE) || \
00411 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00412 }
00413 # else
00414 }
00415 }
00416 # endif
00417 #endif
00418
00419
00420
00421 #endif
00422
00423