Работа с COM-объектом через "точку"
От: Versus-13  
Дата: 17.05.06 08:49
Оценка: :))) :)
В Delphi, при работе с COM-объектом можно обращаться к свойствам и методам объекта через точку. На VC++ соответственно стандарт — через GetIDOfName и Invoke.
Через это вопрос: Можно ли на VC++ получать доступ к свойствам и методам объекта через точку.
Re: Работа с COM-объектом через "точку"
От: algol Россия about:blank
Дата: 17.05.06 11:52
Оценка: 7 (1)
Здравствуйте, Versus-13, Вы писали:

V1>В Delphi, при работе с COM-объектом можно обращаться к свойствам и методам объекта через точку. На VC++ соответственно стандарт — через GetIDOfName и Invoke.

V1>Через это вопрос: Можно ли на VC++ получать доступ к свойствам и методам объекта через точку.

Можно, но не через точку, а через -> , см. директиву #import
Автор(ы): Игорь Ткачёв
Дата: 9.03.2001

В данной статье приводится объяснение работы директивы #import
компилятора Visual C++ и даны примеры её использования с
MS Word, MS Excel, ADO DB и ActiveX Control.
.
Re[2]: Работа с COM-объектом через "точку"
От: George Seryakov Россия  
Дата: 17.05.06 13:53
Оценка:
Здравствуйте, algol, Вы писали:

V1>>В Delphi, при работе с COM-объектом можно обращаться к свойствам и методам объекта через точку. На VC++ соответственно стандарт — через GetIDOfName и Invoke.

V1>>Через это вопрос: Можно ли на VC++ получать доступ к свойствам и методам объекта через точку.

A>Можно, но не через точку, а через -> , см. директиву #import
Автор(ы): Игорь Ткачёв
Дата: 9.03.2001

В данной статье приводится объяснение работы директивы #import
компилятора Visual C++ и даны примеры её использования с
MS Word, MS Excel, ADO DB и ActiveX Control.
.


Похоже, он спрашивает про позднее связывание.

Так вот, на VC++ позднего связывания нет. А есть только методы IDispatch, как совершенно справедливо отмечалось, Invoke() и все такое.

А #import, это для раннего связывания.
GS
Re: Работа с COM-объектом через "точку"
От: George Seryakov Россия  
Дата: 17.05.06 18:37
Оценка: +1
Не вижу, кстати, причин для хохотушек. Ничего не мешает оборудовать обработку библиотеки типов в #import врапперами, реализующими обертки позднего связывания. Другое дело, что это не сделано, но уровень вмешательства в язык не намного больший чем для #import раннего связывания.

Кстати, может понадобиться всяким людям, пишущим аддоны для экселя, или где там связывание только позднее. Это я шароварщикам говорю.
GS
Re[3]: Работа с COM-объектом через "точку"
От: Vi2 Удмуртия http://www.adem.ru
Дата: 18.05.06 05:01
Оценка:
Здравствуйте, George Seryakov, Вы писали:

GS>Так вот, на VC++ позднего связывания нет. А есть только методы IDispatch, как совершенно справедливо отмечалось, Invoke() и все такое.

GS>А #import, это для раннего связывания.

Так методы IDispatch — это и есть пресловутое "позднее связывание". Их, правда, существует два варианта — вызов по имени (GetIDsOfNames+Invoke) и вызов по ID (Invoke). Так вот при #import используется второй вариант. Но это также позднее связывание.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Работа с COM-объектом через "точку"
От: Аноним  
Дата: 18.05.06 08:02
Оценка:
Здравствуйте, George Seryakov, Вы писали:

GS>Не вижу, кстати, причин для хохотушек. Ничего не мешает оборудовать обработку библиотеки типов в #import врапперами, реализующими обертки позднего связывания. Другое дело, что это не сделано, но уровень вмешательства в язык не намного больший чем для #import раннего связывания.


GS>Кстати, может понадобиться всяким людям, пишущим аддоны для экселя, или где там связывание только позднее. Это я шароварщикам говорю.

Там и так позднее связывание через IDispatch, а в С++ кто в своем уме будет пользоватся поздним связыванием, если можна все делать через раннее связывание.
Re[3]: Работа с COM-объектом через "точку"
От: pomozoff  
Дата: 18.05.06 08:05
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Там и так позднее связывание через IDispatch, а в С++ кто в своем уме будет пользоватся поздним связыванием, если можна все делать через раннее связывание.

