Как обрабатывать коллекции COM Объектов

Раздел посвящен программированию с использованием Power Basic.
ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Как обрабатывать коллекции COM Объектов

Сообщение ger_kar » 02.02.2012 (Чт) 11:23

Как в PowerBasic обрабатывать коллекции по типу For Each ... In ... Next как это делается в VB?
Конструкция существующая в PB, для обработки коллекций COM не предназначена и может использоваться
Define a loop of program statements which can sequentially examine and act upon each member of a PowerCollection or LinkListCollection

Хорошо если коллекция нумерованная, тогда можно получить максимальное значение индекса и обработать в простом цикле For ... To ... Next, а если не нумерованная, например такая Item(strObjectPath As String, [iFlags As Long]) As SWbemObject, то тогда с перебором по индексу облом.
Вообще цикл For Each ... In ... Next вроде как использует _NewEnum, но сам механизм, как это происходит я не знаю, вот думаю, что в PB для перебора коллекции тоже можно использовать этот механизм, но моя "дума" всего лишь предположения и как это правильно сделать я не представляю. Просветите меня на это счет, если кто таким знанием обладает.
Заранее спасибо.
Бороться и искать, найти и перепрятать

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Как обрабатывать коллекции COM Объектов

Сообщение ger_kar » 03.02.2012 (Пт) 6:48

Да уж...
Неужели на PoverBasic никто энумерации коллекций ни разу не обрабатывал? Довольно странно.
Видимо придется все самому раскапывать и изнутри изучать ;)
Бороться и искать, найти и перепрятать

Smitis-R
Новичок
Новичок
 
Сообщения: 48
Зарегистрирован: 26.04.2005 (Вт) 0:37

Re: Как обрабатывать коллекции COM Объектов

Сообщение Smitis-R » 03.02.2012 (Пт) 19:12

Главное - потом поделись результатами :wink:

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Как обрабатывать коллекции COM Объектов

Сообщение ger_kar » 04.02.2012 (Сб) 12:47

Стою на асфальте я в лыжи обутый, то ли лыжи не едут то ли я ....

А теперь все по порядку.
Решил таки я изучить, как работает энумерация коллекций COM, так сказать изнутри. Но все оказалось довольно запутанным и туманным. Как оказалось каждая коллекция для того, что-бы поддерживалась обработка For Each In ... Next имеет Property _NewEnum, который если верить документации различных источников и MSDN в т.ч. должен возвращать ссылку на интерфейс IEnumVARIANT, который наследуется от IUnknown и описан в MSDN
Код: Выделить всё
interface IEnumVARIANT : IUnknown {
   virtual HRESULT Next(unsigned long celt,
               VARIANT FAR* rgvar,
               unsigned long FAR* pceltFetched) = 0;
   virtual HRESULT Skip(unsigned long celt) = 0;
   virtual HRESULT Reset() = 0;
   virtual HRESULT Clone(IEnumVARIANT FAR* FAR* ppenum) = 0;
   };

Про то, что коллекция должна иметь _NemEnum, я конечно и раньше знал и не просто знал, а обязательно добавлял в коллекции, которые реализовывал в VB, но что конкретно из себя представляет это свойство узнал только сейчас. Интересненькое дельце, однако идем дальше ... Для реализации энумерации данный интерфейс содержит методы Next, Skip, Reset, Clone. Для перебора коллекции самый нужный метод Next, который описывается так:
Код: Выделить всё
HRESULT Next(
  unsigned long celt,
  VARIANT FAR* rgVar,
  unsigned long FAR* pCeltFetched
);


Кажется все предельно ясным? Ага, аж два раза. С первого взгляда конечно, выглядит все предельно просто, но вот при реализации возникает куча непоняток. Казалось, бы получил ссылку на интерфейс IEnumVARIANT от _NewEnum, вызывай себе метод Next и спокойненько обрабатывай, но не тут то было.
Итак грабли №1:
Попытка получить ссылку на IEnumVARIANT от _NewEnum, не такая уж как оказалось тривиальная задача, ибо вызов вида
Object Get MyCollection._NewEnum To ObjMember
в PB не прокатывает, причем если заключить _NewEnum в скобки и использовать так [_NewEnum], ничего ровным счетом не меняет. Значит в лоб вызвать не получается, прийдется идти в обход... Интеренет советует по этому поводу вызов не по имени, а по DispID. По феншую Microsoft у _NewEnum всегда фиксированное имя и ID которое равно равно '-4'. Разумеется, что сразу же возник вопрос, а как вызывать то по этому ID, и что собственно этот ID из себя предствляет. На эту тему в интернете путнего ничего не нашел, поэтому все так и осталось покрыто туманом неведения и догадок. Если DispID это смещение в таблице VTable, то тогда можно организовать вызов по указателю, но вот само значение '-4' или Hex значение '&HFFFF FFFC' меня несколько ставит в тупик, ибо такое большое число как '&HFFFF FFFC' вряд ли может быть смещением. Конечно может смещение действительно равно -4 и смещается в другую сторону от начала таблицы? Типо того:

ID -4 XXXXXXXX
ID 0 XXXXXXXX Начало VTable (Базовый адресок ;) )
ID 4 XXXXXXXX
ID ............


Но тоже как то все это очень странно и нелогично.

Вобщем объясните знающие люди, что есть DispID и как его можно применить при вызове свойства/метода?
Бороться и искать, найти и перепрятать

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как обрабатывать коллекции COM Объектов

Сообщение iGrok » 04.02.2012 (Сб) 14:16

DispID это просто идентификатор. Используется для вызова через IDispatch::Invoke
http://msdn.microsoft.com/en-us/library/aa912367.aspx
label:
cli
jmp label

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как обрабатывать коллекции COM Объектов

Сообщение Хакер » 04.02.2012 (Сб) 19:46

ger_kar писал(а):Вобщем объясните знающие люди, что есть DispID и как его можно применить при вызове свойства/метода?

Неужели нужно опять давать ссылку на статью, которую ты уже читал?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Как обрабатывать коллекции COM Объектов

Сообщение ger_kar » 04.02.2012 (Сб) 22:21

Хакер писал(а):Неужели нужно опять давать ссылку на статью, которую ты уже читал?
А ведь действительно читал. Но при прошлом прочтении, а было это полгода назад, я читал этот материал абстрактно, так сказать, для пополнения общего багажа знаний. Но по прошествии времени, при решении конкретной проблемы, я почему-то про этот полученный багаж, а именно про DispID, на который там делается особый акцент совершенно забыл. Поэтому прочитал эту статью еще раз, и на этот раз пользы от ее прочтения получилось гораздо больше, во первых потому, что при решении проблемы и прокручивании ее с разных сторон все осознается и откладывается в голове гораздо лучше, и как правило это соединяется с другими сведениями по этой проблеме, в результате получается более полная картина. Ну и конечно нынче, новое знание легло на более подготовленную почву, по сравнению с ситуацией полугодовой давности.
Поэтому отвечу на поставленный вопрос так: Да ссылка мне помогла, поэтому ее стоило дать, за что большое спасибо. Я бы конечно изучая этот вопрос, рано или поздно опять бы вышел на эту статью, но времени было-бы потрачено гораздо больше (в разы).

Кстати в PB и инструмент, после прочтения статьи подходящий отыскался.

iGrok писал(а):DispID это просто идентификатор. Используется для вызова через IDispatch::Invoke
Кстати я этот материал читал буквально вчера, но почему-то мне казалось, что DispID, если и не является смещением в Vtable, то как-то все равно с ним увязан, а зная смещение, гораздо удобнее вызвать метод по указателю, нежели посредством Invoke.
Спасибо, теперь в голове все встало на свое место.
Бороться и искать, найти и перепрятать


Вернуться в Power Basic

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20

    TopList