Я пишу на 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 написано, что должно.
Может я где-то что-то напутала...
Помогите чем можете.
Здравствуйте 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, Вы писали:
OO>В клиенте, ты импортом (#import) подключаешь свой объект?
OO>Это Ptr (обвертка над твоим объектом) полученные при импорте в случае ошибки генерят исключения, а не лично твой объект.
OO>Если импотртом, то с какими параметрами?
я расположила свой ActiveX в диалоговом окне клиента и задала для него переменную, в результате подключились классы моего ActiveX. Больше никаких подключений не делала. Все методы ActiveX работают как надо, кроме исключений.
Здравствуйте natalka, Вы писали:
N>Здравствуйте OlegO, Вы писали:
OO>>В клиенте, ты импортом (#import) подключаешь свой объект?
OO>>Это Ptr (обвертка над твоим объектом) полученные при импорте в случае ошибки генерят исключения, а не лично твой объект.
OO>>Если импотртом, то с какими параметрами?
N>я расположила свой ActiveX в диалоговом окне клиента и задала для него переменную, в результате подключились классы моего ActiveX. Больше никаких подключений не делала. Все методы ActiveX работают как надо, кроме исключений.
Чтобы понять, что происходит достаточно посмотреть .CPP файл, которые сгенерила студия,
для твоего ActiveX.
В методах идет вызов метода CWnd::InvokeHelper, а он в случае ошибки генерит
исключения COleException если код ошибки равен DISP_E_EXCEPTION, или
COleDispatchException в остальных случаях.
для простоты можешь перехватывать все исключения catch(...)
Если исключения не приходят, значит смотри код ActiveX'а
Здравствуйте 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(...), но мне надо конкретно.
Здравствуйте 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(...), но мне надо конкретно.
В некоторых случаях GetErrorInfo может возвращать S_OK, но pEI в то же время = NULL. Т.е. информация об ошибке просто теряется. Это случается, если в COM-объекте после вызова функции Error("Bla-bla-bla") сделать какой-то дополнительный вызов COM. Также эта ситуация возможна при вызове удаленного COM-объекта (в COM+ например).
Так что в этот обработчик лучше ввести дополнительную проверку:
Здравствуйте 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)
Здравствуйте 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.
Здравствуйте natalka, Вы писали:
N>Получилось перехватить catch(COleDispatchException *e), я раньше пробовала — не получалось. N>Но начальник всё-равно требует catch(_com_error &e)
Вариант a (Для тупых начальников):
Тогда эмулирой, это в классе, что сгенерил VS,
а именно в методах, перехватывай исключение COleDispatchException и затем, генери свое исключение
_com_error и его спокой-но ловив у себя .
Вариант б. Через импорт импортировать интерфейс, и после этого работать с ним.
Ну тогда в ручную придется создавать контрол и размещать его на диалоге.
PS Какая разница как получить ошибку, главное узнать что она произошла.
Да, это наверное то что нужно, но не можешь ли ты поподробнее описать использование этих интеллектуальных указателей?
у меня ActiveX помещён в диалоговое окно и у него определена переменная MyActiveX. Я обращалась к методу: MyActiveX.MyMetod. Сейчас мне надо обращаться activex_ptr -> MyActiveX.MyMetod.
Как выглядит описание этого указателя activex_ptr?
CMyActiveXClass activex_ptr; ?
Здравствуйте natalka, Вы писали:
N>Да, это наверное то что нужно, но не можешь ли ты поподробнее описать использование этих интеллектуальных указателей?
N>у меня ActiveX помещён в диалоговое окно и у него определена переменная MyActiveX. Я обращалась к методу: MyActiveX.MyMetod. Сейчас мне надо обращаться activex_ptr -> MyActiveX.MyMetod.
N>Как выглядит описание этого указателя activex_ptr? N>CMyActiveXClass activex_ptr; ?