Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

СОМ объекты

11
19 октября 2007 года
oxotnik333
2.9K / / 03.08.2007
Посдскажите плзкак правильно работать с СОМ объектами:

CComPtr<IHTMLImgElement>spImgEl; // указатель на интерфейс
CComPtr<IDispatch>spDisp; // --||--

for (long i=0; i<Img_ln; i++)
{
spImgEl = NULL; // обнуление указателя
spDisp = NULL;
ind.lVal = i;
spImgCol->item(ind,ind, &spDisp);
spDisp->QueryInterface(IID_IHTMLImgElement, (LPVOID*)&spImgEl);
spImgEl->get_src(&src);
}

вопрос в следующем: можно ли до начала цикла определить указатели на интерфейс а в теле цикла их обнулять? (в принципе так работает)
не повлечет ли это потер. самого объекта для автоматического Release();?
240
19 октября 2007 года
aks
2.5K / / 14.07.2006
Цитата: oxotnik333
Посдскажите плзкак правильно работать с
вопрос в следующем: можно ли до начала цикла определить указатели на интерфейс а в теле цикла их обнулять? (в принципе так работает)


А зачем их обнулять? По сути это же не указатель, а объект представляющий указатель на COM объект. И есть возможность проверять его валидность и так.

Кстати получить spImgEl (над названиями не мешело бы подумать), можно и с помощью объекта типа CComQIPtr<IHTMLImgElement, &IID_IHTMLImgElement>. Его класс специально для автоматического QueryInterface сделан.

11
19 октября 2007 года
oxotnik333
2.9K / / 03.08.2007
1.
Цитата:
(над названиями не мешело бы подумать)


а что в названии не так?
2. Обнулять нужно, т.к. он не раз используется в коде, не только в цикле.
3. CComQIPtr<IHTMLImgElement, &IID_IHTMLImgElement>. автоматом QueryInterface не подходит т.к. делается через IDispatch.
ПЫСЫ: а ответа на вопрос не прозвучало... :(

240
19 октября 2007 года
aks
2.5K / / 14.07.2006
Цитата: oxotnik333
1.
а что в названии не так?


Неинформативное

Цитата: oxotnik333

2. Обнулять нужно, т.к. он не раз используется в коде, не только в цикле.


Ну и что? при чем тут присвоение NULL внутреннему указателю? Проверить можно из без этого. А удалять вызовом Release().

Насчет присвоения - ничего плохого видимо не будет. Внутненний указатель просто станет NULL.

Цитата: oxotnik333

3. CComQIPtr<IHTMLImgElement, &IID_IHTMLImgElement>. автоматом QueryInterface не подходит т.к. делается через IDispatch.


Дык на сколько я помню CComQIPtr для того и создан чтобы автоматом получать объект например из того же IDispatch. Просто он сам вызывает QueryInterface.

11
19 октября 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата:
Неинформативное.


spImgEl - "service-pointer-Imading-Element"

Цитата:
А удалять вызовом Release()


Release() автоматический при такой конструкции: CComPtr<...>spCom;

Цитата:
Дык на сколько я помню CComQIPtr для того и создан чтобы автоматом получать объект например из того же IDispatch. Просто он сам вызывает QueryInterface.


все дело в том что сначала методом item(...) передается в IDispatch, а затем уже в IHTMLImgElement.

вопрос: не потеряется ли "предыдущий" относительно цикла указатель для авто - Release(), если идет обнуление его в последующем шаге цикла?

240
21 октября 2007 года
aks
2.5K / / 14.07.2006
Цитата: oxotnik333
spImgEl - "service-pointer-Imading-Element"


Ну и. Я же говорю неинформативное. Я к тому, что невнятные сокращения не прибваляют информативности к названию, хотя мне впринципе оно и было понятно )

Цитата: oxotnik333

Release() автоматический при такой конструкции: CComPtr<...>spCom;


Ну автоматический Release() не отменяет ручного приминения (именно метода класса CComPtr .Release(), а ->Release() от интерфейса. )

Цитата: oxotnik333

все дело в том что сначала методом item(...) передается в IDispatch, а затем уже в IHTMLImgElement.


Вот в IHTMLImgElement как раз и можно в частности присваивать IDispatch через CComQIPtr

Цитата: oxotnik333

вопрос: не потеряется ли "предыдущий" относительно цикла указатель для авто - Release(), если идет обнуление его в последующем шаге цикла?


