Лекция № 5

Тема: «Окно регистрации. Многострочное поле. Диалоги форматирования»

 

План

1. Многострочное окно редактировани

2.  Создание формы регистрации

3.  Система диалогового форматирования символов

 

1. Многострочное окно редактирования

 Компонент Memo (Standard) является полем редактирования многострочного текста. Оно обладает многими функциями, свойственными большинству редакторов. У него предусмотрены типовые комбинации горячих клавиш: Ctrl+C – копирование выделенного текста в буфер Clipboard (команда Copy), Ctrl+X – вырезание выделенного текста в буфер Clipboard (команда Cut), Ctrl+V – вставка текста с буфера Clipboard в позицию курсора (команда Paste), Ctrl+Z – отмена последней команды редактирования.

В отличие от компонента Edit компонент Memo может содержать текст, набранный в несколько строк. Компонент имеет свойства:

 

Свойство

Описание

Align

Задает выравнивание компонента на форме

Alignment

Выравнивание текста

Color

Задает цвет фона

Cursor

Задает показатель мышки при наведении на счетчик

Enabled

Если равно true, то компонент доступный

Font

Задает параметры форматирования текста

Height

Высота компонента в пикселях

Hint

Текст всплывающей подсказки

Left

Задает отступ компонента от левого края формы в пикселях

Lines

Сохраняет содержание компонента

MaxLength

Задает максимальную длину в символах. Если равно 0, тогда неограниченное

Name

Задает имя компонента для обращения к нему в тексте программы

ReadOnly

Если равно true, то поле заблокированное для редактирования

ScrollBars

Отображение или скрывает полоски прокручивания в поле

ShowHint

Если равно true, тогда отображается текст всплывающей подсказке

TabOrder

Задает порядок перехода на компонент по клавише TAB

TabStop

Если равно false, то перейти на компонент клавишей TAB будет невозможно

Top

Задает отступ компонента от верхнего края формы в пикселях

Visible

Если равно true, то компонент видимый на форме

WantReturns

Если равно true, то при наборе текста можно переходить на новую строчку клавишей ENTER

WantTabs

Если равно true, то при наборе тексту можно делать отступы клавишей TAB

Width

Задает ширину компонента в пикселях

WordWrap

Если равно true, то текст автоматически переноситься на новую строку

 

С компонентом Memo можно выполнить несколько действий с помощью методов:

 

Memo1.Clear; //очистка поля

Memo1.Undo; //отмена изменений

Memo1.SelectAll; //выделить весь текст в поле

Memo1.Lines.Add(текст); //добавление строки в поле

Memo1.SetFocus; //установка курсора в поле

 

Пусть, например, в вашем приложении есть окно редактирования Edit1, в котором пользователь вводит имя сотрудника, и есть кнопка, при нажатии на которую в окно Memo1 должна занестись шапка характеристики этого сотрудника, после чего пользователь может заполнить текст характеристики.

Обработчик нажатия на кнопку может иметь вид:

 

Memo1.Clear;

Memo1.Lines.Add('Характеристика');

Memo1.Lines.Add('Сотрудник '+Edit1.Text);

Memo1.SetFocus;

 

Компонент Memo имеет методы для работы с файлами.

 

Memo1.Lines.LoadFromFile(имя файла); //загружает в компонент указанный файл

Memo1.Lines.SaveToFile(имя файла); //сохраняет содержимое поля в файл

 

Также компонент Memo имеет специальные методы для работы с буфером обмена.

Для копирования выделенного фрагмента в буфер используют команду:

 

Memo1.CopyToClipboard;

 

Для вырезания выделенного фрагмента в буфер используют команду:

 

Memo1.CutToClipboard;

 

Для вставки содержимого буфера в окно Memo используют команду:

 

Memo1.PasteFromClipboard;

 

Организация скроллинга текста в поле

По умолчанию в поле 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;

 

2. Создание формы регистрации

Нередко в программах при запуске нужно пройти регистрацию, вводя пароль. При этом используются следующие требования:

