Re[7]: COM на C#. Не могу получить объект из коллекции.
От: bnk СССР http://unmanagedvisio.com/
Дата: 24.12.07 08:34
Оценка: +1
Здравствуйте, Vi2, Вы писали:

Vi2>Потому что это вызов у объекта "c" метода "objs" с параметром "1". Скорее всего, нужно в этом методе предусмотреть необязательный параметр и отрабатывать его соответственно: если есть, то возвращать i-ый объект коллекции, если нет, то возвращать саму коллекцию. Если это неприемлимо, то тогда и решения нет.


Vi2>PS

Vi2>Кстати, те языки, которые понимают Библиотеку типов, должны правильно разруливать вызовы и должны отработать по сценарию (c.objs)(1).

IMHO тут должен быть какой-то трюк (для экселя вот это например вполне работает):
Тот же VB script:
Set e = CreateObject("Excel.Application")
e.Workbooks.Add
Set a = e.Worksheets(1)  ' <- все ОК (хотя библиотеки типов нет)

Set c = CreateObject("ClassLibrary1.Class1")
Set a = c.objs(1) ' <- Oops !

Кажется Excel добавляет к коллекции метод _Default(VARIANT) c DispId=0
COM на C#. Не могу получить объект из коллекции.
От: sashar2  
Дата: 19.12.07 15:34
Оценка:
Здравствуйте, уважаемые жители этого форума.
Я тут впервые, но со сложным (для меня) вопросом.

Пишу я на C# свой COM. Всё впорядке, но за исключением того, что не могу использовать индексаторы в полной мере. Например: объект myCom.obj[2] или myCom.obj(2) (взависимости от языка) я не могу получить.
Хотя выполняю правильно регистрацию, создаю интерфейсы, присваиваю guid, свойству с индексатором в интерфейсе ставлю аттрибут [DispId(0)], как положено. Но это свойство почему-то правильно работает, только если его вызвать его непосредственно у com объекта:
myCom[0] или myCom(0) (если в моем интерфейсе конечно объявлено свойство с индексатором).
А вот если пойти дальше по иерархии, то уже никак...
Помогите пожалуйста с этой проблемой или можно просто дать работающий пример.

Спасибо заранее!
Re: COM на C#. Не могу получить объект из коллекции.
От: Vi2 Удмуртия http://www.adem.ru
Дата: 20.12.07 05:23
Оценка:
Здравствуйте, sashar2, Вы писали:

S>Пишу я на C# свой COM. Всё впорядке, но за исключением того, что не могу использовать индексаторы в полной мере. Например: объект myCom.obj[2] или myCom.obj(2) (взависимости от языка) я не могу получить.

S>Хотя выполняю правильно регистрацию, создаю интерфейсы, присваиваю guid, свойству с индексатором в интерфейсе ставлю аттрибут [DispId(0)], как положено. Но это свойство почему-то правильно работает, только если его вызвать его непосредственно у com объекта: myCom[0] или myCom(0) (если в моем интерфейсе конечно объявлено свойство с индексатором).

Это правильно — индексатор работает с объектом.

S>А вот если пойти дальше по иерархии, то уже никак...


Куда дальше? Сделать myCom.obj[2] как (myCom.obj)[2]? Для этого объект myCom.obj должен в свою очередь обладать индексатором.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: COM на C#. Не могу получить объект из коллекции.
От: sashar2  
Дата: 20.12.07 11:15
Оценка:
Vi2>Куда дальше? Сделать myCom.obj[2] как (myCom.obj)[2]? Для этого объект myCom.obj должен в свою очередь обладать индексатором.

Он и обладает индексатором, с этим всё впорядке. Из C# все работает.
Re[3]: COM на C#. Не могу получить объект из коллекции.
От: sashar2  
Дата: 21.12.07 04:33
Оценка:
Приведите пожалуйста работающий пример, где можно было бы обратиться через индексатор к свойству ком объекта (как я уже приводил пример myCom.obj(2)). Очень нужно...
Re[4]: COM на C#. Не могу получить объект из коллекции.
От: Vi2 Удмуртия http://www.adem.ru
Дата: 21.12.07 12:17
Оценка:
Здравствуйте, sashar2, Вы писали:

S>Приведите пожалуйста работающий пример, где можно было бы обратиться через индексатор к свойству ком объекта (как я уже приводил пример myCom.obj(2)). Очень нужно...


Непонятны затруднения. Может, тебя интересует myCom(2).obj — обращение к свойству "obj" объекта myCom(2)?
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[5]: COM на C#. Не могу получить объект из коллекции.
От: sashar2  
Дата: 21.12.07 13:40
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, sashar2, Вы писали:


S>>Приведите пожалуйста работающий пример, где можно было бы обратиться через индексатор к свойству ком объекта (как я уже приводил пример myCom.obj(2)). Очень нужно...


Vi2>Непонятны затруднения. Может, тебя интересует myCom(2).obj — обращение к свойству "obj" объекта myCom(2)?


Затруднения в том, что не получается в другом языке создать ком объект и получить объект из коллекции, как например — ком объект — MyCom, у него есть коллекция Obj, к элементу этой коллекции я не могу обратиться как MyCom.Obj(2), только если MyCom.Obj.Item(2). Хотя если у самого ком объекта есть коллекция (например обратиться как MyCom[2]), то все получается.
Если не затруднит, то пожалуйста приведите пример. Он всего занимает несколько строк, но я пойму в чем я ошибался.
Re[6]: COM на C#. Не могу получить объект из коллекции.
От: sashar2  
Дата: 21.12.07 16:09
Оценка:
В С++ я получал из указателя на интерфейс ком объект ком, таким образом там все работало. В C# же такое сделать, как я понимаю (про это была уже такая тема) сделать нельзя:
http://rsdn.ru/Forum/message/124975.flat.aspx
Автор: SCS
Дата: 04.11.02

