Иллюстрированный самоучитель по Delphi 7 для профессионалов

Использование исключительных ситуаций

Если произошла ошибка и возбуждена исключительная ситуация, то она будет обрабатываться по такому алгоритму:

  1. Если ситуация возникла внутри блока try..except, то там она и будет обработана. Если ИС "продвинута" дальше при помощи оператора raise, а также если она возникла в блоке try..finally, обработка продолжается.
  2. Если программистом определен обработчик события Application.onException, то он получит управление. Обработчик объявлен следующим образом:
TExceptionEvent = procedure (Sender: TObject; E: Exception) of object;
  1. Если программист никак не определил реакцию на ИС, то будет вызван стандартный метод showException, который сообщит о классе и месте возникновения исключительной ситуации.

Пункты 2 и 3 реализуются в методе TAppiication.HandieException. Собственно, выглядят они следующим образом:

if not (ExceptObject is EAbort) then
if Assigned(FOnException) then
FOnException(Sender, Exception(ExceptObject))
else
ShcwExceptior. (Exception(ExceptObject));

Обработчик onExceptiоn нужен, если требуется выполнять одно и то же действие в любой исключительной ситуации, возникшей в вашем приложении. К примеру, назвать себя, указать координаты для обращения или предупредить, что это еще бета-версия.

program Project!;
uses
Forms,
SysUtils, //добавлено вручную – там описан класс Exception Dialogs,
Unitl in 'Unitl.pas' {Forml};
{$R *.RES}
type
TExceptClass = class
public
procedure GlobalExceptionHandler(Sender: TObject; E:Exception);
end;
procedure TExceptClass.GlobalExceptionHandler(Sender: TObject;
E:Exception);
begin
ShowMessage('Произошла исключительная ситуация ' + E.ClassName
+ ': ' + E.Message
+ #13#10'Свяжитесь с разработчиками по тел. 222-33-44');
end;
begin
with TExceptClass.Create do
begin
Application.OnException: = GlobalExceptionHandler;
Application.Initialize;
Application.CreateFormfTForml, Forml);
Application.Run;
Free;
end;
end.

Здесь класс TExceptClass создается только для того, чтобы быть носителем метода GiobalException. Обработчик любого события – метод, и он должен относиться к какому-либо объекту. Поскольку он здесь нужен еще до инициализации форм приложения и других его составных частей, то и объект класса TExceptClass создается первым. Теперь пользователь знает, что благодарить за неожиданности нужно по указанному в сообщении об ошибке телефону разработчиков.

Примечание
Есть и более простой способ присвоить обработчик событию Application.OnException. Для этого поместите на форму компонент типа TApplicationEvents (страница Additional Палитры компонентов), роль которого – предоставление "визуального" доступа к свойствам невизуального объекта TApplication. Среди его событий есть и OnException
.

Но как "пощупать" переданный при исключительной ситуации объект? Обычная конструкция:

on EExceptionType do…

Указывает на класс объекта, но не на конкретный экземпляр. Если во время обработки требуется доступ к свойствам этого экземпляра, его нужно поименовать внутри on..do, указав перед именем класса некий идентификатор:

on EZD: EZeroDivide do EZD.Message: = 'Деление на ноль!';

Здесь возникшее исключение выступает под именем EZD. Можно изменить его свойства и отправить дальше:

var APtr: Pointer;
Forml: TForm;
try
APtr: = Forml;
with TObject(APtr) as TBitmap do;
except
on EZD: EInvalidCast do EZD.Message: =. EZD.Message + 'xa-xa!';
Raise;{ теперь обработка будет сделана в другом месте }
end;

Но как поименовать исключительную ситуацию, не попавшую ни в одну из директив on..do? Или, может быть, в вашем обработчике вообще нет on..do, а поработать с объектом надо? Описанный выше путь здесь не подходит. Для этих случаев есть пара системных функций Exceptobject и ExceptAddr. К сожалению, эти функции инициализируются только внутри конструкции try..except; в try..finally работать с объектом– исключительной ситуацией не представляется возможным.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.