Ну на самом деле переприсваивание объекта без Release() не хорошо. И NULL тут впринципе то и не нужен.

11
22 октября 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата:
Ну автоматический Release() не отменяет ручного приминения (именно метода класса CComPtr .Release(), а ->Release() от интерфейса. )


компилятор ругается, и говорит что Release() недоступен для СComPtr
Release() - автоматический!!!

Цитата:
Ну на самом деле переприсваивание объекта без Release() не хорошо. И NULL тут впринципе то и не нужен.


NULL нужен, т.к. при итеррации в цикле если указатель не NULL тогда на QueryInterface AV вылетает...

Цитата:
Я же говорю неинформативное. Я к тому, что невнятные сокращения не прибваляют информативности к названию, хотя мне впринципе оно и было понятно ).


если понятно, то какое же оно не информативное? или писать полностью?


ПЫСЫ: я разобрался в реализации CComPtr - авто-Release() вызывается тогда когда указатель в NULL превращается, следовательно если при итеррции предыдущее значение обнулять, тогда происходит Release() объекта.

11
22 октября 2007 года
oxotnik333
2.9K / / 03.08.2007
вот реализация Release() CComPtr:

ATLINLINE ATLAPI_(IUnknown*) AtlComPtrAssign(__deref_out_opt IUnknown** pp, __in_opt IUnknown* lp)
{
if (pp == NULL)
return NULL;

if (lp != NULL)
lp->AddRef();
if (*pp)
(*pp)->Release();
*pp = lp;
return lp;
}
т.е. если указатель NULL, удаляется объект.
240
22 октября 2007 года
aks
2.5K / / 14.07.2006
Цитата: oxotnik333
компилятор ругается, и говорит что Release() недоступен для СComPtr


Да конечно )) Покажи код как вызываешь.


Цитата: oxotnik333

NULL нужен, т.к. при итеррации в цикле если указатель не NULL тогда на QueryInterface AV вылетает...


Именно для того чтобы не вылетал я и говорил надо делать Release()

Цитата: oxotnik333

если понятно, то какое же оно не информативное? или писать полностью?


Ну оно понятно, потому что я щас догадался из контектса. А мог бы и не быть догадливым. Вобщем конвенции нэйминга это конечно отдельная тема, но вот представь ты через пару лет этот код будешь смотреть - сразу все поймешь?

Цитата: oxotnik333

ПЫСЫ: я разобрался в реализации CComPtr - авто-Release() вызывается тогда когда указатель в NULL превращается


Ну скорее всего так и есть, я не помню уже, но такое поведение вполне логично. Потому и не падает. )

11
22 октября 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата:
Да конечно )) Покажи код как вызываешь


Цитата:
Именно для того чтобы не вылетал я и говорил надо делать Release()



CComPtr<IDispatch>spDisp;
...
...
...
CComPtr<IHTMLElement>spEl;
spDisp->QueryInterface(IID_IDispatch, (LPVOID*)&spEl);
BSTR tag;
spEl->get_tagName(&tag);
spEl->Release(); // вот тут компилятор говорит что для CComPtr метод Release() is not accessible

ПЫСЫ: я ж ниче не придумываю, говорю как есть

240
22 октября 2007 года
aks
2.5K / / 14.07.2006
Цитата: oxotnik333

spEl->Release(); // вот тут компилятор говорит что для CComPtr метод


Все правильно он говорит. ))
Надо просто писать spEl.Release(); а не spEl->Release(); я же говорил.
Чтобы вызвать именно метод Release объекта CComPtr, а не приватный метод итерфейса IUnknown.

240
22 октября 2007 года
aks
2.5K / / 14.07.2006
Кстати раз уж юзаешь ATL-ные обертки над COM интерфейсами, там же есть полезные Обертки над BSTR и VARIANT: CComBSTR и CComVariant.
Удобные, и с переопределенными операторами приисваивания, сравнения и т.п.
11
22 октября 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата:
Кстати раз уж юзаешь ATL-ные обертки над COM интерфейсами, там же есть полезные Обертки над BSTR и VARIANT: CComBSTR и CComVariant.
Удобные, и с переопределенными операторами приисваивания, сравнения и т.п.


спасибо, учту :)
к стати, spEl.Release(); тоже работает, за это отдельное спасибо!
(хотя наверно и в моем варинте тоже все правильно работало)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог