не могу поймать исключение _com_error
От: natalka  
Дата: 21.03.02 07:57
Оценка:
Я пишу на VC ActiveX на ATL с поддержкой ISupportError
Генерирую исключение так:
HRESULT MyMetod()
{
...
if (flag) { return S_OK; }
else {
Error("Вознила ошибка!!!");
return E_FAIL;
}}

В клиенте на VC я пытаюсь его ловить так:
...
try {
MyMetod(); }
catch (_com_error &e)
{ MessageBox(e.Description); }

И исключение не перехватывается, хотя и в книжках и в MSDN написано, что должно.
Может я где-то что-то напутала...
Помогите чем можете.
Re: не могу поймать исключение _com_error
От: OlegO Россия http://www.mediachase.ru
Дата: 21.03.02 08:06
Оценка:
Здравствуйте natalka, Вы писали:

N>Я пишу на VC ActiveX на ATL с поддержкой ISupportError

N>Генерирую исключение так:
N>HRESULT MyMetod()
N>{
N>...
N>if (flag) { return S_OK; }
N>else {
N>Error("Вознила ошибка!!!");
N>return E_FAIL;
N>}}

N>В клиенте на VC я пытаюсь его ловить так:

N>...
N>try {
N>MyMetod(); }
N>catch (_com_error &e)
N>{ MessageBox(e.Description); }

N>И исключение не перехватывается, хотя и в книжках и в MSDN написано, что должно.

N>Может я где-то что-то напутала...
N>Помогите чем можете.

В клиенте, ты импортом (#import) подключаешь свой объект?

Это Ptr (обвертка над твоим объектом) полученные при импорте в случае ошибки генерят исключения, а не лично твой объект.

Если импотртом, то с какими параметрами?
С уважением, OlegO.
Re[2]: не могу поймать исключение _com_error
От: natalka  
Дата: 21.03.02 08:19
Оценка:
Здравствуйте OlegO, Вы писали:

OO>В клиенте, ты импортом (#import) подключаешь свой объект?


OO>Это Ptr (обвертка над твоим объектом) полученные при импорте в случае ошибки генерят исключения, а не лично твой объект.


OO>Если импотртом, то с какими параметрами?


я расположила свой ActiveX в диалоговом окне клиента и задала для него переменную, в результате подключились классы моего ActiveX. Больше никаких подключений не делала. Все методы ActiveX работают как надо, кроме исключений.
Re[3]: не могу поймать исключение _com_error
От: OlegO Россия http://www.mediachase.ru
Дата: 21.03.02 08:48
Оценка:
Здравствуйте natalka, Вы писали:

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


OO>>В клиенте, ты импортом (#import) подключаешь свой объект?


OO>>Это Ptr (обвертка над твоим объектом) полученные при импорте в случае ошибки генерят исключения, а не лично твой объект.


OO>>Если импотртом, то с какими параметрами?


N>я расположила свой ActiveX в диалоговом окне клиента и задала для него переменную, в результате подключились классы моего ActiveX. Больше никаких подключений не делала. Все методы ActiveX работают как надо, кроме исключений.


Чтобы понять, что происходит достаточно посмотреть .CPP файл, которые сгенерила студия,
для твоего ActiveX.

В методах идет вызов метода CWnd::InvokeHelper, а он в случае ошибки генерит
исключения COleException если код ошибки равен DISP_E_EXCEPTION, или
COleDispatchException в остальных случаях.

для простоты можешь перехватывать все исключения catch(...)

Если исключения не приходят, значит смотри код ActiveX'а
С уважением, OlegO.
Re[4]: не могу поймать исключение _com_error
От: natalka  
Дата: 21.03.02 09:15
Оценка:
Здравствуйте OlegO, Вы писали:

OO>Чтобы понять, что происходит достаточно посмотреть .CPP файл, которые сгенерила студия,

OO>для твоего ActiveX.

OO>В методах идет вызов метода CWnd::InvokeHelper, а он в случае ошибки генерит

OO>исключения COleException если код ошибки равен DISP_E_EXCEPTION, или
OO>COleDispatchException в остальных случаях.

OO>для простоты можешь перехватывать все исключения catch(...)


OO>Если исключения не приходят, значит смотри код ActiveX'а


когда я по шагам смотрела, что происходит, он мне показывает, что в методе у меня появляется исключение типа COleDispatchException
В другом клиенте я получаю ошибку другим способом (этот приём везде описан):
hr = pInterface->QueryInterface(IID_ISupportErrorInfo,(void**)&pISER);
if(SUCCEEDED(hr))
{
if(SUCCEEDED(pISER->InterfaceSupportsErrorInfo(riid)))
{
IErrorInfo *pEI;
if (SUCCEEDED(GetErrorInfo(NULL,&pEI)))
{
BSTR desc;
pEI->GetDescription(&desc);
char buff[80];
WideCharToMultiByte(CP_ACP,NULL,desc,-1,buff,80,NULL,NULL);
cout << buff << endl;
SysFreeString(desc);
pEI->Release();
}
}
pISER->Release();
}
pInterface->Release();

и там все работает, но мне для простоты написания клиента нужен catch.
Сейчас у меня как раз исключение и ловиться на catch(...), но мне надо конкретно.
Re[5]: не могу поймать исключение _com_error
От: OlegO Россия http://www.mediachase.ru
Дата: 21.03.02 09:30
Оценка: 1 (1)
Здравствуйте natalka, Вы писали:

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


OO>>Чтобы понять, что происходит достаточно посмотреть .CPP файл, которые сгенерила студия,

OO>>для твоего ActiveX.

OO>>В методах идет вызов метода CWnd::InvokeHelper, а он в случае ошибки генерит

OO>>исключения COleException если код ошибки равен DISP_E_EXCEPTION, или
OO>>COleDispatchException в остальных случаях.

OO>>для простоты можешь перехватывать все исключения catch(...)


OO>>Если исключения не приходят, значит смотри код ActiveX'а


N>когда я по шагам смотрела, что происходит, он мне показывает, что в методе у меня появляется исключение типа COleDispatchException

N>В другом клиенте я получаю ошибку другим способом (этот приём везде описан):
N> hr = pInterface->QueryInterface(IID_ISupportErrorInfo,(void**)&pISER);
N> if(SUCCEEDED(hr))
N> {
N> if(SUCCEEDED(pISER->InterfaceSupportsErrorInfo(riid)))
N> {
N> IErrorInfo *pEI;
N> if (SUCCEEDED(GetErrorInfo(NULL,&pEI)))
N> {
N> BSTR desc;
N> pEI->GetDescription(&desc);
N> char buff[80];
N> WideCharToMultiByte(CP_ACP,NULL,desc,-1,buff,80,NULL,NULL);
N> cout << buff << endl;
N> SysFreeString(desc);
N> pEI->Release();
N> }
N> }
N> pISER->Release();
N> }
N> pInterface->Release();

N>и там все работает, но мне для простоты написания клиента нужен catch.

N>Сейчас у меня как раз исключение и ловиться на catch(...), но мне надо конкретно.

А что тебе мешает ловить так

try
{
  ...
}
catch(COleException *e)
{
        char buf[1024];     // For the Try...Catch error message.
        sprintf(buf, "COleException. SCODE: %08lx.", (long)e->m_sc);
        ::MessageBox(NULL, buf, "COleException", MB_SETFOREGROUND | MB_OK);
      }

      catch(COleDispatchException *e)
      {
        char buf[1024];     // For the Try...Catch error message.
        sprintf(buf,
               "COleDispatchException. SCODE: %08lx, Description: \"%s\".",
               (long)e->m_wCode,(LPSTR)(LPCTSTR)e->m_strDescription);
        ::MessageBox(NULL, buf, "COleDispatchException",
                           MB_SETFOREGROUND | MB_OK);
      }

      catch(...)
      {
        ::MessageBox(NULL, "General Exception caught.", "Catch-All",
                           MB_SETFOREGROUND | MB_OK);
      }
С уважением, OlegO.
Re: не могу поймать исключение _com_error
От: Vi2 Удмуртия http://www.adem.ru
Дата: 21.03.02 09:41
Оценка: 2 (1)
Здравствуйте natalka, Вы писали:

N>Я пишу на VC ActiveX на ATL с поддержкой ISupportError

N>Генерирую исключение так:

N>HRESULT MyMetod()
N>{
N>...
N>  if (flag) { return S_OK; }
N>  else { 
N>    Error("Вознила ошибка!!!");
N>    return E_FAIL;
N>}}


Это не генерация ИСКЛЮЧЕНИЯ, а просто возврат нормальной ошибки.

N>В клиенте на VC я пытаюсь его ловить так:

N>...

N>try {
N>  MyMetod(); }
N>catch (_com_error &e)
N>  { MessageBox(e.Description); }


N>И исключение не перехватывается, хотя и в книжках и в MSDN написано, что должно.

N>Может я где-то что-то напутала...
N>Помогите чем можете.

А исключения-то и нет.
Используй smart-пойнтеры, тогда будет исключение при возврате методом кода ошибки:
try {
  activex_ptr -> MyMetod(); }
catch (_com_error &e)
  { MessageBox(e.Description); }
catch (...)
  { MessageBox("..."); }
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[5]: не могу поймать исключение _com_error
От: Admiral Украина  
Дата: 21.03.02 10:00
Оценка:
Здравствуйте natalka, Вы писали:

N> hr = pInterface->QueryInterface(IID_ISupportErrorInfo,(void**)&pISER);

N> if(SUCCEEDED(hr))
N> {
N> if(SUCCEEDED(pISER->InterfaceSupportsErrorInfo(riid)))
N> {
N> IErrorInfo *pEI;
N> if (SUCCEEDED(GetErrorInfo(NULL,&pEI))) <---- Тонкое место
N> {
N> BSTR desc;
N> pEI->GetDescription(&desc);
N> char buff[80];
N> WideCharToMultiByte(CP_ACP,NULL,desc,-1,buff,80,NULL,NULL);
N> cout << buff << endl;
N> SysFreeString(desc);
N> pEI->Release();
N> }
N> }
N> pISER->Release();
N> }
N> pInterface->Release();

Немного не в тему, но все же:

В некоторых случаях GetErrorInfo может возвращать S_OK, но pEI в то же время = NULL. Т.е. информация об ошибке просто теряется. Это случается, если в COM-объекте после вызова функции Error("Bla-bla-bla") сделать какой-то дополнительный вызов COM. Также эта ситуация возможна при вызове удаленного COM-объекта (в COM+ например).
Так что в этот обработчик лучше ввести дополнительную проверку:

hr = pInterface->QueryInterface(IID_ISupportErrorInfo,(void**)&pISER);
if(SUCCEEDED(hr))
{
   if(SUCCEEDED(pISER->InterfaceSupportsErrorInfo(riid)))
   {
      IErrorInfo *pEI;
      if (SUCCEEDED(GetErrorInfo(NULL,&pEI)))
      {
         if(pEI)
         {
            BSTR desc;
            pEI->GetDescription(&desc);
            char buff[80];
            WideCharToMultiByte(CP_ACP,NULL,desc,-1,buff,80,NULL,NULL);
            cout << buff << endl;
            SysFreeString(desc);
            pEI->Release();
         }
      }
   }
   pISER->Release();
}
pInterface->Release();


Удачи!
Re[4]: не могу поймать исключение _com_error
От: natalka  
Дата: 21.03.02 10:15
Оценка:
Здравствуйте OlegO, Вы писали:

OO>Чтобы понять, что происходит достаточно посмотреть .CPP файл, которые сгенерила студия,

OO>для твоего ActiveX.

OO>В методах идет вызов метода CWnd::InvokeHelper, а он в случае ошибки генерит

OO>исключения COleException если код ошибки равен DISP_E_EXCEPTION, или
OO>COleDispatchException в остальных случаях.

OO>для простоты можешь перехватывать все исключения catch(...)


OO>Если исключения не приходят, значит смотри код ActiveX'а


Получилось перехватить catch(COleDispatchException *e), я раньше пробовала — не получалось.
Но начальник всё-равно требует catch(_com_error &e)
Re[5]: не могу поймать исключение _com_error
От: Андрей Россия  
Дата: 21.03.02 10:20
Оценка:
Здравствуйте natalka, Вы писали:

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


OO>>Чтобы понять, что происходит достаточно посмотреть .CPP файл, которые сгенерила студия,

OO>>для твоего ActiveX.

OO>>В методах идет вызов метода CWnd::InvokeHelper, а он в случае ошибки генерит

OO>>исключения COleException если код ошибки равен DISP_E_EXCEPTION, или
OO>>COleDispatchException в остальных случаях.

OO>>для простоты можешь перехватывать все исключения catch(...)


OO>>Если исключения не приходят, значит смотри код ActiveX'а


N>Получилось перехватить catch(COleDispatchException *e), я раньше пробовала — не получалось.

N>Но начальник всё-равно требует catch(_com_error &e)

Что-то я не пойму, ты на чем пишешь, сдается мне, что на MFC. COleDispatchException — это MFC-шное исключение, а это форум по ATL/WTL.
Re[5]: не могу поймать исключение _com_error
От: OlegO Россия http://www.mediachase.ru
Дата: 21.03.02 10:35
Оценка:
Здравствуйте natalka, Вы писали:

N>Получилось перехватить catch(COleDispatchException *e), я раньше пробовала — не получалось.

N>Но начальник всё-равно требует catch(_com_error &e)

Вариант a (Для тупых начальников):
Тогда эмулирой, это в классе, что сгенерил VS,
а именно в методах, перехватывай исключение COleDispatchException и затем, генери свое исключение
_com_error и его спокой-но ловив у себя .

Вариант б. Через импорт импортировать интерфейс, и после этого работать с ним.
Ну тогда в ручную придется создавать контрол и размещать его на диалоге.

PS Какая разница как получить ошибку, главное узнать что она произошла.
С уважением, OlegO.
Re[2]: не могу поймать исключение _com_error
От: natalka  
Дата: 21.03.02 11:34
Оценка:
Здравствуйте Vi2, Вы писали:


Vi2>А исключения-то и нет.

Vi2>Используй smart-пойнтеры, тогда будет исключение при возврате методом кода ошибки:
Vi2>
Vi2>try {
Vi2>  activex_ptr -> MyMetod(); }
Vi2>catch (_com_error &e)
Vi2>  { MessageBox(e.Description); }
Vi2>catch (...)
Vi2>  { MessageBox("..."); }
Vi2>


Да, это наверное то что нужно, но не можешь ли ты поподробнее описать использование этих интеллектуальных указателей?

у меня ActiveX помещён в диалоговое окно и у него определена переменная MyActiveX. Я обращалась к методу: MyActiveX.MyMetod. Сейчас мне надо обращаться activex_ptr -> MyActiveX.MyMetod.

Как выглядит описание этого указателя activex_ptr?
CMyActiveXClass activex_ptr; ?
Re[3]: не могу поймать исключение _com_error
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 21.03.02 11:54
Оценка:
Здравствуйте natalka, Вы писали:

N>Да, это наверное то что нужно, но не можешь ли ты поподробнее описать использование этих интеллектуальных указателей?


N>у меня ActiveX помещён в диалоговое окно и у него определена переменная MyActiveX. Я обращалась к методу: MyActiveX.MyMetod. Сейчас мне надо обращаться activex_ptr -> MyActiveX.MyMetod.


N>Как выглядит описание этого указателя activex_ptr?

N>CMyActiveXClass activex_ptr; ?

http://www.rsdn.ru/?article/?vcpp/import.xml
Автор(ы): Игорь Ткачёв
Дата: 9.03.2001

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