А вот если нельзя через раннее: нету библиотеки типов для стороннегно COM-объекта к примеру ...
Re[4]: Работа с COM-объектом через "точку"
От: Left2 Украина  
Дата: 18.05.06 08:21
Оценка:
Vi2>Так методы IDispatch — это и есть пресловутое "позднее связывание". Их, правда, существует два варианта — вызов по имени (GetIDsOfNames+Invoke) и вызов по ID (Invoke). Так вот при #import используется второй вариант. Но это также позднее связывание.

#import никак не оборачивает вызовы Invoke. Смысл выделенного непонятен. Может, ты путаешь с MFC? Её визард генерил обёртки именно так как ты рассказываешь...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Работа с COM-объектом через "точку"
От: Left2 Украина  
Дата: 18.05.06 08:23
Оценка: 1 (1)
А>Здравствуйте, George Seryakov, Вы писали:

GS>>Не вижу, кстати, причин для хохотушек. Ничего не мешает оборудовать обработку библиотеки типов в #import врапперами, реализующими обертки позднего связывания. Другое дело, что это не сделано, но уровень вмешательства в язык не намного больший чем для #import раннего связывания.


В этом плане очень сильно помогает ATL с его CComPtr<IDispatch>. Код получается — ну почти как на VB

GS>>Кстати, может понадобиться всяким людям, пишущим аддоны для экселя, или где там связывание только позднее. Это я шароварщикам говорю.

А>Там и так позднее связывание через IDispatch, а в С++ кто в своем уме будет пользоватся поздним связыванием, если можна все делать через раннее связывание.

Я буду. Будет куда меньше проблем при переползании с одной версии Office на другую. А по скорости разница не заметна, ибо всё равно out-of-proc сервер.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Работа с COM-объектом через "точку"
От: Аноним  
Дата: 18.05.06 08:35
Оценка:
Здравствуйте, Left2, Вы писали:

L>Я буду. Будет куда меньше проблем при переползании с одной версии Office на другую. А по скорости разница не заметна, ибо всё равно out-of-proc сервер.


А что за проблема?

Так будет у тебя еще больше проблем, так как через Invoke ты не определишь на этапе компиляции что где то там параметры поменялись.
Re[5]: Работа с COM-объектом через "точку"
От: Vi2 Удмуртия http://www.adem.ru
Дата: 18.05.06 08:55
Оценка: 30 (3)
Здравствуйте, Left2, Вы писали:

L>#import никак не оборачивает вызовы Invoke. Смысл выделенного непонятен. Может, ты путаешь с MFC? Её визард генерил обёртки именно так как ты рассказываешь...


Если #import обнаруживает custom или dual интерфейс, то формируется вызовы через vtable, т.е. осуществляя раннее связывание:
    BSTR _result;
    HRESULT _hr = get_Name(&_result);
    if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
    return _bstr_t(_result, false);

Если #import обнаруживает dispinterface (редкость, согласен), то формируется вызов через Invoke, т.е. осуществляя позднее связывание:
    VARIANT _result;
    _com_dispatch_method(this, 0x225, DISPATCH_METHOD, VT_VARIANT, (void*)&_result, L"\x080c", &Index);
    return _variant_t(_result, false);
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[6]: Работа с COM-объектом через "точку"
От: Left2 Украина  
Дата: 18.05.06 09:07
Оценка:
Vi2>Если #import обнаруживает dispinterface (редкость, согласен), то формируется вызов через Invoke, т.е. осуществляя позднее связывание:

Вот уж век живи — век учись... Спасибо за информацию!
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Работа с COM-объектом через "точку"
От: Left2 Украина  
Дата: 18.05.06 09:07
Оценка:
А>А что за проблема?

Проблема в том что ObjectModel меняется от офиса к офису. И насколько помню частенько методы в интерфейсы добавляются "в середину" что вызывает потрясающие по эффекту неожиданности проблемы в run-time. А вот DISPID остаются старыми.

А>Так будет у тебя еще больше проблем, так как через Invoke ты не определишь на этапе компиляции что где то там параметры поменялись.

А вот параметры менются редко. Куда чаще добавляются новые функции.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Работа с COM-объектом через "точку"
От: algol Россия about:blank
Дата: 18.05.06 10:46
Оценка:
Здравствуйте, Left2, Вы писали:

А>>Там и так позднее связывание через IDispatch, а в С++ кто в своем уме будет пользоватся поздним связыванием, если можна все делать через раннее связывание.


