Методичка Фролов
.pdfключительная ситуация подходит по типу к указанному после on, то выполнение программы переходит на код, помещенный после do. Исключительная ситуация подходит в том случае, если она того же класса, что указан в on, или является его потомком. Например, в случае возникновения исключения EFileNotFound обрабатываться будет ситуация, когда файл не найден. А в случае возникновения исключения EFileIO – все ошибки при работе с файлами, в том числе и EFileNotFound. В блоке else обрабатываются все ошибки, не обработанные до этого.
Перечислим некоторые исключения, которые могут возникать во время работы программы:
–EConvertError – происходит в случае возникновения ошибки при выполнении функций StrToInt и StrToFloat, когда конвертация строки в соответствующий числовой тип невозможна;
–EInOutError – происходит при ошибках ввода/вывода при включенной директиве {$I+};
–EIntError – предок исключений, случающихся при выполнении целочисленных операций;
–EIntOverflow – вызывается при попытке выполнения операций, приводящих к переполнению целых переменных при включенной директиве
{$Q+};
–ERangeError – вызывается при попытке обращения к элементам массива по индексу, выходящему за пределы массива, при включенной дирек-
тиве {$R+};
–EListError – вызывается при обращении к элементу наследника TList по индексу, выходящему за пределы допустимых значений (например, объект TStringList содержит только 10 строк, а происходит обращение к одиннадцатому);
–EMathError – предок исключений, случающихся при выполнении операций с плавающей точкой;
81
–EOverflow – происходит как результат переполнения операций с плавающей точкой при слишком больших величинах;
–Underflow – происходит как результат переполнения операций с плавающей точкой при слишком малых величинах;
–EZeroDivide – вызывается в результате деления на ноль;
–EMenuError – вызывается в случае любых ошибок при работе с пунктами меню для компонент TMenu, TMenuItem, TPopupMenu и их наследников;
–EFault – предок исключений, вызываемых в случае невозможности обработки процессором тех или иных операций.
Примером обработки исключительной ситуации может служить прерывание выполнения процедуры в случае возникновения исключения EZeroDivide (деление на ноль):
procedure TForm1.Button1Click(Sender: TObject); var a,b,c: extended;
begin a:=strtofloat(edit1.Text); b:=strtofloat(edit2.Text); try
c:=a/b; except
on EZeroDivide do begin
ShowMessage('На ноль делить нельзя!'); exit;
end;
end;
edit3.Text:=floattostr(c);
end;
82
2.8.2. Динамическое создание и удаление компонентов
Рассмотрим динамическое создание компонентов на примере программы, форма которой изображена на рис. 2.7, а. После нажатия на форму динамически создается кнопка, при нажатии на которую изменяется свойство Caption компонента Label (рис. 2.7, б). После нажатия на компонент Label созданная кнопка удаляется с формы.
а
б
Рис. 2.7. Пример динамического создания и удаления компонентов
unit Unit1; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm) Label1: TLabel;
procedure OnBtnClick(Sender: TObject); procedure FormClick(Sender: TObject); procedure Label1Click(Sender: TObject); private
{ Private declarations } public
83
{ Public declarations } end;
var
Form1: TForm1;
btn: TButton; {Объявляется переменная btn типа TButton (кнопка)} implementation
{$R *.dfm}
procedure TForm1.OnBtnClick(Sender: TObject); {Данная процедура вызывается собы-
тием OnClick динамически создаваемой кнопки} begin
if Sender is TButton then Label1.Caption:='MYA-HA-HA' {Если процедура вызывается кнопкой, то свойству Caption компонента Label1 присваивается значение 'MYA-HA- HA', если нет, то присваивается значение 'OH NO'}
else Label1.Caption:='OH NO';
end;
procedure TForm1.FormClick(Sender: TObject); begin
btn:=TButton.Create(nil); {Вызывается конструктор Create для создания компонента} btn.Parent:=Form1; {Задается родительский компонент для создаваемого компонента, тем самым он выводится на экран}
btn.Top:=16; {Задаются свойства и методы создаваемого компонента} btn.Left:=18;
btn.Caption:='Кнопка'; btn.OnClick:=OnBtnClick; end;
procedure TForm1.Label1Click(Sender: TObject); {В данной процедуре по нажатию на компонент Label с формы удаляется динамически созданная кнопка}
begin
if Sender is TLabel then btn.Free; end;
end.
84
2.8.3. Создание пользовательских функций
Функция – это последовательность инструкций, имеющая имя. Объявление функции в общем виде выглядит следующим образом:
function имя (параметр 1, параметр 2 : тип 1, ..., параметр n : тип m) : тип ; var
begin
…
имя := выражение; end;
function – зарезервированное слово языка Delphi, обозначающее, что далее следуют инструкции, реализующие функцию разработчика;
имя – имя функции, используется для перехода из программы к инструкциям функции;
параметр – переменная, значение которой используется для вычисления значения функции. Отличие параметра от обычной переменной состоит в том, что он объявляется не в разделе объявления переменных, который начинается словом var, а в заголовке функции. Конкретное значение параметр получает во время работы программы в результате вызова функции из основной программы;
тип – тип значения, которое функция возвращает в вызвавшую ее программу.
Рассмотрим функцию, проверяющую допустимость символов, вводимых в строку, представляющую собой число вещественного типа.
function NormVvod (ch: char; st: string): boolean; {Функция получает следующие пара-
метры: ch – нажатый на клавиатуре символ; st – уже введенная строка символов. Возвращает логическое значение.}
85
begin
if (ch>='0') and (ch<='9') or (ch=#13) or (ch=#8) then {Осуществляется проверка на-
жатого символа: если нажат символ от 0 до 9 или клавиша Enter (#13), или клавиша
Backspace (#8), то функции присваивается значение true – NormVvod:=true;} begin
NormVvod:=true;
Exit; end else
if (ch=',') then {Осуществляется проверка положения символа «,», если нажата соответствующая клавиша}
begin
if length(st)=0 then {Если клавиша с символом «,» нажата в момент, когда в поле ввода не введено еще ни одного символа, то есть длина уже введенной строки length(st) равна 0, то функции присваивается значение false – NormVvod:= false;}
begin
NormVvod:=false;
Exit; end else
if pos(',',st)<>0 then {Если клавиша с символом «,» нажата в момент, когда в поле ввода уже существует подобный символ, то есть позиция символа «,» pos(',',st) в уже введенной строке не равна 0, то функции присваивается значение false – NormVvod:= false;}
begin
NormVvod:=false;
Exit; end else begin
NormVvod:=true; {Если символ «,», вводится в строку впервые и не на первую позицию, то функции присваивается значение true – NormVvod:=true;}
Exit;
end;
86
end
else NormVvod:=false; {Если был нажат символ, отличный от цифр с 0 до 9 и «,», и это не были клавиши Enter и Backspace, то функции присваивается значение false – NormVvod:= false;}
end;
Приведенная выше функция может быть использована, например, в обработчике события OnKeyPress объекта Edit.
procedure TForm1.Edit19KeyPress(Sender: TObject; var Key: Char); {Key – символ, вво-
димый в строку} begin
if NormVvod(key,Edit19.Text)=False then {Если вводимый символ не прошел проверку в функции NormVvod, то выдается соответствующее сообщение и в строку вводится нулевой символ Chr(0)}
begin
ShowMessage('Вы ввели недопустимый символ!'); Key:=Chr(0);
end;
end;
2.8.4. Работа с реестром Windows
Реестр – это иерархически построенная, централизованная база данных в составе операционных систем Microsoft Windows, содержащая сведения, которые используются операционной системой для работы с пользователями, программными продуктами и устройствами.
В реестре хранятся данные, которые необходимы для правильного функционирования Windows. К ним относятся профили всех пользователей, сведения об установленном программном обеспечении и типах файлов, которые могут быть созданы каждой программой, информация о свойствах папок и значках приложений и многое другое.
87
Реестр Windows состоит из 5-ти корневых каталогов:
–HKEY_CLASSES_ROOT (HKCR) – содержит сведения о расширениях всех зарегистрированных в системе типов файлов (хранящиеся здесь сведения отвечают за запуск необходимой программы при открытии файла с помощью Проводника Windows);
–HKEY_CURRENT_USER (HKCU) – содержит информацию о пользователе, вошедшем в систему в настоящий момент (здесь хранятся папки пользователя, цвета экрана и параметры панели управления)
–HKEY_LOCAL_MACHINE (HKLM) – содержит информацию об аппа-
ратной части компьютера, о драйверах устройств, сведения о загрузке
Windows;
–HKEY_USERS (HKU) –содержит информацию о всех активных загруженных профилях пользователей данного компьютера;
–HKEY_CURRENT_CONFIG (HKCC) – содержит информацию о про-
филе оборудования, используемом локальным компьютером при запуске системы.
Реестр также удобен для хранения исходных данных программ. Например, при запуске программы «Расчет усилия зажима заготовки при токарной обработке» [18] необходимо в элемент ComboBox1 заносить названия зажимных устройств, для которых имеется алгоритм расчета зажимных усилий (сам алгоритм хранится в соответствующей dll-библиотеке). Также
вупомянутой программе реестр используется при добавлении названия нового зажимного устройства и пути к dll-библиотеке, содержащей алгоритм расчета зажимного усилия для данного устройства.
Для работы с реестром необходимо в предложении uses, содержащем список подключаемых библиотечных модулей, раздела текста программы interface включить модуль Registry. Рассмотрим алгоритм добавления нового зажимного устройства. На рис. 2.8 показан фрагмент формы, предназначенный для добавления нового зажимного устройства.
88
Рис. 2.8. Фрагмент формы, предназначенный для добавления нового зажимного устройства (1 – Edit14, здесь пользователь вводит название зажимного устройства; 2 – Edit15, здесь отображается имя файла, хранящего dll-библиотеку с алгоритмом расчета зажимного усилия, выбор которого осуществляется в диалоге открытия файла, вызываемого нажатием на кнопку 3; 4 – активирует алгоритм добавления информации о зажимном
устройстве в реестр)
Фрагмент кода, отвечающий за добавление в реестр информации о новом зажимном устройстве, выглядит следующим образом:
procedure TForm1.Button1Click(Sender: TObject); var
REG : TRegistry; {Объявляется переменная типа TRegistry}
ystr_no: string; {Объявляется переменная, хранящая порядковый номер устройства} i: integer;
begin
ComboBox1.Items.Add(edit14.Text); {В объект ComboBox1, хранящий список доступ-
ных зажимных устройств, добавляется имя устройства, введенное пользователем} i:=ComboBox1.Items.IndexOf(edit14.Text); {Переменной i присваивается порядковый номер вводимого устройства из списка в объекте ComboBox1} ystr_no:=floattostr(i);
REG:=TRegistry.Create; {Создается экземпляр класса TRegistry}
REG.RootKey:=HKEY_LOCAL_MACHINE; {Задается корневой каталог реестра} REG.OpenKey('Software\ProjectVRB\Names',true); {Открывается ключ реестра 'Software\ProjectVRB\Names', который хранит имена зажимных устройств}
89
REG.WriteString (ystr_no,Edit14.text); {Создается подключ с именем, равным порядко-
вому номеру вводимого устройства, параметр которого равен имени зажимного устройства, введенного в Edit14}
REG.CloseKey; {Записываются внесенные изменения и закрывается текущий ключ}
REG.OpenKey('Software\ProjectVRB\Files',true); {Открывается ключ реестра
'Software\ProjectVRB\Files', который хранит имена файлов, содержащих алгоритмы расчета зажимных усилий}
REG.WriteString (ystr_no,Edit15.text); {Создается подключ с именем, равным порядко-
вому номеру вводимого устройства, параметр которого равен имени файла с алгоритмом расчета зажимного усилия}
REG.CloseKey;
REG.Destroy; {Уничтожается ранее созданный экземпляр класса TRegistry}
Edit14.Text:='';
Edit15.Text:=''; end;
За добавление при запуске программы в ComboBox1 информации о доступных зажимных устройствах отвечает следующий код:
procedure TForm1.FormCreate(Sender: TObject); var
REG: TRegistry; name: String;
i: integer; str_i:string; begin
i:=0;
while i<>100 do begin
REG:=TRegistry.Create; REG.RootKey:=HKEY_LOCAL_MACHINE; str_i:=FloatToStr(i);
i:=i+1;
90