Поэтому интересно, каким образом это обойти.
Re[5]: COM на C#. Не могу получить объект из коллекции.
От: bnk СССР http://unmanagedvisio.com/
Дата: 23.12.07 19:01
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, sashar2, Вы писали:


S>>Приведите пожалуйста работающий пример, где можно было бы обратиться через индексатор к свойству ком объекта (как я уже приводил пример myCom.obj(2)). Очень нужно...


Vi2>Непонятны затруднения. Может, тебя интересует myCom(2).obj — обращение к свойству "obj" объекта myCom(2)?


Тоже стало интересно.
В чем дело не знаю, но попробую объяснить проблему. Если я правильно понял, то имеем

namespace ClassLibrary1
{
    public class Class1
    {
        public ArrayList objs
        {
            get
            {
                return new ArrayList(new object[] { "a", "b", "c"});
            }
        }
    }
}

теперь используем это (VB script):
Set c = CreateObject("ClassLibrary1.Class1")

a = c.objs.Item(1)        ' <- так работает

a = c.objs(1)             ' <- так не работает (*) - "недопустимое число аргументов или присвоение свойства"

Set objs = c.objs
a = objs(1)               ' <- так работает

for each (obj in c.objs)  ' <- так тоже работает

Вопрос — почему (*) не работает и как сделать чтобы работала?
Re[6]: COM на C#. Не могу получить объект из коллекции.
От: Vi2 Удмуртия http://www.adem.ru
Дата: 24.12.07 07:58
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>a = c.objs.Item(1) ' <- так работает

bnk>a = c.objs(1) ' <- так не работает (*) — "недопустимое число аргументов или присвоение свойства"

Потому что это вызов у объекта "c" метода "objs" с параметром "1". Скорее всего, нужно в этом методе предусмотреть необязательный параметр и отрабатывать его соответственно: если есть, то возвращать i-ый объект коллекции, если нет, то возвращать саму коллекцию. Если это неприемлимо, то тогда и решения нет.

PS
Кстати, те языки, которые понимают Библиотеку типов, должны правильно разруливать вызовы и должны отработать по сценарию (c.objs)(1).
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[8]: COM на C#. Не могу получить объект из коллекции.
От: Vi2 Удмуртия http://www.adem.ru
Дата: 24.12.07 10:33
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>IMHO тут должен быть какой-то трюк (для экселя вот это например вполне работает):

bnk>Тот же VB script:
bnk>Set e = CreateObject("Excel.Application")
bnk>e.Workbooks.Add
bnk>Set a = e.Worksheets(1)  ' <- все ОК (хотя библиотеки типов нет)

bnk>Set c = CreateObject("ClassLibrary1.Class1")
bnk>Set a = c.objs(1) ' <- Oops !

bnk>Кажется Excel добавляет к коллекции метод _Default(VARIANT) c DispId=0

Это не имеет значение, поскольку для ClassLibrary1.Class1 его метод "objs" можно реализовать так, чтобы он возвращал стандартную коллекцию, у которой тоже есть свойство по умолчанию, или же задать у коллекции явно признак Default.

Есть два объяснения феномену.
1) При вызове e.Worksheets(1) по схеме "свойство-с-параметром" через IDispatch::Invoke разработчики сервера Excel часто встречались с такой ситуацией (с таким обращением к свойству) и реализовали специальную обработку при наличии параметра.

2) При вызове e.Worksheets(1) скрипт (управляющая среда) получает ошибку с кодом "Неверное количество аргументов" и редуцирует вызов до e.Worksheets с последующим обращением к дефолтному методу полученного(ых) объекта(ов).

Видно, что реализуется объяснение 1.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[9]: COM на C#. Не могу получить объект из коллекции.
От: bnk СССР http://unmanagedvisio.com/
Дата: 24.12.07 10:55
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Есть два объяснения феномену.

Vi2>1) При вызове e.Worksheets(1) по схеме "свойство-с-параметром" через IDispatch::Invoke разработчики сервера Excel часто встречались с такой ситуацией (с таким обращением к свойству) и реализовали специальную обработку при наличии параметра.

Vi2>2) При вызове e.Worksheets(1) скрипт (управляющая среда) получает ошибку с кодом "Неверное количество аргументов" и редуцирует вызов до e.Worksheets с последующим обращением к дефолтному методу полученного(ых) объекта(ов).


Посмотрел TLB excel-я, там _Default — это проперти с параметром VARIANT и DispId=0

Так что пример должен разбираться как
e.Worksheets._Default(idx)

Но неясно как это сделать на C#.
Т.е. чтобы заработало надо примерно вот это (IDL), но на C# это похоже невозможно? (т.е. propget c параметром)?

interface IWorksheets : IDispatch 
{
  // ля-ля-ля

    [propget, id(-4)]
    HRESULT _stdcall _NewEnum([out, retval] IUnknown** RHS);

    [propget, id(0)]
    HRESULT _stdcall _Default(
                    [in] VARIANT Index, 
                    [out, retval] IDispatch** RHS);
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.