Позволяет нацелиться на этот фрагмент VBScript
Dim vElem
For Each vElem In MyObject
...
Next
особенно реализация MyObject. Как минимум, вы должны реализовать метод / пропет с DISPID_NEWENUM на dispinterface по умолчанию (его dual / dispinterface, чтобы говорить о DISPID). Вы можете назвать это как хотите, это не имеет значения. Большинство коллекций используют NewEnum и помечают его в IDL как скрытое. VB6 использует префикс подчеркивания для обозначения скрытых методов, поэтому вы можете видеть _NewEnum в качестве рекомендации, но это своего рода культовый груз, который делает ATL.
Вы не не нуждаетесь ни в каком Count, Item, Add, Remove, Clear или любом другом методе вообще (в интерфейсе по умолчанию). Вы можете предоставить их для удобства (в частности, средство доступа к элементам и, возможно, Count), но вам не нужно, чтобы приведенный выше пример кода работал.
Затем ретваль имеет в качестве отдельного объекта (так называемого перечислителя), который реализует интерфейс IEnumVARIANT с помощью (частного) указателя на MyObject. В IDL вы можете объявить Retval как IUnknown ничего плохого здесь. Самое интересное то, что у вас есть для реализации только метода Next в IEnumVARIANT, вы можете вернуть E_NOTIMPLEMENTED для остальных, если вам нравится или опционально реализовать их, хотя они никогда не вызываются для каждого. Что делает реализацию еще проще, так это то, что параметр celt для Next (количество запрашиваемых элементов) равен всегда 1, поэтому для каждого запроса элементы всегда один за другим.
То, что вы можете использовать в ATL, это CComEnumOnSTL и тому подобное для создания перечислителя «прокси» в контейнере STL, или перечислитель ATL на основе массива предоставляет (и исключает STL).