Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2005.07.25;
Скачать: [xml.tar.bz2];

Вниз

C++ Абстрактность неабстрактоного класса   Найти похожие ветки 

 
Juice ©   (2005-07-04 12:45) [0]

Знаю что тут много хорошо знающих c++, поэтому извините за тематику. С++ Builder.
С помощью мастера File/New/ActiveX/Automation Object  я создал  класс TMyOutlookEventsImpl. При попытке создания экземпляра этого класса ( EventInterface = new TMyOutlookEventsImpl ) выдается ошибка :
[C++ Error] Unit1.cpp(30): E2352 Cannot create instance of abstract class "TMyOutlookEventsImpl"
[C++ Error] Unit1.cpp(113): E2353 Class "TMyOutlookEventsImpl" is abstract because of "__stdcall TMyOutlookEventsImpl::AddRef() = 0"

Насколько я понимаю , мне самостоятельно надо определить функцию-член AddRef ? Странно конечно, ведь она должна быть определена в билдеровских библиотеках ...
Я попытался обьявить ее так :
virtual ULONG STDMETHODCALLTYPE TMyOutlookEventsImpl::AddRef()
{
 //AddRef();
}
Проблема осталась. И в чем смысл всей этой билдеровской жути ? Я перевожу код по обработке сообщений ole-сервера из Delphi, где все было создано аналогичным образом и работает отлично.


 
Ega23 ©   (2005-07-04 13:59) [1]

Могу ошибаться, но в С++ вроде как запрещено создание инстансов абстрактных классов. Более того, класс считается абстрактным, если у него есть хотя бы один абстрактный метод.
Попробуй создать потомка от своего класса и переопредели все абстрактные методы предка.


 
wicked ©   (2005-07-04 14:36) [2]

> Juice ©
попробуй в имплементации класса вызывать методы предка - ты же наследуешься от IUnknown...
или, как более жизнеспособный вариант - реализовать reference count самому (AddRef(), Release(), QueryInterface())...

ЗЫ почему из изящной COM сделали такое страшилище (ATL) - ума не приложу... но комплекс неполноценности гложет нещадно... ;)

> Ega23 ©   (04.07.05 13:59) [1]
не ошибся - абстрактные инстансы нигде не вольно создавать... а поинтеры на них - сколько угодно... на том весь COM для си++ держится...


 
Juice ©   (2005-07-04 18:25) [3]

Спасибо, так оно и было, унаследовал класс, определил три этих метода - заработало. Теперь другая проблема -
Есть такой код:
 

Variant oApp, oNs1;
oApp = CreateOleObject("outlook.application");
oNs1  = oApp.OleFunction("GetNameSpace", "MAPI");

IConnectionPointContainer * oContain = dynamic_cast<IConnectionPointContainer*>( oNs1.OlePropertyGet("SyncObjects").OleFunction("Item",1) ); // Вот тут ошибка, что мол каст невозможен

Но как преобразовать вариант в IConnectionPointContainer* ? Мне дальше по ходу программы нужно работать с Item именно как с IConnectionPointContainer.


 
Ломброзо ©   (2005-07-04 18:37) [4]

Juice ©   (04.07.05 18:25)
Спасибо, так оно и было, унаследовал класс, определил три этих метода - заработало. Теперь другая проблема -
Есть такой код:


Variant oApp, oNs1;
oApp = CreateOleObject("outlook.application");
oNs1  = oApp.OleFunction("GetNameSpace", "MAPI");

IConnectionPointContainer * oContain = dynamic_cast<IConnectionPointContainer*>( oNs1.OlePropertyGet("SyncObjects").OleFunction("Item",1) ); // Вот тут ошибка, что мол каст невозможен

Но как преобразовать вариант в IConnectionPointContainer* ? Мне дальше по ходу программы нужно работать с Item именно как с IConnectionPointContainer.


фффФФФфф. Всё мучаетесь? Ню-ню.

Вариант 1.
QueryInterface"ом опросить этот Ваш итем на IConnectionPointContainer

IDispatch *pDisp = oNs1.OlePropertyGet("SyncObjects").OleFunction("Item",1);
IConnectionPointContainer *pContainer = null;
HRESULT hr = pDisp->QueryInterface(__uuidof(IConnectionPointContainer), (void**)&pContainer);

анализируем hr и проверяем pContainer на null. Далее аналогично цепочке требуем IConnectionPoint и т.д.

Блин, всё это в MSDN есть.

2. Я уже упоминал темплейт IDispEventImpl<>. В этом случае вообще всё просто: включаем ATL, пишем класс, который подсовываем этому темплейту, реализуем методы-колбэки при помощи ATL-ных макросов. Пример не дам, писал давно и ничего без MSDN не вспомню.

