Как создать объект коллекции VB6 с ATL - PullRequest
1 голос
/ 13 ноября 2009

или VB6-совместимый объект коллекции.

Мы предоставляем хуки в наши продукты .net через набор API.

Нам необходимо продолжать поддерживать клиентов, которые вызывают наши API из VB6, поэтому нам необходимо продолжать поддерживать объекты коллекции VB6 (просто с VBA.Collection в .net).

Проблема заключается в поддержке некоторых сайтов, которые используют VBScript для вызова нашего API. VBScript не имеет понятия объекта коллекции, поэтому для создания объекта коллекции для передачи нашему API мы создали библиотеку ActiveX VB6, которая предоставляет метод «CreateCollection». Этот метод просто создает и передает новый объект коллекции. Проблема решена.

После многих лет обрезки, переноса и перестройки эта DLL является единственным имеющимся у нас кодом VB6. Из-за этого нам все еще нужно установить Visual Studio 6 на наших машинах разработки и разработки.

Я не доволен нашей зависимостью от этой DLL по нескольким причинам (моя личная неприязнь к VB6 не является одной из них). Начало списка - Microsoft больше не поддерживает Visual Studio 6.

У меня вопрос: как заставить ATL создать объект коллекции, который реализует тот же интерфейс, что и объект коллекции VB6.

Я хорошо разбираюсь в C ++, но плохо разбираюсь в ATL - я могу создавать простые объекты и реализовывать простые методы, но это мне не под силу.

Ответы [ 3 ]

8 голосов
/ 13 ноября 2009

Коллекции более или менее основаны на соглашении. Они реализуют IDispatch и предоставляют некоторые стандартные методы и свойства:

  • Add() - необязательно
  • Remove() - необязательно
  • Item()
  • Count - только для чтения
  • _NewEnum - скрыто , только для чтения , возвращает указатель на объект перечислителя, который реализует IEnumVariant

Свойство _NewEnum позволяет Visual Basic For Each.

В IDL вы используете dual интерфейс и:

  • DISPID_VALUE для Item()
  • [propget, id(DISPID_NEWENUM), restricted] HRESULT _NewEnum([out, retval] IUnknown** pVal)

Вот некоторые записи MSDN: Вопросы проектирования для объектов ActiveX
А вот некоторые особенности ATL: Коллекции и счетчики ATL

2 голосов
/ 13 ноября 2009

Позволяет нацелиться на этот фрагмент 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).

0 голосов
/ 03 мая 2010

Хороший пример того, как реализовать коллекции COM, которые будут естественным образом использоваться в языках программирования сценариев, можно найти на мой сайт

Он предлагает исчерпывающий пример того, как это сделать ...

...