ActiveX в Delphi

       

Понятие исключительной ситуации, ее обработка средствами Delphi



Под исключительной ситуацией мы будем понимать некое непредвиденное событие, способное повлиять на дальнейшее выполнение программы.
При обработке такой ситуации Delphi, как обычно, работает с объектами. С точки зрения компилятора Delphi исключительная ситуация - это объект. Для работы с этим специфичным объектом в Delphi (точнее, в Object Pascal) были введены следующие языковые конструкции: try .. except и try .. finally.
Рассмотрим эти языковые конструкции более подробно.
Итак, конструкция try .. except имеет следующий синтаксис (листинг 1.6):

Листинг 1.6
try
{исполняемый код};
except


on Exceptionl do {код, исполняемый в случае возникновения ошибки 1};
on Exception2 do {код, исполняемый в случае возникновения ошибки 2};
else
{код, обработчик всех не перехваченных ранее ошибок};
end;

Если при выполнении кода, размещенного в разделе try, генерируется исключение, то выполнение этого раздела прекращается и управление передается коду, размещенному в разделе except. Раздел except может использоваться двумя способами. Во-первых, в нем могут располагаться любые операторы, кроме обработчиков исключений, начинающихся с приставки on. Это и операторы сообщения об ошибке, и команды, позволяющие освобождать системные ресурсы, а также другие операторы и команды. Во-вторых, раздел except используется для обработки исключений. В этом случае в него могут включаться только операторы обработки исключений. Если среди обработчиков встретился обработчик, соответствующий сгенерированному исключению, то выполняется оператор этого обработчика, исключение разрушается и управление передается коду, расположенному после оператора on Exception do. Раздел, расположенный после ключевого слова else, служит для обработки любых исключений, не описанных в разделе except. Этот раздел не является обязательным. Если при обработке исключительной ситуации не будет найден подходящий обработчик, то произойдет обработка системным обработчиком исключений.
Рассмотрим простой пример обработки исключительной ситуации деления на ноль (листинг 1.7).

Листинг 1.7
try
а:=10;
b:=0;
c:=a/b;
except
on EZeroDivide do MessageBox('Делить на ноль нельзя!');
end;

Итак, как можно видеть из приведенного выше примера, для обработки разных исключений служат разные операторы. Рассмотрим более подробно оператор обработки on .. do. Данный оператор находится внутри раздела except и может иметь две формы (листинг 1.8).

Листинг 1.8
on <класс исключения> do <оператор>;
или
on <имя>: <класс исключения>
do <операторы, в которых можно использовать свойства исключения>

Этот оператор обрабатывает только тот класс исключений, который в нем указан. При указании родительского (базового) класса, все классы исключений - потомки данного класса - также будут обработаны. Для обработки всех исключений можно обратиться к базовому классу всех исключений: Exception. После обработки исключения оно разрушается. Вторая форма оператора on .. do отличается от первой тем, что данному исключению можно временно присвоить имя и обращаться к свойствам исключения. Обращаться к свойствам исключения можно с помощью конструкции <имя>.<имя свойства>. Посмотрим листинг 1.9.

Листинг 1.9
try
ScrollBarl.Max := ScrollBarl.Min - 1;
except
on E: EInvalidOperation do
MessageDlg( 'Игнорируем исключение: '- + E.Message, mtlnformation, [mbOK], O)
end;

В приведенном примере мы присваиваем исключению EInvalidOperation временное имя Е. Затем в окне сообщения выводим текст ошибки E.Message, выдаваемый Delphi по умолчанию (если бы не было нашего обработчика ошибки).

Примечание
Никогда не уничтожайте временный объект исключения. Обработчик исключений автоматически уничтожает объекты исключения. Если вы уничтожите объект исключения самостоятельно, это может привести к ошибке доступа.

Иногда, бывает необходимо, чтобы после обработки исключительной ситуации своим кодом вызывался стандартный обработчик ошибки. Например, в случае возникновения некоторой ошибки вы хотите, чтобы приложение сообщало пользователю какую-либо информацию, а затем передавало управление стандартному обработчику ошибок. Как вы уже знаете, после обработки исключения вашим кодом, исключение уничтожается. Для того чтобы самостоятельно вызвать снова это исключение, можно воспользоваться регенерацией исключений. Для регенерации исключения служит команда raise. Рассмотрим листинг 1.10.

Листинг 1.10
try
{ операторы }
except
on <класс исключения> do
begin
{операторы обработки исключения}
raise; // Регенерация исключения
end;
end;

После выполнения операторов обработки исключения, написанных программистом, выполняется команда raise, которая снова принудительно вызывает это исключение, после чего управление передается стандартному обработчику исключений.
В случае, когда исключение успешно проходит через все блоки try в коде приложения, вызывается метод HandleException. Он показывает диалоговое окно ошибки. Вы можете вызвать этот метод так, как в листинге 1.11.

Листинг 1.11
try
{ операторы } except
Application.HandieException(Self);
end;

Следующая конструкция try .. finally служит для защиты кода, записанного в разделе finally от исключительных ситуаций, которые в силу каких-либо причин могут происходить в разделе try. Синтаксис этой конструкции представлен на листинге 1.12.

Листинг 1.12
try
{операторы, способные создать исключительную ситуацию};
finally
{защищенные операторы, выполняемые в любом случае};
end;

Итак, операторы, которые размещены после ключевого слова finally, будут выполняться в любом случае, была сгенерирована исключительная ситуация или нет. Если в разделе try была сгенерирована исключительная ситуация, то управление немедленно передается разделу finally. Также, если исключительной ситуации в разделе, try не было, блок finally будет выполняться. Даже если в разделе finally произойдет ошибка, выполнение операторов этого раздела будет продолжено до конца. В конструкции try .. finally не происходит обработка исключений, она используется в основмом для освобождения ресурсов памяти, закрытия ненужных файлов и других операций освобождения ресурсов. Таким образом, в данной конструкции нуждаются операции с файлами, памятью, ресурсами Windows и объектами.
Код обработки исключения можно разбить на блоки try .. except .. end и try .. finally .. end. Эти блоки могут быть вложенными (рис. 1.24, а и б).
При разработке приложений на Delphi часто возникают ситуации, когда программисту не требуется обрабатывать исключения, а необходимо лишь прервать нежелательное действие, вызывающее ошибку. Для этого применяются так называемые молчаливые исключения (silent exceptions). Молчаливые исключения являются потомками стандартного исключения EAbort. По умолчанию обработчик ошибок VCL Delphi отображает на экране диалоговое окно ошибки для всех исключений, кроме наследников EAbort.

Примечание
При создании консольных приложений сведения об ошибке выводятся и для необработанных исключений EAbort.

Для того чтобы сгенерировать молчаливое исключение, можно вызвать процедуру Abort. Она автоматически сгенерирует исключение EAbort, которое прервет текущую операцию без вывода сведения об ошибке на экран. Рассмотрим пример. Пусть форма содержит пустой список (ListBoxi) и кнопку (Button1). Запишем в обработчик события кнопки onclick следующий код:

Листинг 1.13
procedure TForml.ButtonlClick(Sender: TObject);
var
I: Integer;
begin
for I := 1 to 10 do (цикл 10 раз}
begin
ListBoxl.Items.Add(IntToStr(I)); {добавляем номер в список}
if I = 7 then Abort; {прерываем добавление номеров в список после добавления седьмого номера}
end;
end;

В результате работы программы, после нажатия кнопки Button1, в список будет добавлено семь строк с номерами от 1 до 7.


Рис. 1.24. Вложенные блоки в обработчике исключений (а) и в конструкции защиты кода (б)



Содержание раздела