Рассмотрим пример. Пусть имеется форма вида:

 

 

Пароль разбит на четыре группы по 5 символов. Пользователь набирает пароль, и курсор автоматически переходит между полями. Всего дается 5 попыток для ввода. Если пароль не верный, то программа завершает роботу.

Сначала для всех полей в свойствах PasswordC har необходимо указать символ «*». Это позволит спрятать на экране настоящие символы пароля.

Для того чтобы курсор автоматически переходил между полями при вводе пароля необходимо проверять, ввел ли пользователь в поле 5 символов, если да, то перейти в следующее поле. При вводе текста для текстового поля происходит событие OnСhange, в которой необходимо написать код:

 

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;

 

Для кнопки ОК нужно написать код, в котором проверяется пароль. Если пароль верный, то открывается окно главной программы. Если пароль не верный, то дается еще одна попытка ввода пароля. Если пользователь сделал 5 неудачных попыток, то программа закрывается.

 

procedure TForm1.Button1Click(Sender: Tobject);

begin

//если пароль верный

if Edit1.Text+Edit2.Text+Edit3.Text+Edit4.Text='11111111111111111111' then

begin

//убираем и удаляем из памяти форму пароля

Free;

//отображаем форму form2

Form2.Show;

end

//если пароль не верный

else

begin

//выдаем сообщение об ошибке

Application.MessageBox('Неверный пароль','Ошибка',mb_ok+ mb_iconstop);

//ставим курсор в первое поле для повторного ввода

Edit1.SetFocus;

//увеличиваем счетчик неудачных попыток

k:=k+1;

end;

//если было сделано пять попыток

if k=5 then

//прерываем работу программы

Application.Terminate;

end;

 

Для работы этого фрагмента необходимо выполнить несколько операций:

Application.Terminate;

 Генерация пароля с помощью MD5 хеширования

Рассмотренный пример имеет недостаток, связанный с тем, что пользователь вводит в поле сам текст пароля без шифрования. Если на компьютере будет установлена шпионская программа, которая перехватывает нажатия клавиш, то такой пароль будет похищен. Для защиты пароля рекомендуется ключевое слово шифровать с помощью специальных алгоритмов и вводить именно зашифрованный текст. Одним из наиболее распространенных и мощных алгоритмов шифрования является метод хеширования MD5. Его суть заключается в том, что из исходной текстовой строки получается некоторый набор из 32 символов, который будет вводиться как пароль. При этом обратная расшифровка не возможна. То есть зная сгенерированный набор символов, не возможно получить исходный текст пароля.

Для шифрования по указанному алгоритму можно использовать следующий подход:

 

//подключите модули

IdHashMessageDigest, idHash

 

В разделе implementation кода формы создайте функцию вида:

 

//аргументом функции является серетное слово-пароль

//функция фозвращает сгенерированный зашифрованный текст

function md5(SourceString: string): string;

var

//описываем переменную для хранения класса шифрования текста

md5: TIdHash128;

begin

    //создает экземпляр класса в памяти

    md5 := TIdHashMessageDigest5.Create;

    //функции присваиваем результат шифрования исходной фразы

    Result := md5.AsHex(md5.HashValue(sourcestring));

    //удаляем переменную из памяти

    FreeAndNil(md5);

end;

 

Пусть имеется 8 полей по 4 символа для ввода пароля. Сам пароль - это текст "password". Необходимо, чтобы пользователь вводил зашифрованное значение пароля, и программа проверяла его правильность.

 

if Edit1.Text+Edit2.Text+...+Edit8.Text=md5('password') then

    //пароль правильный

 

Слово 'password', зашифрованное с помощью MD5 хеширования будет иметь '5F4DCC3B5AA765D61D8327DEB882CF99'. Именно это текст будет вводить пользователь как пароль. Если злоумышленник перехватит вводимый текст, то обратное преобразование не возможно. Слово 'password' ему получить не удастся.

 

3. Системные диалоги форматирования символов

В программах Windows часто используются специальные диалоговые окна: Открыть, Сохранить, Формат, Цвет, Печать. Эти окна всегда имеют одинаковый вид, так как являются стандартными системными диалогами Windows.

Для работы с диалоговыми окнами в Delphi есть специальные компоненты, расположенные на вкладке Dialogs. Рассмотрим диалоги, предназначенные для форматирования текста.

 

Диалог выбора шрифта. Компонент FontDialog

Компонент FontDialog вызывает диалоговое окно выбора атрибутов шрифта. В нем пользователь может выбрать имя шрифта, его стиль (начертание), размер и другие атрибуты.

Основное свойство компонента – Font, в котором можно указать при желании первоначальные установки атрибутов шрифта, и из которого вы можете прочитать значение атрибутов, выбранные пользователем в процессе диалога.

Свойства MaxFontSize и MinFontSize устанавливают ограничения на максимальный и минимальный размер шрифта. Если значения этих свойств равно 0 (по умолчанию), тогда никакие ограничения на размер не накладываются. Если значение свойства задано, тогда в списке Размер диалогового окна появляются только размеры, которые укладываются в заданный диапазон. Свойства MaxFontSize и MinFontSize работают только тогда, когда включен параметр fdLimitSize.

Свойство Device определяет, из какого списка возможных шрифтов будет предложен выбор в диалоговом окне: fdScreen – из списка экрана (по умолчанию), fdPrinter – из списка принтера, fdBoth – с обоими.

Свойство Options содержит набор параметров:

 

fdAnsiOnly

Отображать только набор шрифтов символов Windows, не отображать шрифты со специальными символами.

fdApplyButton

Отображать в диалоге кнопку Применить независимо от того, представлен ли обработчик события OnApply.

fdEffects

Отображать в диалоге индикаторы специальных эффектов (подчеркивание и др.) и список Цвет.

fdFixedPitchOnly

Отображать только шрифты с постоянной шириной символов.

fdForceFontExist

Разрешать пользователю выбирать шрифты только из списка, запретить ему вводить другие имена.

fdLimitSize

Разрешить использовать свойства MaxFontSize и MinFontSize размеры, которые ограничивают размер шрифта.

fdNoFacesel

Открыть диалоговое окно без предварительной установки имени шрифта.

fdNoOemFonts

Выделять из списка шрифтов шрифты OEM.

fdScalableOnly

Отображать только масштабируемые шрифты, выделять из списка не масштабируемые (шрифты bitmap).

fdNoSimulations

Отображать только шрифты и их начертание, прямо поддерживаемые файлами, не отображая шрифты, у которых  жирный стиль и курсив синтезируется.

fdNoSizeSel

Открывать диалоговое окно без предварительно установленного размера шрифта.

fdNoStyleSel

Открывать диалоговое окно без предварительно установленного начертания шрифту.

fdNoVectorFonts

Удалять из списка векторные шрифты (типа Roman или Script).

fdShowHelp

Отображать в диалоговом окне кнопку Справка.

fdTrueTypeOnly

Предлагать в списке только шрифты TrueType.

fdWysiwyg

Предлагать в списке только шрифты, доступные для экрана и для принтера, удаляя из него аппаратно зависимые шрифты.

 

По умолчанию все эти опции, кроме fdEffects, отключены.

Приведем примеры применения компонента FontDialog. Пусть ваше приложение включает окно редактирования Memo1, и кнопку Формат, с помощью которой пользователь может открывать диалог форматирования текста. Если Вы добавили на форму компонент FontDialog с именем по умолчанию FontDialog1, тогда обработчик для кнопки может иметь вид:

 

if FontDialog1.Execute then

    Memo1.Font.Assign(FontDialog1.Font);

 

Приведенный код вызывает диалог атрибутов шрифта и, если пользователь сделал выбор, тогда значения всех выбранных атрибутов из свойства FontDialog1.Font, присваиваются атрибутам свосйтсва Memo1.Font.

Однако, при вызове диалога возникает проблема, связанная с тем, что в окне диалога не всегда правильно отображается текущий формат поля Memo. Это может привести к некорректной работе диалога. Для решения данной проблемы необходимо перед открытием диалога устанавливать в него текущий формат поля. Поэтому полный код для форматирования текста может иметь вид:

 

//устанавливаем в диалог текущий формат поля

Memo1.Font.Assign(FontDialog1.Font);

//вызываем диалог и форматируем текст

if FontDialog1.Execute then

    Memo1.Font.Assign(FontDialog1.Font);

 

Если вы установите в компоненте FontDialog1 опцию fdApplyButton, то можете написать обработчик события OnApply:

 

Memo1.Font.Assign(FontDialog1.Font);

 

Тогда пользователь может наблюдать изменения в окне Memo1, нажимая в диалоговом окне кнопку Применить не закрывая диалог. Это очень удобно, потому что позволяет пользователю правильно подобрать атрибуты шрифта.

Вы можете разрешить пользователю сменить шрифты не только отдельных компонентов, но и всех компонентов и надписей на форме. Это осуществляется оператором:

 

if FontDialog1.Execute then

    Font.Assign(FontDialog1.Font);

 

В этом операторе свойство Font без ссылки на компонент имеет в виду шрифт формы.

 

Диалог выбора цвета. Компоненты ColorDialog и Colorbox

Компонент ColorDialog вызывает стандартное диалоговое окно выбора цвета.

Основное свойство компонента ColorDialog – Color. Это свойство соответствует тому цвету, который выбрал пользователь. Если при вызове диалога желательно установить некоторое начальное значение цвета, это можно сделать, установив свойство Color предварительно во время проектирования формы или программно.

Свойство Options содержит множество следующих опций:

 

cdFullOpen

Отображать при открытии диалогового окна панель определения задаваемых цветов.

cdPreventFullOpen

Запретить появление в диалоговом окне кнопки Определить цвет. В результате пользователь не может определить новые цвета.

cdShowHelp

Добавить в диалоговое окно кнопку Справка.

cdSolidColor

Указать Windows использовать сплошной цвет, ближайший до выбранного (это обедняет палитру).

cdAnyColor

Разрешить пользователю выбирать любой не сплошные цвета (такие цвета могут быть неровными).

 

По умолчанию все опции выключены.

Приведем пример использования компонента ColorDialog. Если вы хотите, чтобы пользователь мог задать цвет какого-то объекта, например, цвет фона компонента Memo1, тогда это можно реализовать оператором

 

if ColorDialog1.Execute then

    Memo1.Color:=ColorDialog1.Color;

 

Рассмотренный компонент ColorDialog вызывает стандартный диалог Windows. Однако нередко его возможности избыточны и пользователю удобнее выбирать цвет с помощью dsgflf.otuj списка. Такую возможность дает компонент Colorbox (Additional).

Узнать цвет, выбранный пользователем в списке Colorbox, позволяет свойство Selected. Для этого можно воспользоваться событием компонента OnSelect, которое наступает в момент выбора пользователем цвета. Например, оператор

 

Memo1.Color:=Colorbox1.Selected;

 

помещенный в обработчик этого события, задаст фону окна Memo1 цвет, выбранный пользователем.

Если вы хотите в начальный момент показать пользователю определенный цвет, это можно сделать в обработчике события формы OnCreate, определив в нем свойство Selected.

Например, пусть при открытии формы Form2 в компоненте Colorbox нужно отобразить текущий цвет фона формы.

Для этого в событии формы OnCreate напишем код:

 

Colorbox1.Selected:=Form2.Color;

 

 Вопросы для самоконтроля

 1. Опишите компонент Memo. Какие свойства он имеет? Опишите методы компонента и приведите примеры их использования.

2. Как вызвать диалог форматирования текста в программе? Какие свойства имеет соответствующий компонент? Приведите пример форматирования текста в поле Memo.

3. Как вызвать диалог выбора цвета? Приведите пример смены цвета фона формы. Опишите принцип роботы с компонентом Colorbox: свойства и пример использования.