При традиционной обработке ошибок, ошибки, обнаруженные в процедуре обычно передаются наружу (в вызывавшую процедуру) в виде возвращаемого значения функции, параметров или глобальных переменных (флажков). Каждая вызывающая процедура должна проверять результат вызова на наличие ошибки и выполнять соответствующие действия. Часто, это просто выход еще выше, в более верхнюю вызывающую процедуру и т.д. : функция A вызывает B, B вызывает C, C обнаруживает ошибку и возвращает код ошибки в B, B проверяет возвращаемый код, видит, что возникла ошибка и возвращает код ошибки в A, A проверяет возвращаемый код и выдает сообщение об ошибке либо решает сделать что-нибудь еще, раз первая попытка не удалась.
Структурная обработка исключительной ситуации замещает ручную обработку ошибок автоматической, сгенерированной компилятором системой уведомления. В приведенном выше примере, процедура A установила бы “охрану” со связанным обработчиком ошибки на фрагмент кода, в котором вызывается B. B просто вызывает C. Когда C обнаруживает ошибку, то создает (raise) исключительную ситуацию. Специальный код, сгенерированный компилятором и встроенный в Run-Time Library (RTL) начинает поиск обработчика данной исключительной ситуации. При поиске “защищенного” участка кода используется информация, сохраненная в стеке. В процедурах C и B нет такого участка, а в A - есть. Если один из обработчиков ошибок, которые используются в A, подходит по типу для возникшей в C исключительной ситуации, то программа переходит на его выполнение. При этом, область стека, используемая в B и C, очищается; выполнение этих процедур прекращается.
Если в A нет подходящего обработчика, то поиск продолжается в более верхнем уровне, и так может идти, пока поиск не достигнет подходящего обработчика ошибок среди используемых по умолчанию обработчиков в RTL. Обработчики ошибок из RTL только показывают сообщение об ошибке и форсированно прекращают выполнение программы. Любая исключительная ситуация, которая осталась необработанной, приведет к прекращению выполнения приложения.
Без проверки возвращаемого кода после каждого вызова подпрограммы, код программы должен быть более простым, а скомпилированный код - более быстрым. При наличии исключительных ситуаций подпрограмма B не должна содержать дополнительный код для проверки возвращаемого результата и передачи его в A. B ничего не должна делать для передачи исключительной ситуации, возникшей в C, в процедуру A - встроенная система обработки исключительных ситуаций делает всю работу.
Данная система называется структурной, поскольку обработка ошибок определяется областью “защищенного” кода; такие области могут быть вложенными. Выполнение программы не может перейти на произвольный участок кода; выполнение программы может перейти только на обработчик исключительной ситуации активной программы.
Пример использования структурной обработки исключительных ситуаций с использованием блока try-exceptв процедуре TMainForm.btnSimpsonRunClick приведен на рисунке 11.
try
a:=StrToFloat(edSimpA.Text);
b:=StrToFloat(edSimpB.Text);
n:=StrToInt(edSimpN.Text);
if a>b then
begin
Application.MessageBox('Нижний предел больше верхнего', 'Ошибка!',MB_OK or MB_ICONError);
exit;
end;
except
on EConvertError do
begin
Application.MessageBox('Ошибка ввода численных значений', 'Ошибка!',MB_OK or MB_ICONError);
exit;
end;
end;
Также в программе применяется методика создания и обработки пользовательской исключительной ситуации. Так в модуле evalComp.pas создается класс EvalException, являющийся потомком класса EAbort. В процессе работы с модулем может произойти генерация исключительной ситуации, которую в свою очередь будет обрабатывать вызывающий модуль (в нашем случае процедура TEvalForm.btnOkClick). Листинг примера работы с пользовательскими исключительными ситуациями приведен на рисунке 12.
type
EvalException = class(EAbort)
end;
function myfac(x,y:real):real;
var
begin
if x<0 then begin raise EvalException.Create(''); halt; end;
if x = 0 then myfac := 1
else
end;
procedure TEvalForm.btnOkClick(Sender: TObject);
begin
Dispose(calc, done);
try
new(calc, init(edEval.Text)); Close;
except
on EvalException do ShowMessage('Ошибка в формуле');
end;
end;
Кроме того, в программе для предотвращения возникновения непредвиденных ситуаций применяется защищенный блок try-finally-end. Листингприведеннарисунке 13.
procedure TChart.SaveToFile(filename: string);
var temporary: TPicture;
begin
temporary:=TPicture.Create;
try
temporary.Bitmap.Width:=width; temporary.Bitmap.Height:=height;
Temporary.Bitmap.Canvas.CopyRect(Temporary.Bitmap.Canvas.ClipRect,MainCanvas, MainCanvas.ClipRect);
Temporary.SaveToFile(filename);
finally
temporary.Destroy;
end;
end;
3. ЭЛЕМЕНТЫ ИНТЕРФЕЙСА ПРОГРАММНОГО КОМПЛЕКСА
3.1 Шаблоны окон
На рисунках 12 и 13 изображено главное окно программы, которое может изменять свой вид в зависимости от выбранной закладки. На рисунке 14 изображено окно, предназначенное для ввода произвольной функции. На рисунке 15 представлена форма окна отображающего сведения о системе. Окно на рисунке 16 изображено окно сведений о разработчике.
Рисунок 12 – Главное окно программы – закладка «Расчет интегралов»
Рисунок 13 – Главное окно программы – закладка «Построение графика»
Рисунок 14 – Окно «Произвольная функция»
Рисунок 15 – Окно отображающее информацию о текущей системе
Рисунок 16 – Окно сведений о программе
Все компоненты, которые расположены на формах представленных на рисунках 12-16, описаны в таблицах 1-4.
3.2 Структурно-функциональная схема программного комплекса
Файл формы – MainUnit.pas
Имя формы – MainForm
Заголовок – Курсовая работа по СПр
Назначение формы – ввод исходных данных для вычисления интегралов, для отрисовки графика зависимости значения интеграла от значения верхнего предела интегрирования при фиксированном нижнем пределе, вывод на экран полученного графика, полученных результатов расчета интегралов и вызов дополнительных форм, демонстрирующих работу API-функций, формы для ввода произвольной функции, формы для получения информации о разработчике, а также вызова справки в стиле Windows.
В таблице 1 представлен перечень компонентов содержащихся на форме.
Таблица 1 – Описание главной формы приложения
Имя компонента в модуле | Назначение компонента | События компонента | Назначение обработчиков событий | Примечания | ||||||||
cbSimpFunct, cbTrapFunct | Компонент ComboBox предназначенный для выбора подинтегральной функции | - | - | - | ||||||||
edSimpA, edSimpB, edTrapA, edTrapB | Поля для ввода изменения границ интегрирования | - | - | - | ||||||||
edSimpN | Поле для ввода числа разбиений в методе Симпсона | - | - | - | ||||||||
edTrapEPS | Поля для ввода точности вычислений в методе трапеций | - | - | - | ||||||||
edSimpResult,edTrapResult | Поля для вывода результатов интегрирования | - | - | - | ||||||||
btnSimpsonRun | Кнопка для расчета интеграла методом Симпсона | onClick | Сначала производиться проверка на наличие верхней и нижней границ. Далее проверка на то, чтобы нижняя граница была меньше или равна верхней. Контроль записи вещественных чисел. В случае прохождения всех вышеперечисленных проверок—расчет методом Симпсона и выдача в поле вывода результата. Вывод значения интеграла в edSimpResult. | MessageBox('Нижний предел больше верхнего', 'Ошибка!',MB_OK or MB_ICONError);MessageBox('Ошибка ввода численных значений', 'Ошибка!',MB_OKorMB_ICONError) | ||||||||
btnTrapRun | Кнопка для расчета интеграла методом трапеций | onClick | Сначала производиться проверка на наличие верхней и нижней границ, проверка на то, чтобы нижняя граница была меньше или равна верхней. Контроль записи вещественных чисел.—расчет методом трапеций и выдача в поле вывода результата. Вывод значения интеграла в TrapResult. | MessageBox('Нижний предел больше верхнего', 'Ошибка!',MB_OK or MB_ICONError);MessageBox('Ошибка ввода численных значений', 'Ошибка!',MB_OKorMB_ICONError) | ||||||||
imInt1, imInt2 | Image для отображения интегралов 1 и 2 | - | - | - | ||||||||
PageControl | Компонент TPageControl, для управления закладками | - | - | - | ||||||||
ChartBox | Компонент Image для отрисовки графиков | OnMouseDown | Выполняется проверка какая клавиша нажата – левая или правая – устанавливается соответствующий флаг - и в результате принимается решение о начале масштабирования либо перемещения графика | - | ||||||||
OnMouseMove | Выполняется проверка флага нажатия кнопки мыши и в результате: если нажата левая клавиша – продолжение перемещения, правая – продолжение масштабирования | - | ||||||||||
OnMouseUp | Выполняется проверка флага нажатия кнопки мыши и в результате: если нажата левая клавиша – окончание перемещения и снятие флага, правая – окончание масштабирования и снятие флага | - | ||||||||||
SavePictureDialog | Компонент страницы DIALOGS служащий для сохранения изображения графика в виде отдельного файла. | Execute | Вызов стандартного окна сохранения файлов | |||||||||
MainMenu | Главное меню программы состоящее из разделов: «Файл», «Фукции», «Сервис», «Помощь» | - | - | - | ||||||||
mmSave | Пункт меню для сохранения графика | onClick | Вызов стандартного окна сохранения графика | |||||||||
mmExit | Пункт меню для выхода из программы | onClick | Выход программы | |||||||||
mmIntFunct1 | Пункт меню для отображения/скрытия графика подынтегральной функции 1 | onClick | Отображает/скрывает график подынтегральной функции 1 | |||||||||
mmIntFunct2 | Пункт меню для отображения/скрытия графика подынтегральной функции 2 | onClick | Отображает/скрывает график подынтегральной функции 2 | |||||||||
mmIntegral1 | Пункт меню для отображения/скрытия графика интеграла 1 | onClick | Отображает/скрывает графикинтеграла 1 | |||||||||
mmEval | Пункт меню для открытия окна ввода произвольной функции | onClick | Вызывает окно ввода произвольной функции (форма EvalForm) | |||||||||
mmGrid | Пункт меню для установки сетки на графике | onClick | Разрешает/запрещает отрисовку сетки на графике | |||||||||
mmSysInfo | Пункт меню для вывода информации о системе | onClick | Выводит окно с информацией о системе (форма SystemInfoForm) | |||||||||
mmClipCursor | Пункт меню для использования функции ClipCursor | onClick | Демонстрирует использование функции ClipCursor | |||||||||
mmHelp | Пункт меню для вызова помощь | onClick | ||||||||||
mmAbout | Пункт меню для вывода окна информации о разработчике | onClick | Вызов формы FormAbout с информацией о разработчике |
Файл формы – evalForm.pas