![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как поймать исключение ? [D7, Win95/98, Win2k]
Альф © (2005-09-22 11:51:00)Столкнулся с тем что не могу перехватить обработку исключения в следующей ситуации:
- есть компонент импортированный из OCX.
- форма на которой этот компонент расположен.
- написан обработчик на Application.OnException.
При создании этой формы через Application.CreateForm(...) вываливается окошко с заголовком "Application Error" и текстом "Exception EOleSysError in module ... at xxxx. Класс не зарегистрирован."
Это происходит когда на клиентской машине не установлен/не зарегистрирован этот *.ocx.
Проблема в том что никак не могу перехватить это сообщение, хотя все остальные исключитальные ситуации с успехом попадают в мой ExceptHandler.
Digitman (2005-09-22 17:41:00) [1]логично.
спасибо !
сабж сей я освежил у себя в памяти.
Альф (2005-09-22 17:33:00) [2]Т.е. как и ожидалось исключение возникает при попытке создать ActiveX контрол, класс котрого системе неизвестен.
Альф (2005-09-22 17:26:00) [3]В двух словах и насколько я понял:
эксперементальным путем выяснили что окошко ошибки - это MessageBox из процедуры SysUtils.ShowException(...)
но сначала я думал что этаSysUtils.ShowExceptionвызывается вTApplication.HandleException(...), тогда было странно видеть как EOleSysError не могло пройти проверкуif ExceptObject is Exception- но я оказался неправ !!!
оказалось что данное исключение не возникает внутри TApplication а возникаем при вызове вида
OleCheck(CoGetClassObject(IMy, CLSCTX_INPROC_SERVER or
CLSCTX_LOCAL_SERVER, nil, IClassFactory2, V));
где IMy - интерефейс с неизвесным системе UID;
ближайший источник вызова процедуры SysUtils.ShowException(...) оказался там же в SysUtilsExceptProc := @ExceptHandler;где в ExceptHandler и вызывалась данная ShowException(...)
осталось присвоить ExceptProc свой обработчик - и вуаля - мы получили перехват этого исключения :)
Digitman (2005-09-22 17:07:00) [4]
> Альф (22.09.05 17:05) [14]
колись уже ?)
таки любопытно все ж ...
Альф (2005-09-22 17:05:00) [5]Большое всем спасибо !!!
Проблема решена с помощью Mystic-а © за что ему огромное человеческое спасибо.
Альф (2005-09-22 14:22:00) [6]Сергей (два Сергея ;) ) мне прям неудобно что отвечаете только Вы.
Может ну его ...
Внести в документацию как "feature" :)))
Альф (2005-09-22 14:13:00) [7]Да - исключение просто гаситься
>> ShowMessage заменил на MessageBox
>зачем ?
нет - сомнений нету никаких, лень было Dialogs прописывать :)
Digitman (2005-09-22 13:23:00) [8]
> ShowMessage заменил на MessageBox
зачем ?
у тебя есть сомнения, что тело exсept-блока выполняется в том же потоке, в котором исключение и было возбуждено (т.е. в дан.случае - основном потоке, в котором была попытка создания формы) ?
Digitman (2005-09-22 13:20:00) [9]
> если убрать raise; - то получаем silentисключение
поясни ...
получив при возникновении исключения управление в except-блоке ты либо "гасишь" это исключение (по по нормальному завершению работы except-блока - под silent именно это имелось ввиду ?) либо перевозбуждаешь его по raise .. третьего не дано
Альф (2005-09-22 13:01:00) [10]Дополнение
try
Application.CreateForm(T_dataR3, _dataR3);
except
on e:exception do begin
MessageBox(0,'Исключение',nil,MB_OK);
// raise;
end;
end;
если убрать raise; - то получаем silent исключение, но поймать его всё же пока не получается
umbra (2005-09-22 12:57:00) [11]Что-то вроде
try
Application.Initialize;
except
on E:EOleSysError do
begin
ShowMessage(E.Message);
exit;
end;
end;
Альф (2005-09-22 12:46:00) [12]Сделал как сказал, только ShowMessage заменил на MessageBox.
Немножко изменилась реакция :)
Запускаем
Выскакивает окошко 'Исключение....
Песочные часы сек на 2-3
Стандартная форма Windows "В приложении ... обнаружена ошибка. Приложение будет закрыто."
Всё то же окошко с заголовком "Application Error"
При нажатии <Ok> висим ...
Снимаем через Task Manager :)
Причем это не зависит от наличия/присутсвия raise; в обработке ...
umbra (2005-09-22 12:36:00) [13]Если ты используешь активэксы, то скорее всего у тебя в юзесах есть ComObj. Так вот он имеет секцию инициализации, которая присваивает переменной InitProc ссылку на процедуру. Это значит, что в Application.Initialize что-то происходит и исключение случается именно там! Включи Application.Initialize в try.
Digitman (2005-09-22 12:31:00) [14]
> в T_dataOcx.FormCreate(...) не попадаем
здесь нет ничего удивительного.
событие OnCreate возбуждается лишь при условии и ПОСЛЕ того как будут успешно сконструированы все без исключения компоненты, брошенные тобой на форму в дизайн-тайм .. а поскольку при конструировании ocx-компонента возникла никак необработанная искл.ситуация, до вызова OnCreate-обработчика дело попросту не доходит
Digitman (2005-09-22 12:27:00) [15]пробуй так:
try
Application.CreateForm(T_dataOcx, _dataOcx);
exception
on e:exception do begin
ShowMessage('Исключение : ' + e.ClassName + ' ' + e.Message);
raise;
end;
end;
сообщение видишь ?
Альф (2005-09-22 12:22:00) [16]дополнение
Application.CreateForm(T_dataOcx, _dataOcx); // вот тут при нажатии F8 ловим вышеозначенное окно
и в T_dataOcx.FormCreate(...) не попадаем и при нажатии <Ok> глухо виснем...
Альф (2005-09-22 12:14:00) [17]
Application.Initialize();
with T_startuperr.Create(nil) do begin // вот тут ставиться Application.OnException := ExceptHandler;
Application.CreateForm(T_main_tst, _main_tst); // всё Ok
Application.CreateForm(T_data, _data); // всё Ok
Application.CreateForm(T_dataOcx, _dataOcx); // вот тут при нажатии F8 ловим вышеозначенное окно
CheckError(); // а тут стоит Application.Terminate();
end;
Application.Run();
При добавлении в FormCreate любой формы из T_main_tst, T_data кода видаraise EXXXError.Create('T_main_tst.FormCreate');попадаем в мой ExceptHandler, только кроме создания _dataOcx :(
Вероятно это происходит при создании компонента - но отловить это как ???
Digitman (2005-09-22 11:58:00) [18]
> обработчик на Application.OnException.
> Application.CreateForm(...)
это все в dpr происходит ?
покажи, в каком порядке ...