Практическое занятие № 3
Тема: Создание простого текстового редактора
Цель работы: получить практические навыки по работе с компонентами Edit, Memo, по масштабированию компонентов, по работе с диалогами.
Ход работы
Создать программу, которая при загрузке выдает окно ввода пароля:

Пароль разбивается на четыре части по 5 символов. В каждом поле предусмотреть автоматический переход в следующее поле при вводе 5 символов в текущем поле. В случае неверного ввода программа должна выдать сообщение об ошибке и предлагает ввести пароль снова (переходит в первое текстовое поле). В случае 5 неверных попыток кнопка "ОК" блокируется и продолжение работы с программой становится невозможным.
Указания: для первой формы задайте свойства: Caption="Регистрация. Осталось попыток : 5"; BorderStyle=bsDialog; Position=poDesktopCenter. На форме разместите 4 текстовых поля Edit, для которых задайте свойства: MaxLength=5 (длина в 5 символов), PasswordChar=* (символ для замены текста на экране), Text очистить.
Для автоматического перехода курсора между полями при вводе пароля в событии OnChange каждого поля введем код:
procedure TForm1.Edit1Change(Sender: TObject);
begin
//если в первое поле введено 5 символов
if Length(Edit1.Text)=5 then
//то переходим во второе поле
Edit2.SetFocus;
end;
procedure TForm1.Edit2Change(Sender: TObject);
begin
//если во второе поле введено 5 символов
if Length(Edit2.Text)=5 then
//то переходим в третье поле
Edit3.SetFocus;
end;
procedure TForm1.Edit3Change(Sender: TObject);
begin
//если в третье поле введено 5 символов
if Length(Edit3.Text)=5 then
//то переходим в четвертое поле
Edit4.SetFocus;
end;
procedure
TForm1.Edit4Change(Sender: TObject);
begin
//если в четвертое поле введено 5 символов
if Length(Edit4.Text)=5 then
//то переходим на кнопку
Button1.SetFocus;
end;
Добавим на форму кнопку со свойствами: Default=True; Caption=OK
Для подсчета количества попыток ввода пароля необходимо описать глобальную целую переменную в разделе Interface. Для этого после слова Var вставим строку вида:
k:integer=0;
Для кнопки напишем код:
procedure TForm1.Button1Click(Sender: TObject);
begin
//если введенный пароль равен заданному
if Edit1.Text+Edit2.Text+Edit3.Text+eDit4.Text='11111111111111111111' then
begin
//скрываем и удаляем из памяти окно пароля
Free;
//открываем окно редактора
Form2.Show;
end
//если пароль не верный
else
begin
//считаем количество попыток
k:=k+1;
//в заголовке окна меняем число оставшихся попыток
Caption:='Регистрация. Осталось попыток : '+IntToStr(5-k);
//выдаем сообщение об ошибке
Application.MessageBox('Неверный пароль',
'Ошибка',
MB_OK+MB_IconStop);
//ставим курсор в первое поле для повторного ввода
Edit1.SetFocus;
end;
//если пользователь сделал 5 попыток
if k=5 then
//блокируем доступ к кнопке
Button1.Enabled:=false;
end;
При верном вводе пароля на экране появляется окно редактора, который состоит из многострочного текстового поля и кнопок.

С помощью кнопки "Формат" должен открываться диалог форматирования символов. Сам диалог должен содержать кнопку Применить. С помощью кнопки "Цвет" должен открываться диалог для выбора цвета фона компонента Memo. Кнопки "Сохранить" и "Открыть" запрашивают ввод с клавиатуры имени файла и сохраняют содержимое поля в файл или загружают содержимое файла в поле (в качестве пути к файлу используется папка с приложением). Предусмотреть проверку наличия файла на диске.
Для окна редактора предусмотреть возможность масштабирования элементов на форме: при растягивании окна текстовое поле должно растягиваться пропорционально окну, а кнопки должны оставаться внизу. Окно не может уменьшаться меньше его начального размера.
Указания: добавим в проект новую форму и зададим ей свойство Caption=Редактор, Width=700, Height=470. Чтобы форма не уменьшалась меньше начального размера установите свойства формы: Constraints - Minwidth = 700, Constraints - MinHeight = 470.
На форме разместите компонент Memo (Standard). Для масштабирования компонента на форме в свойстве Anchors установите все параметры в True. На форме разместите 4 кнопки. Для масштабирования кнопок в их свойстве Anchors установите параметр akButtom=true, другие параметры установите в false.
По умолчанию в поле Memo нет полосы прокрутки, но как только текст в поле не помещается, должна отображаться вертикальная полоса. Как только текст помещается – исчезает.
Для реализации данной функции вначале переведем компонент Memo в рисунок, затем получим высоту строки в точках. Затем множим высоту строки на количество строк - получим высоту всего текста в точках. Если высота текста превышает высоту компонента, то отображается полоса прокрутки. В противном случае полоса прокрутки исчезает.
В событии OnChange поля введите код:
procedure TForm1.Memo1Change(Sender: TObject);
var
//переменная для создания класса работы с изображением
cnv:TCanvas;
//переменная для хранения высоты текста в точках
row:integer;
begin
//создаем экземпляр класса для изображения
cnv := TCanvas.Create;
try
//привязываем ссылку экземпляра класса к ссылке поля Memo1
cnv.Handle:=GetDC(Memo1.Handle);
//устанавливаем на изображении шрифт, аналогичный полю Memo1
cnv.Font.Assign(Memo1.Font);
//в переменную записываем высоту строки текста в точках
row:=cnv.TextHeight(Memo1.Text);
except end;
//если высота строки * количество строк + 1
//больше высоты компонента
if (row*(Memo1.Lines.Count+1))>=Memo1.Height then
begin
//отображаем вертикальную полосу прокрутки
Memo1.ScrollBars:=ssVertical ;
//ставим курсор в текущую позицию
Memo1.SelLength:=0;
end
//иначе - скрываем полосу прокрутки
else
Memo1.ScrollBars:=ssNone;
//удаляем из памяти экземпляр класса
FreeAndNil(cnv);
end;
На форме разместите компонент FontDialog (Dialogs). В свойстве Options установите параметр fdApplyButton=true для отображения кнопки Применить.
Для форматирования текста для кнопки "Формат" напишем код:
procedure TForm2.Button1Click(Sender: TObject);
begin
//передаем в окно форматирования формат текста
FontDialog1.Font.Assign(Memo1.Font);
//если в окне форматирования пользователь нажал кнопку ОК
if FontDialog1.Execute then
//применяем формат к тексту в поле
Memo1.Font.Assign(FontDialog1.Font);
end;
Для работы кнопки "Применить" для компонента FontDialog в событии OnApply введите код:
procedure TForm2.FontDialog1Apply(Sender: TObject; Wnd: hWnd);
begin
Memo1.Font.Assign(FontDialog1.Font);
end;
На форме разместите компонент ColorDialog (Dialogs).
Для изменения цвета фона поля Memo для кнопки "Цвет" напишем код:
procedure TForm2.Button2Click(Sender: TObject);
begin
//если в окне выбора цвета пользователь нажал кнопку ОК
if ColorDialog1.Execute then
//применяем цвет к фону поля Memo
Memo1.Color:=ColorDialog1.Color;
end;
Для сохранения содержимого поля в файл для кнопки Сохранить напишем код:
procedure TForm2.Button3Click(Sender: TObject);
begin
//сохраняем содержимое поля Memo1 в файл file.txt на диске C:
Memo1.Lines.SaveToFile('c:\file.txt');
end;
Для кнопки Открыть напишем код:
procedure TForm2.Button4Click(Sender: TObject);
begin
//загружаем ранее сохраненный файл в поле Memo1
Memo1.Lines.LoadFromFile('c:\file.txt');
end;
Обратите внимание, что при закрытии окна с текстом, программа продолжает работу (находится в ОЗУ).
Реализуйте корректное завершение программы.
Указания: данная проблема возникает потому, что главная форма (форма регистрации) была скрыта с экрана, но не закрыта.
Для завершения работы программы нужно закрыть главную форму проекта.
Для решения проблемы в событии OnClose второй формы добавьте команду:
//прервать работу приложения
Application.terminate;