L>Я буду. Будет куда меньше проблем при переползании с одной версии Office на другую. А по скорости разница не заметна, ибо всё равно out-of-proc сервер.


Хотел бы я посмотреть, как вы перепишете на VC++ тысяч 10 строк VBA через IDispatch->Invoke().
Re[5]: Работа с COM-объектом через "точку"
От: Аноним  
Дата: 18.05.06 11:02
Оценка:
Здравствуйте, algol, Вы писали:

A>Хотел бы я посмотреть, как вы перепишете на VC++ тысяч 10 строк VBA через IDispatch->Invoke().


По идее имелось ввиду, что как то автоматом можна сгенерить враппер который будет делать эти вызовы через Invoke.
Re[5]: Работа с COM-объектом через "точку"
От: Left2 Украина  
Дата: 18.05.06 12:08
Оценка:
L>>Я буду. Будет куда меньше проблем при переползании с одной версии Office на другую. А по скорости разница не заметна, ибо всё равно out-of-proc сервер.

A>Хотел бы я посмотреть, как вы перепишете на VC++ тысяч 10 строк VBA через IDispatch->Invoke().


10 тысяч строк и с нуля-то написать тяжеловато, не находишь?
А писать буду примерно так:

CComPtr<IDispatch> spObj;
CComVariant vtName;
spObj.GetProperty("Name", vtName);

spObj.Invoke0("MethodWOParams");
spObj.Invoke1("MethodWith1Param", CComVariant(L"Paramter1"));


И далее в том же духе.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Работа с COM-объектом через "точку"
От: algol Россия about:blank
Дата: 18.05.06 13:05
Оценка:
Здравствуйте, Left2, Вы писали:

L>10 тысяч строк и с нуля-то написать тяжеловато, не находишь?


Нахожу, но VBA я упомянул, потому что проще сначала отладить алгоритм там, а потом уже переносить на C++. А кучу строк можно записать через Macro Recorder.

L>А писать буду примерно так:

L>И далее в том же духе.

Для примера возьмем вот такую простую строчку на VBA:
lastRow = Cells.Find("*", Range("A1"), xlFormulas, , xlByRows, xlPrevious).Row


При использовании #import это будет соответствовать:
int lastRow = m_pApplication->Cells->Find("*", (IDispatch*)m_pApplication->Range->Item["A1"], xlFormulas, vtMissing, xlByRows, xlPrevious)->Row;


Сколько строк это займет при использовании Invoke()? Здесь только вызовов 5 штук. Не забудьте еще, что все параметры придется конвертить в VARIANT и обратно. А все параметры функций вам придется искать в хелпе, потому что никакого Intellisence не будет. А потом будете долго бодаться с ошибками типа Invalid Parameter. В общем, если вы попытаетесь написать вручную через Invoke() что-нибудь сложнее, чем "Hello, World!", то флаг вам в руки.
Re[7]: Работа с COM-объектом через "точку"
От: Константин Л.  
Дата: 18.05.06 14:06
Оценка:
Здравствуйте, algol, Вы писали:

[]

Я в одном проекте использовал CComPtr<IDispatch>. Нужно было вызвать у офисного документа буквально пару методов/свойств, а импортить вордовый typelib не хотелось. Если надо дурнуть свойство или метод с малым кол-ом параметров — то в самый раз.
Re[4]: Работа с COM-объектом через "точку"
От: George Seryakov Россия  
Дата: 18.05.06 14:26
Оценка:
Здравствуйте, Vi2, Вы писали:

GS>>Так вот, на VC++ позднего связывания нет. А есть только методы IDispatch, как совершенно справедливо отмечалось, Invoke() и все такое.

GS>>А #import, это для раннего связывания.

Vi2>Так методы IDispatch — это и есть пресловутое "позднее связывание". Их, правда, существует два варианта — вызов по имени (GetIDsOfNames+Invoke) и вызов по ID (Invoke). Так вот при #import используется второй вариант. Но это также позднее связывание.


Ну да. Но я про то, что это позднее связывание осуществляется ручками благодарного за это программиста, а не средствами языка. У VC++ позднего связывания нет.
GS
Re[6]: Работа с COM-объектом через "точку"
От: Left2 Украина  
Дата: 18.05.06 14:53
Оценка: 4 (1)
Во как интересно — оказывается, у #import есть аттрибут no_dual_interfaces — он позволяет все дуальные интерфейсы дёргать только через диспатч.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.