#ifndef __NmEnum_h__ #define __NmEnum_h__ // This is used to create IEnumXXX objects for CSimpleArray > objects template HRESULT CreateEnumFromSimpleAryOfInterface(CSimpleArray& rObjArray, TEnum** ppEnum) { DBGENTRY(CreateEnum); HRESULT hr = S_OK; typedef CComEnum > enum_type; enum_type* pComEnum = new CComObject< enum_type >; if(pComEnum) { TItf** apInterface = NULL; int nItems = rObjArray.GetSize(); if(nItems) { apInterface = new TItf*[nItems]; if(apInterface) { for(int i = 0; i < rObjArray.GetSize(); ++i) { hr = rObjArray[i]->QueryInterface(__uuidof(TItf), reinterpret_cast(&apInterface[i])); if(FAILED(hr)) { delete [] apInterface; goto end; } } } else { hr = E_OUTOFMEMORY; } } TItf** begin = apInterface; TItf** end = apInterface + nItems; if(begin == end) { // Hack to get around ATL bug. // The problem is that for empty enums ATL returns E_FAIL for Next instead of S_FALSE hr = pComEnum->Init(reinterpret_cast(69), reinterpret_cast(69), NULL, AtlFlagNoCopy); } else { hr = pComEnum->Init(begin, end, NULL, AtlFlagTakeOwnership); } if(SUCCEEDED(hr)) { hr = pComEnum->QueryInterface(__uuidof(TEnum), reinterpret_cast(ppEnum)); } if(FAILED(hr)) { delete [] apInterface; } } else { hr = E_NOINTERFACE; } end: DBGEXIT_HR(CreateEnum,hr); return hr; } #endif // __NmEnum_h__