--------
DMJS 0.6 | http://dmjsclient.narod.ru


 
Ломброзо ©   (2005-07-04 18:41) [5]

Поцказка: у Variant должно быть поле pdispVal. Которое суть IDispatch. не знаю, как у борландовой реализации, но в ATL есть три класса: VARIANT, _variant_t и CComVariant, во всех трёх имеется способ достучаться до IDispatch.


 
Ломброзо ©   (2005-07-04 18:49) [6]

В общем, дуйте на msdn.microsoft.com, поиск по ключевым словам BEGIN_SINK_MAP, END_SINK_MAP, SINK_ENTRY, IDispEventImpl


 
Juice ©   (2005-07-04 19:27) [7]


> Блин, всё это в MSDN есть.

Тема очень сложная, пробовал читать, очень сложно что-то понять.


>
> 2. Я уже упоминал темплейт IDispEventImpl<>. В этом случае
> вообще всё просто: включаем ATL, пишем класс, который подсовываем
> этому темплейту, реализуем методы-колбэки при помощи ATL-ных
> макросов. Пример не дам, писал давно и ничего без MSDN не
> вспомню.

Я с ATL никогда не работал, боюсь что это еще сложнее будет, тем более что проблема уже почти решена.

Я воспользовался вашей подсказкой и программа компильнулась (ура!)
Однако, осталась последняя, как мне кажется, проблема: ничего не происходит. Вот весь значимый код:


 IConnectionPoint* ESink;

 oApp = CreateOleObject("outlook.application");
 oNs  = oApp.OleFunction("GetNameSpace", "MAPI");

 IDispatch *pDisp = oNs.OlePropertyGet("SyncObjects").OleFunction("Item",1);
 IConnectionPointContainer *pContainer = NULL;
 HRESULT hr = pDisp->QueryInterface(__uuidof(IConnectionPointContainer), (void**)&pContainer);

 if (EventInterface == NULL)  EventInterface = new TMyOutlookEvents;

 switch ( pContainer->FindConnectionPoint(Outlook_tlb::DIID_SyncObjectEvents, &ESink)  )
 {
     case S_OK : ShowMessage("OK"); break;
     case E_POINTER : ShowMessage("POINTER"); break;
     case CONNECT_E_NOCONNECTION : ShowMessage("NOCONNECTION"); break;
 }

 IDispatch *pDisp1 = EventInterface;
 IUnknown *pUnkSink = NULL;
 HRESULT hr1 = pDisp1->QueryInterface(__uuidof(IMyOutlookEvents), (void**)&pUnkSink);

 //switch ( ESink->Advise(dynamic_cast<IUnknown*>(EventInterface), FUserID)  )
 switch ( ESink->Advise(pUnkSink, FUserID)  )
 {
     case S_OK  :                      ShowMessage("S_OK"); break;
     case E_POINTER :                  ShowMessage("E_POINTER"); break;
     case CONNECT_E_ADVISELIMIT :      ShowMessage("CONNECT_E_ADVISELIMIT"); break;
     case CONNECT_E_CANNOTCONNECT :    ShowMessage("CONNECT_E_CANNOTCONNECT"); break;
     default : ShowMessage("OTHER!");
 }

 oNs.OlePropertyGet("SyncObjects").OleFunction("Item",1).OleFunction("Start");


Выводится "OK", затем "OTHER!". Получается что проблема с адвайсом ? Но что ж там такое может быть ? Как видите я пробовал получать пердаваемый этой функции интерфейс иначе.


 
Juice ©   (2005-07-04 20:26) [8]

Кажется проблема в том как я реализовал функцию QueryInterface :

HRESULT STDMETHODCALLTYPE TMyOutlookEvents::QueryInterface(REFIID riid, void** ppObj)
{
 if (riid == IID_IUnknown)
 {
   *ppObj = static_cast<IUnknown*>(this);
 }
 else if (riid == IID_IMyOutlookEvents)
 {
   *ppObj = static_cast<IMyOutlookEvents*>(this);
 }
 else
 {
   *ppObj = NULL;
   return E_NOINTERFACE ;
 }
 AddRef();
 return S_OK;
}



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2005.07.25;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.013 c
6-1113717499
07BB:080Dh
2005-04-17 09:58
2005.07.25
Как получить список пользователей локалки.


1-1120926660
Michael5
2005-07-09 20:31
2005.07.25
Подскажите, как код разнести по разным файлам (Unit ам)?


8-1111865107
seregka
2005-03-26 22:25
2005.07.25
TMemoryStream и bitmap


1-1120823676
Still Swamp
2005-07-08 15:54
2005.07.25
Конвертировать строку в varian


14-1119556021
Ломброзо
2005-06-23 23:47
2005.07.25
И снова DMJS Client





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский