В процессе визуального проектирования интерфейса получаем заготовку модуля с полями – компонентами. Каждый раз при добавлении обработчика прерывания Turbo Delphi автоматически добавляла метод в описание класса TForm2. В результате после добавления всех обработчиков описание класса будет выглядеть следующим образом:
Unit Uses_Massiv;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, Grids, StdCtrls, Buttons, ExtCtrls;
Type
TForm2 = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N6: TMenuItem;
StringGrid1: TStringGrid;
Label1: TLabel;
Edit1: TEdit;
Panel1: TPanel;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
Label3: TLabel;
Label2: TLabel;
N7: TMenuItem;
Label4: TLabel;
procedure FormActivate(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure N4Click(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure N5Click(Sender: TObject);
procedure N6Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure Edit1Change(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure N7Click(Sender: TObject);
private
{ Private declarations }
Public
{ Public declarations }
end;
Соответственно последовательно добавляются обработчики событий. В начале добавляются процедуры вычисления самих задач z1, z2, z3, z4, z5 – имена процедур, соответствующие номерам задач, которые вызываются обработчиком Bitbtn1Click.
Фрагмент описания одной из процедур:
procedure z1(sgr1:TStringGrid;label3:TLabel);
var i:Integer; s,d:Real;
begin
try
x:=TMas.Create(1,3);
y:=TMas.Create(1,3);
for i:=1 to 3 do x.Elem[i]:=strtofloat(Sgr1.cells[i-1,1]);
for i:=1 to 3 do y.Elem[i]:=strtofloat(Sgr1.cells[i-1,2]);
y.Sub(x);
S:=0;
for i:=1 to 3 do s:=s+sqr(y.Elem[i]);
d:=sqrt(s);
label3.caption:='Расстояние между двумя точками:=
'+floattostrf(d,ffFixed,5,1);
except
on EConvertError do ShowMessage('Ошибка в записи числа');
on EOverflow do ShowMessage ('Переполнение');
on EMathError do ShowMessage ('Ошибка при вычислениях');
end;
x.Free; y.Free;
end;
Далее добавляем обработчик FormActivate, который должен обеспечить внешний вид интерфейса, представленный на рисунке 11.
procedure TForm2.FormActivate(Sender: TObject);
begin
StringGrid1.fixedrows:=1;
StringGrid1.colCount:=4;
StringGrid1.cells[0,0]:='X';
StringGrid1.cells[1,0]:='Y';
StringGrid1.cells[2,0]:='Z';
StringGrid1.cells[3,0]:='m';
StringGrid1.Enabled:=False; // ввод чисел не доступно
StringGrid1.Visible:=False; // сделать невидимой таблицу ввода
чисел
Label1.visible:=False; // сделать невидимой метку ввода чисел
Label2.visible:=False; // сделать невидимой метку
Label3.visible:=False; // сделать невидимой метку окна вывода
Edit1.Enabled:=False; // окно ввода не доступна
Edit1.Visible:=False; // cделать окно ввода невидимой
Bitbtn1.Enabled:=False; // кнопка «Вычислить» не доступна
Bitbtn2.Enabled:=False; // кнопка «Следующая» не доступна
Label4.visible:=false; // сделать невидимой метку названий задач
end;
При создании проекта важным является выбор процедур z1, z2, z3, z4, z5 соответствующих номерам задач, которые вызываются обработчиком. Для этого добавляем обработчик Bitbtn1Click. Каждая из процедур решает одну из поставленных задач. Код обработчика этого события имеет вид:
procedure TForm2.BitBtn1Click(Sender: TObject);
begin
Bitbtn1.Enabled:=False;
Bitbtn2.Enabled:=true;
case nz of
1:z1(stringGrid1,label3);
2:z2(stringGrid1,label3);
3:z3(stringGrid1,label3);
4:z4(stringGrid1,label3);
5:z5(stringGrid1,label3);
end;
end;
Добавляем обработку нажатия клавиши «ВЫЧИСЛИТЬ». Для каждой задачи отдельная обработка. В данном фрагменте вызываем первую из поставленных задач, для которой была описана процедура вычисления z1. Создаем таблицу для ввода данных из 3 столбцов и 3 строк. В первой строке написаны сами названия точек, а в две оставшиеся вводим сами координаты двух точек. Все компоненты видимы и доступны.
procedure TForm2.N3Click(Sender: TObject);
begin
StringGrid1.RowCount:=3;
StringGrid1.СolCount:=3;
nz:=1;
n:=3;
k:=3;
Bitbtn1.Enabled:=true;
Label1.visible:=true;
Label3.visible:=true;
Label1.caption:='ВВЕДИТЕ КООРДИНАТЫ ДВУХ ТОЧЕК';
StringGrid1.Enabled:=true;
StringGrid1.Visible:=true;
Label4.caption:='Расстояние между двумя точками';
Label4.visible:=true;
Label4.Enabled:=true;
end;
Ниже приведен фрагмент кода процедуры z3, которая вызывается обработчиком события Bitbtn1Click при выборе пункта меню «Координаты центра тяжести материальных точек». При выборе данного пункта, как и пункта меню «Площадь многоугольника», вызывающего процедуру z4, становится доступным окно ввода. Пользователь вводит число материальных точек n и при этом StrigGrid1 становится доступным и в нем устанавливается необходимое число строк для заполнения координатами и массами введенного выше количества точек.
Создаются экземпляры класса TMas: массивы x, y, z, m, состоящие из n элементов:
x:=TMas.Create(1,n);
y:=TMas.Create(1,n);
z:=TMas.Create(1,n);
m:=TMas.Create(1,n);
Из таблицы StrigGrid1 считываются координаты и массы точек и присваиваются элементам массивов x, y, z, m:
for i:=1 to n do x.Elem[i]:=strtofloat(Sgr1.cells[0,i]);
for i:=1 to n do y.Elem[i]:=strtofloat(Sgr1.cells[1,i]);
for i:=1 to n do z.Elem[i]:=strtofloat(Sgr1.cells[2,i]);
for i:=1 to n do m.Elem[i]:=strtofloat(Sgr1.cells[3,i]);
Вызываются соответственно методы Mul и Sum для нахождения произведений и сумм:
x.Mul(m); y.Mul(m); z.Mul(m); sm:=m.Sum();
Опишем фрагмент кода процедуры z5, которая вызывается обработчиком события Bitbtn1Click при выборе пункта меню «Расстояние от точки до прямой».
Создаются экземпляры класса TMas: массивы x, y, z, состоящие из 3 элементов:
x:=TMas.Create(1,3);
y:=TMas.Create(1,3);
z:=TMas.Create(1,3);
Создаются экземпляры класса TMatr: матрицы – объекты M1, M2, M3 размера 2*2:
M1:=TMatr.Create(1,2,1,2);
M2:=TMatr.Create(1,2,1,2);
M3:=TMatr.Create(1,2,1,2);
Из таблицы StrigGrid1 считываются координаты двух точек и вектора прямой и присваиваются элементам массивов x, y, z:
for i:=1 to 3 do x.Elem[i]:=strtofloat(Sgr1.cells[i-1,1]);
for i:=1 to 3 do y.Elem[i]:=strtofloat(Sgr1.cells[i-1,2]);
for i:=1 to 3 do z.Elem[i]:=strtofloat(Sgr1.cells[i-1,3]);
Задаются значения входных данных для трех двумерных матриц:
M1[1,1]:=y[1]-x[1];
M1[1,2]:=y[2]-x[2];
M1[2,1]:=z[1];
M1[2,2]:=z[2];
M2[1,1]:=y[2]-x[2];
M2[1,2]:=y[3]-x[3];
M2[2,1]:=z[2];
M2[2,2]:=z[3];
M3[1,1]:=y[3]-x[3];
M3[1,2]:=y[1]-x[1];
M3[2,1]:=z[3];
M3[2,2]:=z[1];
Соответственно вызывается метод вычисления определителя второго порядка Det2, описанного в классе TMatr. Данный метод необходим для вычисления расстояния от точки до прямой:
chis:=sqr(M1.Det2)+sqr(M2.Det2)+sqr(M3.Det2);
znam:=sqr(z[1])+sqr(z[2])+sqr(z[3]);
rast:=sqrt(chis/znam);
Добавляем обработку события нажатия на кнопку «Следующая», для которой был создан компонент BitBtn2Click.
procedure TForm2.BitBtn2Click(Sender: TObject);
var i,j:Integer;
begin
Label2.caption:='';
Label3.caption:='';
Label1.caption:='';
Edit1.Text:='';
for i:=1 to n do
for j:=0 to k-1 do
StringGrid1.cells[j,i]:='';
StringGrid1.Enabled:=false;
StringGrid1.Visible:=false;
Bitbtn2.Enabled:=False;
Label1.visible:=false;
Label4.visible:=false;
Label4.Enabled:=false;
end;
Добавляем обработчик события «Изменение» для окна ввода. Компонента StringGrid становится доступной для ввода значений в том случае, если длина строки в окне ввода отлична от нуля.
procedure TForm2.Edit1Change(Sender: TObject);
begin
if strlen(PAnsiChar(Edit1.text))<>0 then
begin
n:=strtoint(edit1.text);
ShowMessage(inttostr(n));
StringGrid1.RowCount:=n+1;
StringGrid1.Enabled:=true;
StringGrid1.Visible:=true;
Label1.visible:=true;
bitbtn1.Enabled:=True;
end;
end;
В данном проекте важным является добавление обработчика событий Edit1KeyPress для окна ввода количества точек:
procedure TForm2.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
try
n:=strtoint(edit1.text);
StringGrid1.RowCount:=n+1;
StringGrid1.Enabled:=true;
StringGrid1.Visible:=true;
Label1.visible:=true;
if nz=3 then Label1.caption:='ВВЕДИТЕ КООРДИНАТЫ И
МАССЫ '+inttostr(n)+' ТОЧЕК;
if nz=4 then Label1.caption:='ВВЕДИТЕ КООРДИНАТЫ
'+inttostr(n)+' ТОЧЕК;
bitbtn1.Enabled:=true;
Edit1.Visible:=False;
label2.Visible:=False;
Edit1.Enabled:=false;
label2.Enabled:=False;
except
on EConvertError do ShowMessage('Ошибка в записи числа ');
end;
end;
Программа обработки помимо перенастройки интерфейса должна проверять, правильно ли введено число, и выполнять операцию или выдавать сообщение об ошибке.
Для проверки используем конструкцию try… except. Эта конструкция позволяет перехватить перехватывать обработку аварийных ситуаций (так называемых исключений), возникающих при выполнении операторов, расположенных между служебными словами try и except. Каждое исключение имеет определенное имя, так если при преобразовании строки в число функцией StrtoFloat фиксируется неверный формат исходной строки, то генерируется исключение с именем EConvertError. Соответственно, именно при обнаружении этого исключения в блоке except выдается сообщение о неверном вводе данных.
try
x:=TMas.Create(1,n);
y:=TMas.Create(1,n);
for i:=1 to n do x.Elem[i]:=strtofloat(Sgr1.cells[0,i]);
for i:=1 to n do y.Elem[i]:=strtofloat(Sgr1.cells[1,i]);
- Площадь многоугольника:= '+floattostr(sp);
except
on EConvertError do ShowMessage('Ошибка в записи числа);
on EOverflow do ShowMessage ('Переполнение');
on EMathError do ShowMessage ('Ошибка при вычислениях');
Также немаловажным является объявление переменных. Поскольку переменные, необходимые для вычислений являются внутренними, объявляем их в секции реализации модуля после служебного слова implementation:
Uses Massiv, Matrisa;
var x,y,z,m:TMas; M1,M2,M3:TMatr;
n,k,nz:integer;
{$R *.dfm}