Компьютерное проектирование интерфейса пользователя

 














Методические указания

к выполнению лабораторных работ

Компьютерное проектирование интерфейса пользователя











Кривой Рог 2007

Содержание

программный интерфейс приложение редактор

Введение

Лабораторная работа №1

Тема: Создание простейшего приложения "Светофор"

Лабораторная работа №2

Тема: Создание игры «Поймай кнопку»

Лабораторная работа №3

Тема: Создание логической игры

Лабораторная работа №4

Тема: Генератор функций

Лабораторная работа №5

Тема: Создание простейшего калькулятора

Лабораторная работа №6

Тема: Создания элементов интерфейса простейшего графического редактора

Лабораторная работа № 7

Тема: Электронная записная книжка

Лабораторная работа №8

Тема: Текстовый редактор

Лабораторная работа №9

Тема: Создание простейшего графического редактора

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

Введение


Данное методическое пособие предназначено для самостоятельной работы студентов специальности «Гибкие компьютеризированные системы и робототехника» дневной и заочной формы обучения при выполнении лабораторных работ по дисциплине «Компьютерное проектирование интерфейса пользователя».

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

Лабораторная работа №1. Тема: Создание простейшего приложения «Светофор»


Цель: Изучение компонентов Button, Shape, Bevel, Edit, Label.

Краткие теоретические сведения.

Компонент Bevel предназначен для внешнего оформления формы. Стиль отображения Bevel определяется свойством Style, которое может принимать значения bsLowered - утопленный, и bsRaised - приподнятый. А контур компонента определяется свойством Shape, которое может принимать значения: bsBox - прямоугольник, bsFrame - рамка, bsSpacer - пунктирная рамка, bsTopLine, bsBottomLine, bsLeftLine, bsRightLine - соответственной верхняя, нижняя, левая и правая линии. В зависимости от значения Style линии могут быть утопленными или выступающими.

Компонент Shape только условно может быть отнесен к средствам отображения графической информации, поскольку просто представляет собой различные геометрические фигуры, соответствующим образом заштрихованные. Основное свойство этого компонента - Shape (форма), которое может принимать значения:


stRectangle прямоугольник stRoundRect прямоугольник со скругленными углами stEllipse эллипс stSquare квадрат stRoundSquare квадрат со скругленными углами stCircle круг

Другое существенное свойство компонента - Brush (кисть). Это свойство является объектом типа TBrush, имеющим ряд подсвойств, в частности: цвет (Brush.Color) и стиль (Brush.Style) заливки фигуры. Третье из специфических свойство компонента Shape - Pen (перо), определяющее стиль линий.

Простейшей и, пожалуй, наиболее часто используемой кнопкой является кнопка Button, расположенная на странице библиотеки Standard.

Основное с точки зрения внешнего вида свойство кнопки - Caption (надпись). В надписях кнопок можно предусматривать использование клавиш ускоренного доступа, выделяя для этого один из символов надписи. Перед символом, который должен соответствовать клавише ускоренного доступа, ставится символ амперсанта «&». Этот символ не появляется в надписи, а следующий за ним символ оказывается подчеркнутым. Тогда пользователь может вместо щелчка на кнопке нажать в любой момент клавишу Alt совместно с клавишей выделенного символа.

Основное событие любой кнопки - OnClick, возникающее при щелчке на ней. Именно в обработчике этого события записываются операторы, которые должны выполняться при щелчке пользователя на кнопке. Помимо этого есть еще ряд событий, связанных с различными манипуляциями клавишами и кнопками мыши.

Свойство Cancel, если его установить в true, определяет, что нажатие пользователем клавиши Esc будет эквивалентно нажатию на данную кнопку. Это свойство целесообразно задавать равным true для кнопок «Отменить» в различных диалоговых окнах, чтобы можно было выйти из диалога, нажав на эту кнопку или нажав клавишу Esc.

Свойство Default, если его установить в true, определяет, что нажатие пользователем клавиши ввода Enter будет эквивалентно нажатию на данную кнопку, даже если данная кнопка в этот момент не находится в фокусе. Правда, если в момент нажатия Enter в фокусе находится другая кнопка, то все-таки сработает именно кнопка в фокусе.

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

Тексты, отображаемые в компоненте, определяются значением свойства Caption. Его можно устанавливать в процессе проектирования или задавать и изменять программно во время выполнения приложения. Например: .Caption := 'Новый текст';

Цвет фона определяется свойством Color, а цвет надписи - подсвойством Color свойства Font.

Компонент Edit предназначен для отображения, ввода и редактирования однострочных текстов. Имеется возможность оформления объемного бордюра. Основное свойство - Text. Это свойство можно устанавливать в процессе проектирования или задавать программно.

Свойство PasswordChar позволяет превращать окно редактирования в окно ввода пароля. По умолчанию значение PasswordChar равно #0 - нулевому символу. В этом случае это обычное окно редактирования. Но если в свойстве указать иной символ (например, символ звездочки «*»), то при вводе пользователем текста в окне будут появляться именно эти символы, а не те, которые вводит пользователь.

Ход работы.

. Для начала запустим Delphi. При этом автоматически будет создан новый проект с формой. Давайте назовём форму "Светофор". Для этого в Инспекторе объектов на вкладке Свойства находим свойство Caption и задаём заголовок окна Светофор.

. Из вкладки Additional палитры компонентов, вставляем на форму компонент Bevel и располагаем его так, чтобы он служил как обрамление для светофора

. Выделим компонент Bevel и из вкладки Additional вставим компонент Shape.

В Инспекторе объектов на вкладке Свойства компонента Shape, в свойстве Shape стоит наименование stRectangle, меняем его на stEllipse. (для того чтобы изменить свойства компонента, его нужно выбрать, для этого достаточно щелкнуть по нему мышкой). Далее выбираем этот компонент снова и выбираем в меню Правка / Копировать, а затем 2 раза Правка / Вставить - теперь у нас стало 3 таких компонента.



4. Из вкладки Standart палитры компонентов, вставляем на форму компонент Button (Кнопка). Описанным выше образом размножим кнопки до количества 3.

В Инспекторе объектов первой кнопки находим свойство Caption и задаём ему название "Красный", второй кнопки "Желтый", а третьей "Зелёный". Шрифт надписи на кнопке можно изменить, щелкнув по свойству кнопки Fonts. Теперь всё это красиво расположим на форме (как на рисунке).

. Теперь выберем «Красную» кнопку, щелкнем по ней 2 раза и запишем исходный код (пишем только выделенный жирным код - остальное генерируется автоматически):

procedure TForm1.Button1Click(Sender: TObject);.Brush.Color:=clRed; //свойство Brush определяет заливку объекта.Brush.Color:=clWhite;.Brush.Color:=clWhite;

end;

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

Аналогично поступаем с остальными кнопками. Для «Желтой» кнопки:

Shape1.Brush.Color:=clWhite;

Shape2.Brush.Color:=clYellow;.Brush.Color:=clWhite;

и для «Зеленой».Brush. Color:=clWhite;.Brush. Color:=clWhite;.Brush. Color:=clGreen;

6. Сделаем так, чтобы «глаза» светофора подпрыгивали при щелчке мышки. Чтобы создать обработчик события необходимо: выделить объект, перейти в Инспекторе объектов на вкладку События, найти название нужного события и щелкнуть два раза в текстовом окне напротив него. При этом появится заготовка процедуры, между begin и end мы пишем необходимые операторы.

В обработчике события OnMouseDown каждого из «глаз» поместим код:.Top:= shape1.Top+10; // элемент переместится на 10 единиц вниз по вертикали - вернется на место

Это событие возникает, когда пользователь нажал левую клавишу мыши на объекте.

В обработчике события OnMouseUp напишем:.Top:= shape1.Top-10; // элемент переместится на 10 единиц вверх по вертикали

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

!!!! Не забудьте поменять номера компонентов shape2, shape3.

7. Для непонятливых сделаем подсказку.

Свойству ShowHint каждого из компонентов Shape («глаза светофора») установим значение True. В свойстве Hint напишем сам текст подсказки, например, «Нажми меня!» или любое другое, подходящее к данному случаю.


. Усложняем наше приложение. Сделаем так, чтобы при запуске приложения на экране появлялось окно с запросом пароля.

Создайте новую форму, нажав на кнопку Новая форма.

Для Form1 (нашей первой, главной формы, не забудьте щелкнуть по ней, выбрав в качестве объекта) в обработчике события OnShow (При появлении) напишем:

procedure TForm1.FormShow(Sender: TObject);

form2.Showmodal

end;

Это означает, что при появлении окна-формы1 на экран выскочит окно-форма-2.

Зададим заголовок форме «Смена пароля». Подсвойству biSystemMenu свойства BorderIcons формы (подсвойства появляются, когда нажмешь на плюсик) зададим значение false. Это означает, что никаких кнопок в заголовке окна не будет.

Добавим в список переменных модуля Unit2 переменную логического типа. Для этого необходимо нажать на кнопку Показать список модулей (Ctrl+F12) и выбрать в списке нужный.


Найдем в модуле блок описания глобальных переменных и добавим строку, выделенную жирным.

var: TForm2;

f:boolean;

В обработчике события OnCreate form2 запишем код:

procedure TForm2.FormCreate(Sender: TObject);

f:=false

end;

При создании формы переменная f инициализируется с начальным значением false.

Для обработчика события OnClose:TForm2.FormClose(Sender: TObject; var Action: TCloseAction);f=false then form1.close;;

Таким образом, если какой-то умник нажмет Alt+F4 для закрытия окна ввода пароля, он ничего не добьется - автоматически закроется и главная форма, если пароль не был введен правильно.

. Поместите на Form2 компонент Label (Метка). Определите для него шрифт MS Sans Serif 12 полужирный (для того, чтобы изменить шрифт необходимо щелкнуть мышкой по кнопке с тремя точками напротив свойства Font компонента в Инспекторе объектов). Разместим на новой форме еще два компонента - кнопку Button и поле для ввода текста Edit. Переименуем и разместим их как показано на рисунке.



Удалим текст из свойства Text компонента Edit, установим его свойство AutoSize в false, а свойству PasswordChar присвоим значение *

В обработчике события OnClick для кнопки Button1 напишем код:

procedure TForm2.Button1Click(Sender: TObject);edit1.Text='secret' then:=true; form2.Close;showmessage('Пароль введен неверно!');

Это означает, что если пароль введен верно (это secret), то окно ввода пароля закроется и на экране появится главное окно, иначе - программа выдаст сообщение о неправильном вводе.

Выполнить самостоятельно:

. Сделать так, чтобы при нажатии Enter в окне ввода пароля было аналогично нажатию кнопки ОК. (Для этого используем событие OnKeyPress для компонента Edit1).

. Измените заголовок окна сообщения о неправильном вводе пароля на «Ошибка!». При неправильном вводе пароля фокус должен возвращаться в поле ввода.

. Сделайте так, чтобы при троекратном неправильном вводе окно автоматически закрывалось.

Результатом выполнения данной лабораторной работы являются созданный согласно заданию программный продукт. Выполненное задание должно быть предъявлено преподавателю в электронном виде. В ходе защиты лабораторной работы студент должен продемонстрировать свои навыки работы с изученными компонентами и методами проектирования интерфейса пользователя.

Лабораторная работа №2. Создание игры «Поймай кнопку»


Цель: Изучение особенностей компонента Timer.

Краткие теоретические сведения.

Компонент Timer (палитра System) позволяет задавать в приложении интервалы времени. Таймер находит многочисленные применения: синхронизация мультипликации, закрытие каких-то окон, с которыми пользователь долгое время не работает, включение хранителя экрана или закрытие связей с удаленным сервером при отсутствии действий пользователя, регулярный опрос каких-то источников информации, задание времени на ответ в обучающих программах - все это множество задач, в которых требуется задавать интервалы времени, решается с помощью таймера.

Таймер - невизуальный компонент, который может размещаться в любом месте формы. Он имеет два свойства, позволяющие им управлять: Interval - интервал времени в миллисекундах и Enabled - доступность. Свойство Interval задает период срабатывания таймера. Через заданный интервал времени после предыдущего срабатывания, или после программной установки свойства Interval, или после запуска приложения, если значение Interval установлено во время проектирования, таймер срабатывает, вызывая событие OnTimer. В обработчике этого события записываются необходимые операции.

Если задать Interval = 0 или Enabled = false, то таймер перестает работать. Чтобы запустить отсчет времени надо или задать Enabled = true, если установлено положительное значение Interval, или задать положительное значение Interval, если Enabled = true.

Например, если требуется, чтобы через 5 секунд после запуска приложения закрылась форма - заставка, отображающая логотип приложения, на ней надо разместить таймер, задать в нем интервал Interval = 5000, а в обработчик события OnTimer вставить оператор Close, закрывающий окно формы.

Ход работы

1. Для оформления окна программы понадобится три компонента - прыгающая командная кнопка (Button1), кнопка выхода (Button2) и таймер. Примерный вид формы показан на рисунке:



. Зададим первой кнопке следующие свойства:

Caption - Введем заголовок.

TabStop - False. Это свойство разрешает выбирать элемент управления клавишей TAB. В этой игре клавиатурой пользоваться нельзя.

Visible - false. Сначала кнопка должна быть невидима, чтобы пользователь не знал, где она находится.

Height - 30, Width - 80

Left -10, Top -10. В левом верхнем положении расстояние между кнопкой и краями формы 10 пикселей.

. Теперь необходимо вычислить, какой размер будет иметь окно программы. Рисунок иллюстрирует, как именно это было сделано.


Зададим свойству формы ClientWidth (Внутренняя ширина) - значение 300, свойству ClientHeight (Внутренняя высота) - 200.

Чтобы размер окна нельзя было изменить в ходе работы программы, зададим свойству формы BorderStyle - bsSingle

. Для кнопки «Выход» Button2 определим свойства:

Left - 110, Top - 160, Width - 80, Height - 30.- True. Фокус ввода всегда будет принадлежать этой кнопке и нажатие клавиши Enter будет связано только с ней..

. Разместим на форме компонент Timer (вкладка System). Свойству Interval зададим значение 500.

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

Создадим для компонента Timer обработчик события OnTimer (Сигнал таймера).

procedure TForm1.Timer1Timer(Sender: TObject); i:integer;//описываем локальную переменную

begin

i:=random(9); //случайное значение в диапазоне от 0 до 9

button1.Visible:=true;.Top:=10+50*(i div 3);.Left:=10+100*(i mod 3);;

Таким образом, при каждом сигнале таймера, положение кнопки (свойства Left и Top) будут меняться случайным образом.

. Обработаем щелчок на кнопке Button1 следующим образом:

procedure TForm1.Button1Click(Sender: TObject);.Caption:='Готово!';.enabled:=false;.enabled:=false;

end;

Если щелчок произошел, значит, игра закончилась победой. Чтобы сообщить об этом, изменяем надпись на кнопке и отключаем кнопку и таймер (свойство Enabled)

. В завершении программы создадим еще два обработчика:

При щелчке на кнопке Button2 (Выход):

procedure TForm1.Button2Click(Sender: TObject);

begin.Close;

Для инициализации процедуры генерации случайных чисел создадим процедуру обработки загрузки формы:

procedure TForm1.FormCreate(Sender: TObject);

begin;

Выполнить самостоятельно:

1.Добавить две кнопки «Быстрее» и «Медленнее». Щелчок по одной из них будет увеличивать значение интервала таймера на 100 миллисекунд, а по другой - уменьшать его в 2 раза.



Результатом выполнения данной лабораторной работы являются созданный согласно заданию программный продукт. Выполненное задание должно быть предъявлено преподавателю в электронном виде. В ходе защиты лабораторной работы студент должен продемонстрировать свои навыки работы с изученными компонентами и методами проектирования интерфейса пользователя.


Лабораторная работа №3. Тема: Создание логической игры


Цель: Изучение возможностей использования свойства Tag и объекта Sender.

Краткие теоретические сведения.

Целью данной лабораторной работы является написание следующей программы. Игровая доска содержит семь клеток. На трех левых клетках стоят красные фишки, на трех правых - синие. Центральная клетка пуста. Задача заключается в том, чтобы, делая допустимые ходы, поменять фишки местами. Вид рабочего окна игры представлен ниже.


Правила ходов такие:

. Красные фишки могут ходить только вправо, синие - только влево.

. Ходить разрешается только на свободное поле.

. Разрешены перемещения на соседнее поле и «прыжок» через фишку.

В ходе решения головоломки кнопки будут двигаться, а вид окна изменяться. Поэтому необходимо точно задать геометрические параметры объектов. Настраивать параметры будем, изменяя свойства Top, Left, Height, Width компонентов. Параметры должны быть следующими:



В чем заключается ход в игре? В том, что одна из фишек-кнопок переносится на свободное место. Это значит, что достаточно указать, какой фишкой надо пойти. Если фишка может сделать ход, то он только один.

Итак, пользователь может выбрать ход, щелкнув на одной из кнопок. То есть мы будем обрабатывать событие OnClick (При щелчке).

Но мы должны различать кнопки, а также знать, где они находятся и где находится свободная клетка. Поэтому мы поступим так: будем хранить дополнительные данные прямо в свойствах объекта-кнопки. Для этого нам нужно «свободное» свойство. Такое свойство есть: все компоненты системы Delphi предоставляют свойство Tag, которое программист может использовать по своему усмотрению.

Свойство Tag может хранить любое целое число. Нам нужно хранить два числа. Во-первых, номер клетки, в которой находится кнопка, а во вторых, признак «цвета» фишки (от него зависит, в какую сторону она может ходить). Эти данные легко «упаковать» в одно целое число: умножим номер клетки на 2 и, если фишка синяя, прибавим к нему единицу. Такое значение легко «разобрать» обратно на составляющие. Разделим его на 2. Частное даст номер клетки, а остаток будет признаком цвета фишки.

Ход работы.

1. Разместим на форме компонент Panel (401 x 65). На панели расположим 6 компонентов BitBtn (панель Additional) размером 49 на 49. Свойство Top всех компонентов будет равно 8, Left - 64,120,232,288,344.



. Создайте при помощи графического редактора изображения красного и синего треугольников или любых других фигур на ваш вкус и сохраните их в формате bmp. Затем, используя свойство Glyph компонента, поместите изображения на кнопки.


3. Теперь можно задать значения свойства Tag для всех кнопок. Поочередно выберем фишки слева направо и зададим для свойства Tag значения, приведенные в таблице.


Значение свойстваКомментарий2первая клетка, красная фишка4вторая клетка, красная фишка6третья клетка, красная фишка11пятая клетка, синяя фишка13шестая клетка, синяя фишка15седьмая клетка, синяя фишка

. Опишем глобальную переменную n, в которой будем хранить номер пустой клетки и переменную win, в которой будет содержаться количество ходов.

var1: TForm1;

n:integer=4;:integer=24;

Здесь мы не только описываем нужные переменные, но и сразу присваиваем им начальное значение. Первоначально у нас пуста четвертая клетка, отсюда и выбор этого числа, 24 - максимально возможное число ходов.

. Выберем первую кнопку и создадим обработчик OnClick для нее.

procedure TForm1.BitBtn1Click(Sender: TObject);i,c,k,ak:integer;Sender as TBitBtn do:=Tag div 2;:=Tag mod 2;:=n-i;:=abs(k);ak<3 then((c=0) and (k>0)) or

((c=1) and (k<0)) then:=tag+2*k;:=left +56*k;:=win-ak;:=i;;;win=0 then:=Vaw!!!!';.Color:=clFuchsia; //меняем цвет панели

panel1.Enabled:=false; /все кнопки, находящиеся на панели становятся недоступными/;;


Обратите внимание на то, что в процедуру передается параметр - объект Sender. Он представляет именно тот объект, который вызвал событие, и может дать доступ к его свойствам. Но напрямую это не получится. Программе надо специально указать, что объект Sender в данном случае следует считать кнопкой. Для этого служит ключевое слово as. После него указывают тип, которому на самом деле принадлежит объект Sender: Sender as TBitBtn

6. Для каждой из кнопок на вкладке События в окне напротив OnClick выберите из списка уже описанную нами процедуру.



Выполнить самостоятельно:

Попробуйте выиграть!!!

Результатом выполнения данной лабораторной работы являются созданный согласно заданию программный продукт. Выполненное задание должно быть предъявлено преподавателю в электронном виде. В ходе защиты лабораторной работы студент должен продемонстрировать свои навыки работы с изученными компонентами и методами проектирования интерфейса пользователя.


Лабораторная работа №4. Генератор функций


Цель: Изучение компонента PaintBox и методов рисования на канве. Компонент TrackBar

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

Канва имеет свойство Pixels. Это свойство представляет собой двумерный массив, который отвечает за цвета канвы. Например, Canvas.Pixels[10,20] соответствует цвету пикселя, 10-го слева и 20-го сверху. С массивом пикселей можно обращаться как с любым свойством: изменять цвет, задавая пикселю новое значение, или определять его цвет по хранящемуся в нем значению. Например, Canvas.Pixels[10,20] := 0 или Canvas.Pixels[10,20] := clBlack - это задание пикселю черного цвета.

Канва - объект класса TCanvas имеет множество методов, которые позволяют рисовать графики, линии, фигуры с помощью свойства Pen - перо. Это свойство является объектом, в свою очередь имеющим ряд свойств. Одно из них уже известное вам свойство Color - цвет, которым наносится рисунок. Второе свойство - Width (ширина линии). Ширина задается в пикселях. По умолчанию ширина равна 1. Свойство Style определяет вид линии.

Фигуры в общем случае рисуются не пустыми, а закрашенными с помощью свойства канвы Brush - кисть. Свойство Brush является объектом, имеющим в свою очередь ряд свойств. Свойство Color определяет цвет заполнения. Свойство Style определяет шаблон заполнения (штриховку). По умолчанию значение Style равно bsSolid, что означает сплошное закрашивание цветом Color.

Компонент TrackBar представляет собой элемент управления в виде ползунка, который пользователь может перемещать курсором мыши или клавишами во время выполнения. Таким образом, пользователь может управлять какими-то процессами: громкостью звука, размером изображения и т.п. Основное свойство компонента - Position. Это свойство можно задавать во время проектирования или программно во время выполнения. При перемещении пользователем ползунка можно прочитать значение Position, характеризующее позицию, в которую пользователь переместил ползунок. Свойство Position - целое, значение которого может изменяться в пределах, задаваемых свойствами Min и Мах.

Ход работы

. После запуска Delphi программа имеет только одно окно Form1, у которого сразу переименовываем заголовок (свойство Caption) на «Генератор функций». Устанавливаем свойство Form1.Position в poDesktopCenter, чтобы окно при каждом запуске и при любом экранном разрешении всегда было ровно посередине экрана. Устанавливаем свойство Form1.BorderStyle в bsSingle, для неизменяемого размера окна. Оставляем во вложенных свойствах BorderIcons только biSystemMenu в true, остальные в false. Это для того, чтобы окно нельзя было свернуть в значок, развернуть во весь экран и окно имело иконку в заголовке.

. Устанавливаем в форму компонент PaintBox (вкладка System), два компонента RadioButton, один компонент CheckBox, три кнопки Button (все компоненты расположены на панели Standard) и ползунок прокрутки TrackBar, расположенный на вкладке Win32. Расположим компоненты, как это указано на рисунке ниже.

. RadioButton1.Caption переименовываем в "Sin". Этот флаг будет признаком рисования синусоиды. RadioButton2.Caption переименовываем в "Cos" - косинусоида. Начальное значение свойства Checked для RadioButton1 устанавливаем в true.

. CheckBox1.Caption переименовываем в "Все". Если этот флаг установлен, то будет рисоваться два графика.

. Названия кнопок Button1 - "Старт", Button2 - "Стоп (пауза)" и Button3 - "Выход". Названия на кнопках меняются через свойство Caption. Теперь назначение этих кнопок понятно.

. Компонент TrackBar1 свойство минимального значения Min устанавливаем в 1, максимальное значение Max - 50.

. Для PaintBox1, на котором будет непосредственно рисоваться график задаем размеры высоты Height=140, ширина.

. Сразу после слова implementation в модуле окна объявляем глобальные переменные, которые будут доступны из любой процедуры в этом модуле. Var stop:boolean; // признак рисования x:Integer; // координата оси X

. В обработчике события OnClick для кнопки Button1 («Старт») напишем следующее:

procedure TForm1.Button1Click(Sender: TObject);Var y:Integer; // ось Ybeginif x=0 then // если точка в начале координат, то:beginPaintBox1.Canvas.Brush.Color:=clWhite; // цвет фона белыйPaintBox1.Canvas.FillRect(ClientRect); // заливка всей рабочей областиend;stop:=false; // флаг старта процесса рисованияWhile not stop do // бесконечный цикл, пока флаг остановки не поднят:beginif (RadioButton1.Checked)or(CheckBox1.Checked) then // если установлен "Sin" или "Все", то:beginy:=Round(Sin(pi*x/100)*50)+70; // вычисление положения синусоидыPaintBox1.Canvas.Pixels[x,y]:=clBlack; // нарисовать черную точкуend;if (RadioButton2.Checked)or(CheckBox1.Checked) then // если установлен "Cos" или "Все", то:beginy:=Round(Cos(pi*x/100)*50)+70; // вычисление положения косинусоидыPaintBox1.Canvas.Pixels[x,y]:=clBlack; // нарисовать черную точкуend;inc(x); // увеличить значение X на едицину. Аналог X:=X+1if x>500 then // если X вышел за пределы PaintBox1, то:beginx:=0; // установить X на начало координатPaintBox1.Canvas.Brush.Color:=clWhite; // Цвет фона белыйPaintBox1.Canvas.FillRect(ClientRect); // Очистка рабочей области PaintBox1end;Sleep(TrackBar1.Position); // Процедура "засыпает" на заданное время в миллисекундахApplication.ProcessMessages; // Обработка всей очереди сообщенийend;end;

Коротко расскажем работу этой процедуры. Как только нажата кнопка "Старт" Компонент PaintBox1 очищается и начинается бесконечный цикл While, выйти из которого можно только, пока переменная Stop не примет значение true. Это можно сделать кнопкой Button2, соответствующая процедура которой обработается во время Application.ProcessMessages. С помощью бегунка TrackBar1 можно менять скорость рисования кривой. Этот параметр передается в команду Sleep.

10. Процедура нажатия на кнопку остановки Button2:

procedure TForm1.Button2Click(Sender: TObject);

begin:=true; // установить флаг остановки процесса рисования;

. Процедура создания окна Form1OnCreate:

procedure TForm1.FormCreate(Sender: TObject);

begin

x:=0; // начальное значение X

end;


. Если нажата кнопка "Выход", то реакция на это событие будет таким:

procedure TForm1.Button3Click(Sender: TObject); begin Close; // закрыть окно end;

13. И реакция перед закрытием окна OnClose. Без этой процедуры, если рисование включено, то окно не закроется.TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Stop:=true; // остановить (если включен) цикл рисования end; После запуска программы, установки флажка "Все" и нажатии на кнопку "Старт" на экране отобразится график:




Выполнить самостоятельно:

. Добавьте CheckBox «Инвертировать», при выборе которого цвет области построения становится черным, а графики функций вырисовываются белым цветом.

2. Сделайте так, чтобы в неинвертированном режиме синусоида изображалась красным цветом, а косинусоида - синим.

Результатом выполнения данной лабораторной работы являются созданный согласно заданию программный продукт. Выполненное задание должно быть предъявлено преподавателю в электронном виде. В ходе защиты лабораторной работы студент должен продемонстрировать свои навыки работы с изученными компонентами и методами проектирования интерфейса пользователя.


Лабораторная работа №5. Создание простейшего калькулятора


Цель: Изучение структуры CASE и особенностей работы с математическими функциями. Преобразование типов и обработка исключительных ситуаций.

Краткие теоретические сведения.

Математические функции языка Object Pascal


abs(x)Модуль аргумента - arctan(x)Арктангенс аргумента (угол в радианах)sin(x)Синусcos(x)Косинусexp(x)Экспонента - sqr(x)Квадрат аргумента - sqrt(x)Корень квадратный аргумента - ln(x)Логарифм натуральныйfrac(x)Дробная часть числаint(x)Целая часть числаtrunc(x)Отбрасывает дробную часть числаround(x)Округляет x до ближайшего целого значенияpip=3.141592653…random(x)Псевдослучайное число, расположенное в диапазоне 0…(х-1)

Так как функции тангенса и котангенса в языке Pascal отсутствуют, они выражаются через значения синуса и косинуса:


Десятичный логарифм можно выразить следующим способом -



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



Примеры выражений:



В Object Pascal это выражение будет выглядеть так:


0.3*exp(5*ln((sqr(sin(x))-sqr(cos(x)))/exp(x))*sqrt(abs(cos(x)-1))/sqrt(exp(3*ln(abs(x))))


При использовании окон редактирования для вывода, ввода и редактирования чисел необходимо использовать функции взаимного преобразования строк и чисел. FloatToStr и IntToStr преобразуют соответственно вещественные и целочисленные переменные в строковые. Функция StrToFloat предназначена для преобразование строки в значение с плавающей запятой, и StrToInt - преобразование строки в целое значение.

Для реакции на конкретный тип исключительной ситуации применяется блок try..except. В простейшем виде синтаксис его следующий:<0ператоры, которые могут вызвать исключительную ситуацию>

< Операторы >;;

Выполнение блока начинается с секции try. При отсутствии исключительных ситуаций только она и выполняется. Секция except получает управление в случае если они возникли. Например:= 5 /0;

showmessage(Делить на ноль нельзя!);;

Ход работы

. Разместим на форме 2 компонента Panel, 16 компонентов Button и окошко редактирования Edit. Расположим их на форме следующим образом.


Размеры панелей и кнопок могут быть произвольными, в данном примере были использованы следующие параметры:


Panel1Panel2Button…Width-180Width-70Width-50Height - 235Height - 235Height - 50

Очистим свойство Text компонента Edit1, а свойствам Caption компонентов зададим соответствующие значения.

. Итак, приступим к коду. Добавим в наш код 4 глобальных переменных.

var: TForm1; ,p,r:real;

//они будут сохранять числа введенные пользователем (i- значение первого введенного числа, р - второго, r - полученный результат):integer;

//режим калькулятора (умножить, разделить и т.д)

Переменная mode будет содержать числовое значение действия: 1 - прибавление, 2 - вычитание, 3 - деление, 4 - умножение.

. Теперь приступим к нашим кнопкам. В каждой цифровой кнопке обработаем событие OnClick. Код будет идентичен для всех цифровых кнопок (от 1 до 10-й). Приведем пример кода для первой кнопки (цифра 1):

procedure TForm1.Button1Click(Sender: TObject);

edit1.Text:=edit1.Text+'1';// для всех остальных кнопок заменяйте 1 на нужное вам число

end;

Далее пишем обработчики OnClick для кнопок операций.

Для кнопки «+»:TForm1.ButtonPlusClick(Sender: TObject);:=StrToFloat(Edit1.Text);:=1;

Edit1.Text:=''; //это две одинарные кавычки

end;

Для кнопки «-»

procedure TForm1.ButtonMinusClick(Sender: TObject);:=StrToFloat(Edit1.Text);:=2;.Text:='';;

Для кнопки «*»

procedure TForm1.ButtonMultiplyClick(Sender: TObject);:=StrToFloat(Edit1.Text);:=3;.Text:='';;

Для кнопки «/»

procedure TForm1.ButtonDIVClick(Sender: TObject);:=StrToFloat(Edit1.Text);:=4;.Text:='';;

Кратко поясним, что мы сделали. При нажатии на кнопку мы сохраняем значения введенного числа в переменной I, затем переменной mode присваиваем значения действия. Теперь у нас есть все необходимые данные для обработки события OnClick для кнопки "=".

procedure TForm1.ButtonRezultClick(Sender: TObject);mode of

:begin:=StrToFloat(Edit1.Text);:=i+p;.Text:=FloatToStr(r);;

:begin:=StrToFloat(Edit1.Text);:=i-p;.Text:=FloatToStr(r);;

:begin:=StrToFloat(Edit1.Text);:=i*p;.Text:=FloatToStr(r);;

:begin:=StrToFloat(Edit1.Text);:=i/p;.Text:=FloatToStr(r);;;;

Создадим обработчик для кнопки С (Сброс):

procedure TForm1.ButtonResetClick(Sender: TObject);.Text:='';:=0; i:=0; p:=0;;

Чтобы при появлении окна калькулятора фокус был передан окну ввода напишем обработчик OnShow для Form1.

procedure TForm1.FormShow(Sender: TObject);

edit1.SetFocus;

end;

Аналогичным образом, сделаем так, чтобы при нажатии кнопок «=» и «С», а также кнопок математических операций, фокус передавался окну ввода.

Выполнить самостоятельно

(создание простенького калькулятора):

1.Настроить параметры формы таким образом, чтобы размеры окна нельзя было изменить и кнопка «Развернуть /Maximize/» отсутствовала.

2.Добавить кнопку «,» для ввода разделителя между целой и дробной частью числа. Для этого в обработчик OnClick кнопки добавим:

if pos(',',edit1.Text)<>0 then exit // если символ «,» в строке уже имеется

else edit1.Text:=edit1.Text+','

3.Добавить кнопку «+/-» для изменения знака числа на противоположный.

procedure TForm1.BitBtn2Click(Sender: TObject);s:string;:=Edit1.Text;s[1]='-' then delete(s,1,1) else('-',s,1);.Text:=s;

end;

4.Запретить ввод с клавиатуры в текстовое окно любых символов кроме цифровых и «-» (минус), «,» (запятая) - смотрим в конспект лекций.

5.Создать кнопки для следующих математических операций:

·возведение в степень r:=exp(p*ln(i));

·целочисленное деление (div) и остаток от деления (mod)- для преобразования типов использовать функцию round;

·возведение в квадрат (sqr);

·извлечение квадратного корня (sqrt);

·вычисления натурального и десятичного логарифма;

·вычисления sin-са, cos-са и tg-са аргумента;

·вычисления экспоненты (e^x);

·для вычисления 1/x;

·ввода числа p;

·для нахождения факториала числа.

Результатом выполнения данной лабораторной работы являются созданный согласно заданию программный продукт. Выполненное задание должно быть предъявлено преподавателю в электронном виде. В ходе защиты лабораторной работы студент должен продемонстрировать свои навыки работы с изученными компонентами и методами проектирования интерфейса пользователя.


Лабораторная работа №6. Создание элементов интерфейса простейшего графического редактора


Цель: Изучение компонентов ColorGrid, SpinEdit, RadioGroup, ListBox, ColorDialog.

Краткие теоретические сведения.

ColorGrid - пример компонента, используемого для создания таблицы цветов, в которой пользователь выбирает требуемый цвет. Компонент визуальный. Свойство GridOrdering определяет внешний вид сетки (количество строк и столбцов). Свойство ForegroundColor определяет цвет, выбранный пользователем левой клавишей, BackgroundColor - правой.- окно редактирования в комбинации с кнопкой-счетчиком. Свойства MinValue и МахValue компонента задают соответственно минимальное и максимальное значения чисел, свойство Increment задает приращение числа при каждом нажатии на кнопку. Свойство Value определяет текущее значение числа. Это свойство можно читать, чтобы узнать, какое число задал пользователь.

Радиокнопки образуют группы взаимосвязанных индикаторов, из которых обычно может быть выбран только один. Компонент RadioGroup - панель группы радиокнопок, которая может содержать регулярно расположенные столбцами и строками радиокнопки. Надпись в левом верхнем углу панели определяется свойством Caption. А надписи кнопок и их количество определяются свойством Items, имеющим тип TStrings. Щелкнув на кнопке с многоточием около этого свойства в окне Инспектора Объектов, вы попадете в редактор списков строк. В нем вы можете занести надписи, которые хотите видеть около кнопок, по одной в строке. Сколько строчек вы запишете - столько и будет кнопок.

Определить, какую из кнопок выбрал пользователь, можно по свойству ItemIndex, которое показывает индекс выбранной кнопки. Индексы, как всегда в Delphi, начинаются с 0. По умолчанию ItemIndex = -1, что означает отсутствие выбранной кнопки.

Компонент ListBox отображает списки строк. ListBox отображает список в раскрытом виде и автоматически добавляет в список полосы прокрутки, если все строки не помещаются в окне компонента.

Основное свойство компонента, содержащее список строк, - Items, имеющее тип TStrings. Заполнить его во время проектирования можно, нажав кнопку с многоточием около этого свойства в окне Инспектора Объектов. Во время выполнения работать с этим свойством можно, пользуясь свойствами и методами класса TStrings - Clear, Add и другими. Номер выбранной строки можжно узнать из свойства ItemIndex. Если ни одна строка не выбрана, то ItemIndex = -1.

Компонент ColorDialog вызывает диалоговое окно выбора цвета. Основное свойство компонента ColorDialog - Color. Это свойство соответствует тому цвету, который выбрал в диалоге пользователь.

Ход работы

Часть 1.

1. Создайте новый проект и сохраните его в своей папке.

Поместите на форму компонент Shape (палитра Aditional) и ColorGrid (палитра Samples). Свойству Shape компонента Shape присвоить значение stRectangle. Свойству GridOrdering компонента ColorGrid присвоить значение go8x2.

Расположить компоненты на форме следующим образом:



. Создадим обработчик события OnChange компонента ColorGrid

Shape1.Pen.Color:=ColorGrid1.ForegroundColor;.Brush.Color:=ColorGrid1.BackgroundColor;

Запустим программу и посмотрим как она работает. Левым щелчком по палитре выбирается цвет контура (передний цвет), правым - цвет фона (задний цвет).

. Используя компонент SpinEdit (палитра Samples) создадим возможность изменения толщины контура от 1 до 50.

Свойству MaxValue зададим значение 50, MinValue - 1

В обработчике события OnChange компонента SpinEdit запишем:

shape1.Pen.Width:=SpinEdit1.Value;

Расположим компонент Label (свойство Caption - Контур) и SpinEdit, как это показано на рисунке ниже.

. Расположим на форме компонент RadioGroup.

Присвоим его свойству Captions и свойству Items (содержит названия строк списка) значения, как это показано на рисунке ниже. Сделаем так, чтобы по умолчанию был выбран первый компонент списка. Для этого свойству ItemIndex компонент а RadioGroupзададим значение 0 (нумерация в списке начинается с нуля)



5. В обработчике OnClick для RadioGroup1 запишем:

if RadioGroup1.ItemIndex=0 then Shape1.Shape:=stCircle; {если выбран первый элемент списка}

if RadioGroup1.ItemIndex=1 then Shape1.Shape:=stEllipse;RadioGroup1.ItemIndex=2 then Shape1.Shape:=stRoundRect;RadioGroup1.ItemIndex=3 then Shape1.Shape:=stRoundSquare;RadioGroup1.ItemIndex=4 then Shape1.Shape:=stSquare;

6. Расположим на форме компоненты Label (свойство Caption - Способ заливки) и компонент ListBox. В Редакторе списка строк компонента ListBox (вызывается щелчком по свойству Items) введите значения, как это показано на рисунке выше.

. В обработчик OnClick компонента ListBox введем следующий код:

if ListBox1.Selected[0] then Shape1.Brush.Style:=bsSolid;ListBox1.Selected[1] then Shape1.Brush.Style:=bsClear;ListBox1.Selected[2] then Shape1.Brush.Style:=bsBDiagonal;ListBox1.Selected[3] then Shape1.Brush.Style:=bsFDiagonal;ListBox1.Selected[4] then Shape1.Brush.Style:=bsCross;ListBox1.Selected[5] then Shape1.Brush.Style:=bsDiagCross;ListBox1.Selected[6] then Shape1.Brush.Style:=bsHorizontal;ListBox1.Selected[7] then Shape1.Brush.Style:=bsVertical;

Запустим программу и посмотрим как она работает.

Часть 2.

1.Создайте новый проект и сохраните его в своей папке.

2.Наша задача добиться следующего эффекта: при щелчке мышки по форме на ней должна появиться фигура. Ели клавиша Shift не нажата, это будет круг, если нажата - квадрат. Для этого в обработчике события OnMouseDown формы напишем код:

if Button=mbLeft thenssShift in Shift then.Rectangle(x-10,y-10,x+10,y+10)canvas.Ellipse(x-10,y-10,x+10,y+10);

3.Сделаем так, чтобы при движении курсора мыши в заголовке формы отображались его координаты. В обработчике OnMouseMove запишем:

caption:=Format('Фигуры: X=%d, Y=%d', [X,Y]);

4.Поместим на форму компоненты MainMenu и ColorDialog.

Создадим главное меню, содержащее следующие пункты:

Файл:Цвет:Размер:

НовыйЦвет карандашаУвеличить карандаш

ВыходЦвет кистиУменьшить карандаш

Увеличить фигуру

Уменьшить фигуру

.Создадим глобальную переменную Radius, инициализируем ее при создании формы значением 10, и заменим ею константы при создании фигур в обработчике события OnMouseDown:

if button=mbLeft thenssShift in Shift then canvas.rectangle(x-radius,y-radius,x+radius,y+radius)canvas.Ellipse(x-radius,y-radius,x+radius,y+radius);

6.Обработаем события OnClick пунктов меню следующим образом:

Новый:

repaint;

Выход:.Close;

Цвет карандаша:.Color:=canvas.Pen.color;colordialog1.Execute then.Pen.Color:=colordialog1.Color;

Цвет кисти:.Color:=canvas.brush.color;colordialog1.Execute then.brush.Color:=colordialog1.Color;

Увеличить карандаш:.Pen.Width:=canvas.Pen.Width+2;

Уменьшить карандаш:

canvas.Pen.Width:=canvas.Pen.Width-2;Canvas.Pen.Width<3 then canvas.Pen.Width=3; {ограничение на минимальную толщину карандаша)

Увеличить фигуру:

radius:=radius+5;

Уменьшить фигуру:

radius:=radius-5;

Выполнить самостоятельно:

. Создать обработчик события OnClick пункта меню Выход с запросом о выходе из программы.

. Создать ограничение на увеличение размера карандаша.

. Создать ограничения на увеличение и уменьшение (не меньше чем Radius-10) размера фигуры.

Результатом выполнения данной лабораторной работы являются созданный согласно заданию программный продукт. Выполненное задание должно быть предъявлено преподавателю в электронном виде. В ходе защиты лабораторной работы студент должен продемонстрировать свои навыки работы с изученными компонентами и методами проектирования интерфейса пользователя.


Лабораторная работа № 7. Электронная записная книжка


Цель: Изучение компонентов многостраничных панелей TabControl и PageControl.

Краткие теоретические сведения.

Многостраничные панели позволяют экономить пространство окна приложения, размещая на одном и том же месте страницы разного содержания. Каждая создаваемая вами страница компонента TabControl и PageControl является объектом типа TTabSheet. Это панель, на которой можно размещать любые управляющие компоненты, окна редактирования и т.п.

Страница имеет следующие основные свойства:


NameИмя, по которому можно ссылаться на страницуCaption Надпись, которая появляется на ярлычке закладки PageIndex Индекс страницы, по которому можно ссылаться на страницу ImageIndex Индекс изображения, которое может появляться на ярлычке закладки

Из общих свойств компонента TabControl и PageControl можно отметить:


StyleОпределяет стиль отображения компонента: tsTabs - закладки, tsButtons - кнопки, tsFlatButtons - плоские кнопки. MultiLineОпределяет, будут ли закладки размещаться в несколько рядов, если все они не помещаются в один ряд.TabPositionОпределяет место расположения ярлычков закладок: tpBottom - внизу, tpLeft - слева, tpRight - справа и tpTop - вверху компонента. TabHeight и TabWidthВысота и ширина ярлычков закладок в пикселях. Если значения этих параметров заданы равными 0, то размеры ярлычков определяются автоматически по размерам надписей на них ImagesСсылка на компонент ImageList, который содержит список изображений на ярлычках. Свойства ImageIndex страниц содержат индексы, соответствующие именно этому списку ScrollOppositeОпределят способ перемещения закладок при размещении их в несколько рядов. ActivePageИмя активной страницы Pages[Index: Integer]Доступ к странице по индексу (первая страница имеет индекс 0). Свойство только для чтения PageCountКоличество страниц. Свойство только для чтения

Принципиальное отличие компонента TabControl от PageControl заключается в том, что TabControl не имеет множества панелей (страниц). Компонент представляет собой одну страницу с управляющим элементом типа кнопки со многими положениями. И надо написать соответствующие обработчики событий OnChanging и OnChange, чтобы определить, что именно должно происходить на панели при переключениях закладок пользователем. У компонента имеется еще одно свойство - MultySelect, позволяющее множественный выбор закладок. Если это свойство установлено в true, то в обработчиках событий надо описать реакцию на такой выбор пользователя.

Число закладок и их надписи определяются свойством Tabs типа TStrings. В нем вы можете задать надписи закладок. Сколько строчек надписей вы укажете, столько будет закладок. Текущее состояние переключателя определяется свойством TabIndex. Вы можете установить его в процессе проектирования, чтобы определить исходное состояние переключателя. А затем в обработчиках событий OnChanging и OnChange можете читать это свойство, чтобы определить, что именно выбрал пользователь.

Визуальные иневизуальные компоненты для создания СУБД в среде Delphi, а также методы создания таблиц БД описаны в методических указаниях к выполнению контрольных робот и в конспекте лекций.

Ход работы

Рассмотрим процесс создания приложения, имитирующего записную книжку со списком телефонов. Вид готового приложения будет следующим:


. Создадим при помощи DataBase DeskTop таблицу notebook.db со следующими полями (процесс создания таблиц и псевдонимов подробно описан в рекомендациях по выполнению контрольных заданий)


Имя поляТип поляОписаниеNameAlpha[25]Фамилия, инициалыPhoneAlpha[18]Номер телефонаNoteAlpha[40]Для заметок

. Поместим на форму следующие компоненты: TabControl (вкладка Win32), DBGrid, DBNavigator (вкладка Data Controls), Table (вкладка BDE), DataSource (вкладка Data Access ).

Зададим свойству Align компонентов TabControl значение alClient (на все окно).

В свойстве Tabs компонента TabControl введем буквы алфавита:


Для того, чтобы закладки располагались сверху - вниз, справа - налево, зададим свойству Anchors компонента TabControl значения:

akLeft -true-true- true - true

MultiLin=true

3. Установим компонентам следующие свойства:

Table:

  • DatabaseName (псевдоним базы данных) - выбираем из списка свой Alias.
  • TableName - выбираем имя своей таблицы.
  • AutoRefresh (обновление структуры таблицы) - устанавливаем значение true.
  • Active - устанавливаем true - подключаем таблицу.

DataSource:

  • DataSet (источник данных) - выбираем Table1.

DBGrid, DBNavigator:

  • свойству DataSource устанавливаем значение DataSource1.
  • Align (выравнивание): DBGrid - alClient (на все окно), DBNavigator - alBottom (внизу окна).

4. Создадим обработчик OnChange компонента TabControl:

procedure TForm1.TabControl1Change(Sender: TObject);.Filter:='Name='''+TabControl1.Tabs[TabControl1.TabIndex]+'*''';;

Фильтрация ведется по совпадению первой буквы фамилии. При выборе закладки автоматически формируется выражение фильтра, включающее в себя название (букву) выбранной закладки и символ «*».

. Свойству Filtered компонента Table установим значение True.

Чтобы фильтрация выполнялась независимо от регистра букв и по частичному совпадению установим параметры свойства Filtered компонента Table следующим образом:

foCaseInsensitive - True

foNoPartialCompare - False

Для того, чтобы сразу же после загрузки приложения компоненты появлялись в отсортированном виде, для свойства OnCreate формы выберем из списка TabControl1Change.

Выполнить самостоятельно:

1.Создать всплывающие подсказки (Hint) для каждой из кнопок DBNavigator

2.Русифицировать названия полей таблицы (см. рекомендации к выполнению контрольных работ).


1Переход на первую запись6Удалить запись2Переход на предыдущую запись7Редактировать запись3Переход на следующую запись8Сохранить изменения4Переход на последнюю запись9Отменить изменения5Добавить запись10Перечитать таблицу

Результатом выполнения данной лабораторной работы являются созданный согласно заданию программный продукт. Выполненное задание должно быть предъявлено преподавателю в электронном виде. В ходе защиты лабораторной работы студент должен продемонстрировать свои навыки работы с изученными компонентами и методами проектирования интерфейса пользователя.


Лабораторная работа №8. Текстовый редактор


Цель: Изучение компонентов Panel, Memo, OpenDialog, SaveDialog, MainMenu, PopupMenu, SpeedButton

Краткие теоретические сведения.

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

В компоненте Memo формат (шрифт, его атрибуты, выравнивание) одинаков для всего текста и определяется свойством Font. Если вы сохраните в файле текст, введенный или отредактированный пользователем, то будет создан текстовый файл, содержащий только символы и не содержащий элементов форматирования. При последующем чтении этого файла в Memo формат будет определяться текущим состоянием свойства Font компонента Memo, а не тем, в каком формате ранее вводился текст.

Свойства Alignment и WordWrap определяют выравнивание текста и допустимость переноса длинных строк. Установка свойства ReadOnly в true задает текст только для чтения.

Основное свойство Memo - Lines, содержащее текст окна в виде списка строк и имеющее тип TStrings. Начальное значение текста можно установить в процессе проектирования, нажав кнопку с многоточием около свойства Lines в окне Инспектора Объектов.

Во время выполнения приложения вы можете заносить текст в окно редактирования с помощью методов свойства Lines типа TStrings. Доступ к отдельной строке текста вы можете получить с помощью свойства Strings[Index: Integer]. Индексы, как и везде в Delphi, начинаются с 0. Так что Memo1.Lines.Strings[0] - это текст первой строки. Свойство только для чтения Count указывает число строк в тексте. Для очистки текста в окне надо выполнить процедуру Clear. Этот метод относится к самому окну, а не к его свойству Lines.

Для занесения новой строки в конец текста окна редактирования можно воспользоваться методами Add или Append свойства Lines. Для загрузки текста из файла применяется метод LoadFromFile. Сохранение текста в фале осуществляется методом SaveToFile.

В Delphi имеется два компонента, представляющие меню: MainMenu - главное меню, и PopupMenu - всплывающее меню. Оба компонента расположены на странице Standard. Эти компоненты имеют много общего. Это невизуальные компоненты, т.е. место его размещения на форме в процессе проектирования не имеет никакого значения для пользователя - он все равно увидит не сам компонент, а только меню, сгенерированное им.

Основное свойство компонента - Items. Его заполнение производится с помощью Конструктора Меню, вызываемого двойным щелчком на компоненте или нажатием кнопки с многоточием рядом со свойством Items в окне Инспектора Объектов.

Контекстное меню (PopUpMenu) привязано к конкретным компонентам. Оно всплывает, если во время, когда данный компонент в фокусе, пользователь щелкнет правой кнопкой мыши. Оконные компоненты: панели, окна редактирования, а также метки и др. имеют свойство PopupMenu, которое по умолчанию пусто, но куда можно поместить имя того компонента PopupMenu, с которым будет связан данный компонент.

В приложениях часто приходится выполнять стандартные действия: открывать и сохранять файлы, задавать атрибуты шрифтов, выбирать цвета палитры, производить контекстный поиск и замену и т.п. Разработчики Delphi позаботились о том, чтобы включить в библиотеку простые для использования компоненты, реализующие соответствующие диалоговые окна. Они размещены на странице Dialogs.

Компоненты OpenDialog - диалог «Открыть файл» и SaveDialog - диалог «Сохранить файл как...», пожалуй, используются чаще всего, в большинстве приложений. Основное свойство, в котором возвращается в виде строки выбранный пользователем файл, - FileName. Типы искомых файлов, появляющиеся в диалоге в выпадающем списке Тип файла, задаются свойством Filter. В процессе проектирования это свойство проще всего задать с помощью редактора фильтров, который вызывается нажатием кнопки с многоточием около имени этого свойства в Инспекторе Объектов. Свойство FilterIndex определяет номер фильтра, который будет по умолчанию показан пользователю в момент открытия диалога.

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

Свойство DefaultExt определяет значение расширения файла по умолчанию. Если значение этого свойства не задано, пользователь должен указать в диалоге полное имя файла с расширением. Если же задать значение DefaultExt, то пользователь может писать в диалоге имя без расширения. В этом случае будет принято заданное расширение. Свойство Title позволяет вам задать заголовок диалогового окна. Свойство Options определяет условия выбора файла.

Кнопки SpeedButton имеют возможность отображения пиктограмм и могут использоваться как обычные управляющие кнопки или как кнопки с фиксацией нажатого состояния. Изображение на кнопке задается свойством Glyph.

Особенностью кнопок SpeedButton являются свойства GroupIndex (индекс группы), AllowAllUp (разрешение отжатого состояния всех кнопок группы) и Down (исходное состояние - нажатое). Если GroupIndex = 0, то кнопка ведет себя так же, как Button и BitBtn. При нажатии пользователем кнопки она погружается, а при отпускании возвращается в нормальное состояние. В этом случае свойства AllowAllUp и Down не влияют на поведение кнопки.

Если Grouplndex > 0 и AllowAllUp = true, то кнопка при щелчке пользователя на ней погружается и остается в нажатом состоянии. При повторном щелчке пользователя на кнопке она освобождается и переходит в нормальное состояние (именно для того, чтобы освобождение кнопки состоялось, необходимо задать AllowAllUp = true). Если свойство Down во время проектирования установлено равным true, то исходное состояние кнопки - нажатое.

Если есть несколько кнопок, имеющих одинаковое ненулевое значение GroupIndex, то они образуют группу взаимосвязанных кнопок из которых нажатой может быть только одна. Если одна кнопка находится в нажатом состоянии и пользователь щелкает на другой, то первая кнопка освобождается, а вторая фиксируется в нажатом состоянии.

Состояние кнопки во время выполнения можно определить по значению свойства Down: если значение равно true, то кнопка нажата. Во время события OnClick значение Down уже равно тому состоянию, которое примет кнопка в результате щелчка на ней.

Ход работы

. Поместить на форму компонент Panel, присвоить свойству Align значение alTop. Удалить строку из свойства Caption.

. Поместить на Panel четыре компонента Button (кнопка) и присвоить их свойству Caption соответственно значения &Open, &Save, Save &As…, E&xit. Определить свойство Font для панели из кнопок как «жирный»

. Изменить заголовок формы (свойство Caption) - например, My Editor

. Поместить на форму компонент Memo и установить его свойства следующим образом:

Align - alClient, Scroll bar - ssBoth, Lines (убрать текст из свойства, выполнив щелчок на свойстве Lines, и затем на кнопке с тремя точками).

. Поместить на форму компонент OpenDialog, который находится на странице Dialog и присвоить его свойствам значения:


DefaultExtTXTTitleОткрыть файлOptions.ofFileMustExistTrueOptions.ofNoReadOnlyReturnTrue

. Открыть окно редактора фильтров, для чего дважды щелкнуть на свойстве Filter. Заполнить две первые строки в колонке Имя фильтра названиями фильтров: текстовые файлы и все файлы, а в колонке Фильтр ввести соответствующие маски: *.txt и *.*

. Поместить на форму компонент SaveDialog и присвоить ему значения:


DefaultExtTXTTitleСохранить файлOptions.ofOverwritePromptTrueOptions.ofNoReadOnlyReturnTrue

. Открыть окно редактора фильтров, для чего дважды щелкнуть на свойстве Filter. Заполнить две первые строки в колонке Имя фильтра названиями фильтров: текстовые файлы и все файлы, а в колонке Фильтр ввести соответствующие маски: *.txt и *.*

. Создадим обработчик события OnClick для кнопки Open:

with OpenDialog1 doexecute then.Lines.LoadFromFile(FileName);.Modified:=false;:='My Editor -'+ExtractFileName(FileName);.FileName:=FileName;:='';;

10. Создадим обработчик OnClick для кнопки Save As..:

with SaveDialog1 doExecute then.Lines.SaveToFile(FileName);.Modified:=false;:='My Editor -'+ExtractFileName(FileName);;

. Создадим обработчик OnClick для кнопки Save:

if SaveDialog1.FileName='' thenClick(Sender)

else.Lines.SaveToFile(SaveDialog1.Filename);.Modified:=false;;

12. Создадим обработчик события OnClick для кнопки Exit:

Case MessageDlg('Закрыть редактор?', mtConfirmation,mbYesNoCancel,0) of: form1.Close;:;:;;

. Расположить на форме компонент MainMenu и создать пункты меню следующим образом:




Редактор меню вызывается двойным щелчком по компоненту. Для создания разделительной черты в свойстве Caption, необходимо ввести символ «-» (Минус)

. Каждый пункт меню кроме New свяжем с уже существующим методом OnClick для соответствующих кнопок. Например, кнопка Open имеет имя Button1, поэтому на странице Events окна Object Inspector для пункта меню Open вы щелкните на клавише открытия списка, расположенной рядом с OnClick и выберите Button1.Click.

. В обработчик события OnClick пункта меню New поместим код:

if Memo1.Modified then

case MessageDlg('Ôàéë'+ExtractFileName(SaveDialog1.FileName)+

'áûë èçìåíåí. Ñîõðàíèòü?',mtConfirmation,mbYesNoCancel,0) of:button2Click(Sender);:;:Exit;.Clear;.FileName:='';:='My Editor';

. Двойным щелчком отредактируем компонент-меню и добавим еще один пункт меню Color, и в нем два подпункта ColorBackGround и ColorText.

Поместим на форму компонент ColorDialog, находящийся в палитре Dialogs.

В обработчик пункта меню ColorBackGraund вставить следующий код:

with ColorDialog1 doExecute then1.Color:=color;

В обработчик пункта меню ColorText вставить следующий код:

with ColorDialog1 doExecute then.Font.Color:=color;

17.Создать для формы обработчик события OnCloseQuery:

if Memo1.Modified thenMessageDlg('Файл'+ExtractFileName(SaveDialog1.FileName)+

'был изменен. Сохранить?',mtConfirmation,mbYesNoCancel,0) of: button2Click(Sender);:;:CanClose:=false;;

. Установим на панели три кнопки SpeedButton. В свойства Caption этих кнопок введем буквы Ж(жирный), К(курсив), П (подчеркнутый) соответствующим образом изменив тип начертания в свойстве Font.

Выделив все три кнопки установим их свойство AllowAllUp установим True. Также установим следующие свойства:


КомпонентGroupIndexTagSpeedButton110SpeedButton221SpeedButton332

В обработчик события OnClick для кнопки Ж введем:

with sender as TSpeedButton dodown then.Font.Style:=memo1.Font.Style+[TFontStyle(tag)].Font.Style:=memo1.Font.Style-[TFontStyle(tag)]

end;

События OnClick для оставшихся двух кнопок свяжем с событием SpeedButton1Click при помощи Инспектора объектов, как в случае с пунктами меню.

. Поместить на панель еще одну кнопку SpeedButton. В свойство Caption ничего не вводить. Выполнить два щелчка на свойстве Glyph. В появившемся диалоговом окне выбрать команду Load и из каталога Program Files/Common Files/Borland Shared/Images/Buttons загрузим файл Font.bmp или любой другой.

В обработчике OnClick написать следующий код:

with fontdialog1 doexecute then memo1.Font:=font;

18. Компонент Memo позволяет хранить информацию только в формате txt, поэтому при закрытии файла все элементы форматирования пропадут. Поэтому мы заменим компонент на позволяющий сохранять текст в формате rtf. Для этого необходимо нажать Alt+F12. На экране появится окно с содержимым файла Unit1.dfm (данный файл ресурсов формы содержит все настройки формы, сделанные с помощью Инспектора объектов). Найдите в этом файле описание компонента object Memo1: T Memo и замените его на Memo1: TRichEdit. Затем снова нажмите Alt+F12. При компиляции согласитесь с тем, что вам предложит Delphi.

. Поместим на панель еще три кнопки SpeedButton, которые будут отвечать за выравнивание текста по левому краю, по правому краю и по центру. Зададим их свойства следующим образом:


КомпонентGroupIndexTagSpeedButton540SpeedButton641SpeedButton742

В свойствах Caption введем «<», «>» и «=» соответственно.

Для 1-й кнопки создадим обработчик OnClick:

with sender as tspeedbutton do.Paragraph.Alignment:=TAlignment(tag)


Обработчики этого события для остальных кнопок свяжем с SpeedButton5Click

. Установить на форму компонент StatusBar, находящийся в палитре Win32. Два раза щелкнуть на компоненте, чтобы перейти в окно редактирования StatusBar. В окне редактирования три раза нажать кнопку Добавить, чтобы получить три панели на компоненте. На первых двух будет отображаться текущее состояние клавиш CapsLock и NumLock. На третьей - системное время.

. Добавить на форму компонент Timer, расположенный на палитре System. добавим в список глобальных переменных KS: Tkeyboardstate

Создать обработчик OnTimer:(KS);StatusBar1 doKS[VK_Capital]=1 then panels[0].Text:='CAP' else panels[0].Text:='';KS[VK_NumLock]=1 then panels[1].Text:='Num' else panels[1].Text:='';.Panels[2].Text:=TimeToStr(Time);

end;

Чтобы не было секундной задержки после загрузки программы, для обработчика OnCreate формы выберем Timer1Timer.

. Создадим контекстное меню. Установить на форму компонент PopupMenu. Создадим пункты - Cut, Copy, Paste. В обработчики событий OnClick ввести соответственно следующий код:

Для пункта Copy: Memo1. CopyToClipboard;

Для пункта Cut: Memo1. CutToClipboard;

Для пункта Paste: Memo1.PasteFromClipboard;

В свойстве Memo1 PopUpMenu выберем PopUpMenu1

Для того, чтобы недоступные команды (если текст не выделен или буфер пуст) выделялись серым цветом сделаем следующее. В список uses добавим модуль Clipbrd (он обеспечивает доступ к объекту Clipboard - буферу обмена).

Создадим обработчик OnPopUp для PopUpMenu

copy1.Enabled:=memo1.SelLength>0;.Enabled:=memo1.SelLength>0;.Enabled:=Clipboard.HasFormat((CF_TEXT);

Выполнить самостоятельно:

  1. Создать кнопку для Зачеркнутого шрифта (свойство Style - fsStrikeOut, т.е Tag=3)
  2. Сделать всплывающие подсказки для всех кнопок.
  3. Добавить на панель кнопку для добавления маркеров. В обработчике OnClick для новой кнопки поместить код:

if (sender as TSpeedButton).down then.Paragraph.Numbering:=nsBullet else.Paragraph.Numbering:=nsNone

  1. Используя свойство ShortCut пунктов меню назначить им комбинации горячих клавиш, например - Open - Ctrl+O, Save - Ctrl+S и т.п.
  2. Создать кнопку Undo, при нажатии которой будет отменено последнее действие. В обработчике кнопки поместить код:

Memo1.Undo.

Если отменять нечего, кнопка должна быть недоступной (для этого используем свойство Memo1.CanUndo).

6. Добавить в контекстное меню пункты Выделить все (метод SelectAll) и Удалить (ClearSelection). Если операции недоступны, пункты должны быть неактивными. В первом случае можно использовать значение memo1.text<>.

. Создать пункт меню О программе.

Создать новую форму. Изменить ее заголовок. Поместить на нее компонент Memo. Установить свойство компонента ReadOnly в True. Щелкнуть два раза по свойству Lines и ввести текст. Изменить произвольным образом свойства Color и Font компонента Memo.

В обработчике события OnClick пункта меню О программе написать код:

Form2.showmodal

Результатом выполнения данной лабораторной работы являются созданный согласно заданию программный продукт. Выполненное задание должно быть предъявлено преподавателю в электронном виде. В ходе защиты лабораторной работы студент должен продемонстрировать свои навыки работы с изученными компонентами и методами проектирования интерфейса пользователя.


Лабораторная работа №9. Создание простейшего графического редактора


Цель: Изучение компонентов Image, ScrollBox, компонетов-диалогов, а также обработки событий мыши.

Краткие теоретические сведения.

Компонент Image представляют собой некоторую ограниченную поверхность с канвой, на которую можно заносить изображения. Свойства и методы работы с канвой описаны в Л/р№4.

Компонент Image используется для отображения графики: пиктограмм, битовых матриц и метафайлов. Для этого служит его свойство Picture - объект типа TPicture. Если установить свойство AutoSize в true, то размер компонента Image будет автоматически подгоняться под размер помещенной в него картинки. Если же свойство AutoSize установлено в false, то изображение может не поместиться в компонент или, наоборот, площадь компонента может оказаться много больше площади изображения. Другое свойство - Stretch позволяет подгонять не компонент под размер рисунка, а рисунок под размер компонента

Свойство - Center, установленное в true, центрирует изображение на площади Image, если размер компонента больше размера рисунка.

Рассмотрим еще одно свойство - Transparent (прозрачность). Если Transparent равно true, то изображение в Image становится прозрачным. Это можно использовать для наложения изображений друг на друга. - панель с прокруткой. Этот компонент предназначен для создания области, в которой могут размещаться компоненты, занимающие площадь большую, чем сам ScrollBox. Если размеры ScrollBox меньше, чем размещенные компоненты, то появляются полосы прокрутки, которые позволяют пользователю перемещаться по всем размещенным в ScrollBox компонентам.

Свойства компонентов OpenPictureDialog и SavePictureDialog ничем не отличаются от свойств компонентов OpenDialog и SaveDialog. Единственное отличие - заданное значение по умолчанию свойства Filter в OpenPictureDialog и SavePictureDialog. В этих компонентах заданы следующие фильтры:


All (*.jpg; *.jpeg; *.bmp; *.ico; *.emf; *.wmf) *.jpg; *.jpeg; *.bmp; *.ico; *.emf; *.wmf JPEG Image File (*.jpg) *.jpg JPEG Image File (*.jpeg) *.jpeg Bitmaps (*.bmp) *.bmp Icons (*.ico) *.ico Enhanced Metafiles (*.emf) *.emf Metafiles (*.wmf) *.wmf

В этих фильтрах перечислены все типы графических файлов, с которыми может работать диалог. Так что вам остается удалить, если хотите, фильтры тех файлов, с которыми вы не хотите работать, добавить, может быть, фильтр «Все файлы (*.*)» и перевести на русский язык названия типов.

Компонент ColorDialog вызывает диалоговое окно выбора цвета. В нем пользователь может выбрать цвет из базовой палитры или, нажав кнопку Определить цвет, раскрыть дополнительную панель, позволяющую синтезировать цвет, отличный от базовых. Синтезированный цвет можно добавить кнопкой Добавить в набор в палитру дополнительных цветов на левой панели и использовать его в дальнейшем.

События мыши


СобытиеОписаниеonClickЩелчок мыши на компоненте и некоторые другие действия пользователяonDblClickДвойной щелчок мыши на компонентеonMouseDownНажатие клавиши мыши на компоненте. Возможно распознавание нажатой кнопки и координат курсора мышиonMouseMoveПеремещение курсора мыши над компонентом. Возможно распознавание нажатой кнопки и координат курсора мышиonMouseUpОтпускание ранее нажатой мыши над компонентом. Возможно распознавание нажатой кнопки и координат курсора мышиonStartDragНачало процесса «перетаскивания» объекта. Возможно распознавание перетаскиваемого объектаonDragOverПеремещение «перетаскиваемого» объекта над компонентом. Возможно распознавание перетаскиваемого объекта и координат курсора мышиonDragDropОтпускание ранее нажатой кнопки мыши после «перетаскивания» объекта. Возможно распознавание перетаскиваемого объекта и координат курсора мышиonEndDragЕще одно событие при отпускании ранее нажатой кнопки мыши после «перетаскивания» объекта. Возможно распознавание перетаскиваемого объекта и координат курсора мышиonEnterСобытие в момент получения элементом фокуса в результате манипуляций мышью, нажатия клавиши табуляции или программной передачи фокусаonExitСобытие в момент потери элементом фокуса в результате манипуляций мышью, нажатия клавиши табуляции или программной передачи фокуса

Во все события, связанные с мышью, передаются также координаты курсора X и Y . Эти параметры определяют координаты курсора в клиентской области компонента. Благодаря этому можно обеспечить различную реакцию в зависимости от того, в какой части клиентской области расположен курсор.

Ход работы

1. Создадим новое приложение и сохраним его в своей папке.

. Разместим на форме 4 компонента Button и зададим им соответствующие названия. Далее разместим на форме компонент ScrollBox (вкладка Additional). Выделив этот компонент, разместим на нем компонент Image. В свойстве Align этого компонента выберем alClient



Разместим на форме также два невизуальных компонента - OpenPictureDialog и SavePictureDialog. В этих компонентах свойство Filter уже содержит фильтры для некоторых типов графических файлов. Все эти фильтры, кроме фильтра для bmp-файлов, надо удалить. В свойстве DefaultExt обоих компонентов введем bmp.

. Создадим еще одну форму и разместим на ней компоненты Button, Label и SpinEdit следующим образом:


Для компонентов SpinEdit здадим следующие свойства:

SpinEdit1: MinValue = 10, MaxValue = 800, Increment = 10: MinValue = 10, MaxValue = 600, Increment = 10

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

Для кнопок определим следующие свойства:

Button1: ModalResult=mrOK, Default = True.: ModalResult=mrCancel, Cancel = True.

4. Вернемся к первой форме. Создадим обработчик OnClick для кнопки New:form2 do //устанавливаем значения счетчиков на второй форме равными текущим значениям ширины и высоты компонента Image

begin.Value:=image1.Width;.Value:=image1.Height;;form2.ShowModal=mrOK then //если на 2-й форме нажата кнопка ОК

with image1 do:=nil; //очистка прежнего изображения и создание нового с нужными размерами

picture.Bitmap.Width:=form2.SpinEdit1.Value;.Bitmap.Height:=form2.SpinEdit2.Value;

canvas.FillRect(canvas.ClipRect); //заливка созданного изображения цветом фона

savepicturedialog1.FileName:='';.Caption:='Image editor';

end;

. Создадим обработчик OnClick для кнопки Open:

with openpicturedialog1 doexecute then.Picture.LoadFromFile(filename);.FileName:=filename;.Caption:='Image Editor - '+Filename; //к заголовку окна добавляется название файла

filename:='';;

. Аналогичным образом создаем обработчик для кнопки Save:

with savepicturedialog1 doexecute thenimage1.Picture.SaveToFile(filename);.Caption:='Image Editor -'+ filename;

end;

. Для копки Clear создадим следующий обработчик:

with image1.Canvas do(cliprect);

8. Создадим обработчик события OnCreate для формы:

image1.Parent.DoubleBuffered:=true;image1 do.Bitmap.Width:=scrollbox1.Width;.Bitmap.Height:=scrollbox1.Height;.FillRect(canvas.ClipRect);;

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

. Следующим шагом будет реализация возможности рисования линии черного цвета толщиной 1 пиксел. Рисование будет возможным как на созданных, так и на загруженных изображениях.

Для Image1 в обработчике OnMouseDown напишем:.Canvas.MoveTo(x,y); //точка с координатами X,Y становится текущей точкой канвы.

Обработчик OnMouseMove Image1:ssleft in shift then //если нажата левая клавиша мышки

image1.Canvas.LineTo(x,y); //рисуется линия от текущей точки до точки с координатами X,Y и эта точка становится следующей текущей

. Приступим к следующему этапу. Добавим редактору следующие функции: возможность рисования прямых линий, изменения толщины контура, а также возможность выбора цвета фона и контура. Разместим на форме дополнительные компоненты: (Capture = Mode), внутри которого размещены две кнопки:

SpeedButton1 (Capture=Brush, GroupIndex=1, Down=True) - кнопка для рисования в режиме «free hand»(Capture =RulerGroupIndex=1, Tag=1) - кнопка для рисования в режиме «прямой линии»

ColorGrid1 (свойство GridOrdering=go16x1 - ячейки расположены в один ряд)

SpiEdit1 (MaxValue=22, MinValue=1, Value=1, Increment=3).

Label1 (Capture=Width)

В свойстве Tag будет хранится номер режима рисования.



. Напишем следующие обработчики:для ColorGrid1:

image1.Canvas.Pen.Color:=colorgrid1.ForegroundColor; //цвет контура.Canvas.Brush.Color:=colorgrid1.BackgroundColor; //цвет фонадля SpiEdit1:.Canvas.Pen.Width:=spinedit1.Value;// задаем толщину линии

12. Теперь обеспечим возможность рисования во втором режиме - прямые линии.

OnClick для SpeedButton1:.Tag:=(sender as tspeedbutton).Tag;

(sender as Tspeedbutton).Down:=true;

Для события OnClick SpeedButton2 выберем из списка SpeedButton1Click

Опишем глобальные переменные:,MovePoint:tpoint;

А в секции Implementation (сразу после {$R *.dfm}) опишите следующую процедуру:

procedure drawfigure(p1,p2:tpoint; amode:TPenMode);form1.Image1.Canvas do.Mode:=Amode;(p1.X,p1.Y);(p2.X,p2.Y);

end;;

. Создадим следующие обработчики:

Image1 OnMouseUp:startpoint.X=10000 then exit; (image1.Tag=1) or

(image1.Tag=2) //это условие нам пригодится в будущем для рисования фигур

then drawfigure(startpoint,point(x,y),pmCopy);

Отредактируем метод Image1MouseMove следующим образом:

if ssleft in shift thenimage1.Tag of

: image1.Canvas.LineTo(x,y);

: begin(startpoint,movepoint,pmNotXor);:=Point(x,y);(StartPoint,MovePoint,pmNotXor);;;

В метод Image1MouseDown добавьте:

startpoint:=point(x,y);:=StartPoint;

Теперь рисование можно производить в двух режимах: в режиме «Brush» рисуются линии произвольной формы, а в новом режиме «Ruler» рисуются прямые линии.

. Усложним на редактор. Добавим еще один инструмент - Рисование фигур

Добавим в GroupBox1 еще одну кнопку SpeedButton3 (Caption = Figure).

Параметры кнопки - GroupIndex=1, Tag=2

Разместим также в левом нижнем углу формы панель (Panel1) и поместим на нее компонент Shape1. Установите значения Width и Height для Shape1 на 4 пикселя меньше, чем соответствующие значения компонента Panel1. Разместите компонент Shape1 по центру панели.

Компонент Shape1 позволяет определить, как будет выглядеть нарисованная фигура. В других режимах рисования данный компонент позволяет визуально оценить текущие цвет и толщину линии. При щелчке левой клавиши мышки на компоненте-образце Shape1 изменяется тип фигуры (прямоугольник, прямоугольник с закругленными углами, эллипс) и происходит автоматический переход в режим «Figure». Щелчок правой клавиши по компоненту позволяет перейти в режим рисования фигур с равными измерениями (квадраты и т.п.).


15. Объявим еще две глобальные переменные: dx,dy:integer;

В раздел uses для Unit1 необходимо добавить модуль математических функций Math

Измените уже описанную нами процедуру DrawFigure следующим образом (добавить выделенные жирным строки):

with form1.Image1.Canvas do.Mode:=Amode;form1.Image1.tag of

: begin(p1.X,p1.Y);(p2.X,p2.Y);;

: begin:=p2.X-p1.X;:=p2.Y-p1.Y;abs(dx)>abs(dy) then dx:=abs(dy)*sign(dx) else dy:=abs(dx)*sign(dy);form1.shape1.Shape of:Rectangle(p1.X,p1.Y,p2.X,p2.Y);:RoundRect(p1.X,p1.Y,p2.X,p2.Y,(p2.Y-p1.X) div 2,(p2.Y-p1.Y) div 2);: Ellipse(p1.X,p1.Y,p2.X,p2.Y);:rectangle(p1.X,p1.Y,p1.X+dx,p1.Y+dy);:RoundRect(p1.X,p1.Y,p1.X+dx,p1.Y+dy,dx div 2, dy div 2);:Ellipse(p1.X,p1.Y,p1.X+dx,p1.Y+dy);;;;;

В методе Image1MouseMove замените строку 1:begin на1,2:begin

В метод ColorGrid1Change добавьте:.Brush.Color:=colorgrid1.BackgroundColor;.Pen.Color:=ColorGrid1.ForegroundColor;

В метод SpinEdit1Change добавьте:.Pen.Width:=spinedit1.Value;

16. Создадим обработчик OnMouseDown для Shape1:

procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;: TShiftState; X, Y: Integer);i:integer;ssLeft in Shift then:=(ord(shape1.Shape)+2) mod 6 elseodd(ord(Shape1.Shape)) then:=ord(shape1.Shape)-1i:=ord(shape1.Shape)+1;.Shape:=tshapetype(i);.Down:=true;1.Tag:=2;

end;

. Реализуем функцию отмены предыдущей операции. Для этого объявим глобальную переменную oldbitmap:tbitmap;

Отредактируйте метод FormCreate следующим образом:

image1.Parent.DoubleBuffered:=true;:=tbitmap.Create;image1 do.Bitmap.Width:=scrollbox1.Width;.Bitmap.Height:=scrollbox1.Height;.FillRect(canvas.ClipRect);.Width:=picture.Bitmap.Width;.Height:=picture.Bitmap.Height;;;

Создадим обработчик OnDestroy для Form1:

oldbitmap.Free;

Установим свойству KeyPreview формы значение true и напишем обработчик OnKeyPress для формы:

if key=#27 thenimage1.Canvas do(cliprect,oldbitmap.Canvas,cliprect);

Теперь любую графическую операцию можно отменить сразу после ее выполнения, нажав клавишу Esc.

. Добавим нашему редактору еще несколько функциональных возможностей. Реализуем возможность использования дополнительных цветов.

Разместим на форме компоненты StaticText1 (Caption=FG), StaticText2 (Caption=BG) (панель Additional) и ColorDialog1. Для компонентов StaticText1 и StaticText2 зададим следующие свойства:

Alignment=taCenter; AutoSize=False; BorderStyle=sbsSunken; Font.Color = cllnactiveCaption.

В секцию imlementation добавьте следующую процедуру:

procedure NewColor (sender:TObject; Acolor:TColor);Form1 dosender = StaticText1 then.ForegroundIndex:=-1 else.BackgroundIndex:=-1 ; // скрытие подписей FG и BG на компоненте ColorGrid1

(sender as TStaticText).Color:=AColor;

(sender as TStaticText).Font.Color:=AColor xor $FFFFFF; //цвет текста на компонентах StaticText будет инверсным к фону компонентаChange(Sender);;;

. Напишем обработчик OnMouseDown для StaticText1:ColorDialog1 doSender=StaticText1 then:=Shape1.Pen.ColorColor:=Shape1.Brush.Color;execute then //вызов диалогового окна ColorDialog1, если оно было закрыто кнопкой «ОК», Execute=true(sender,color);;

Для OnMouseDown StaticText2 выберем StaticText1MouseDown

Обработчик OnChange для Colorgrid1 изменим следующим образом:

with colorgrid1 doForegroundIndex <>-1 then.Pen.Color:=ForegroundColor;.Color:=clBtnFace;.Font.Color:=clInactiveCaption;.Pen.Color:=StaticText1.Color;.Canvas.Pen.Color:=shape1.Pen.Color;BackGroundIndex<>-1 then.Color:=clBtnFace;.Font.Color:=clInactiveCaption;;BackGroundIndex<>-1 then.Brush.Color:=BackgroundColorshape1.Brush.Color:=StaticText2.Color;.Canvas.Brush.Color:=shape1.Brush.Color;

end;

Для выбора цвета линии или цвета фона, не входящего в палитру ColorGrid1, нужно щелкнуть мышкой по компонентам StaticText1 или StaticText2 соответственно, в появившемся диалоговом окне «Цвет» указать новый цвет и нажать ОК. При этом компонент StaticText окрасится в соответствующий текст, а метка «FG»(«BG») из палитры ColorGrid1 исчезнет.

. Реализуем задание цветов при помощи «пипетки». Внесем изменения в обработчик OnMouseDown для Image1:

with image1.Canvas do.Canvas.CopyRect(cliprect,image1.Canvas,cliprect);ssAlt in Shift thenButton of:NewColor(Statictext1,Pixels[x,y]);:NewColor(StaticText2,Pixels[x,y]);;;.Canvas.MoveTo(x,y);:=point(x,y);:=StartPoint;

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

. Разместим на форме дополнительные компоненты.



Компоненты SpeedButton4 (Cuption=Roller, GroupIndex=1, Tag=3), SpeedButton5 (Cuption=Text, GroupIndex=1, Tag=4), Label2 (Caption=Text), Label3 (Caption=Style), Button5 (Caption=Font), Edit1 (Text=), FontDialog1 (Options.fdEffects=false - отключение возможности настройки цвета шрифта, а также выбора режима подчеркивания и перечеркивания текста), ComboBox1 и ComboBox2 (Style=csOwnerDeawFixed, Text=, ItemIndex=0).

Для кнопок SpeedButton событие OnClick определите как SpeedButton1Click.

. Четвертым режимом рисования будет «Валик» (Roller). Этот режим позволяет заливать текущим цветом фона области, ограниченные линиями других цветов. Заливка производится при щелчке мышью внутри нужной области.

Внесем изменение в метод Image1MouseDown:

if ssAlt in Shift thenButton of:NewColor(Statictext1,Pixels[x,y]);:NewColor(StaticText2,Pixels[x,y]);image1.Tag=3 then(x,y,pixels[x,y],fsSurface)

23. Пятый режим - добавление в рисунок текста. В метод Image1MouseDown добавим:image1.Tag=3 then(x,y,pixels[x,y],fsSurface)if image1.tag=4 then TextOut(x,y,edit1.Text);

Создадим обработчик OnEnter для Edit1:

SpeedButton5.Down:=true;.Tag:=4;

В метод ColorGrid1Change добавьте операторы:

image1.Canvas.Pen.Color:=shape1.Pen.Color;.Canvas.Font.Color:=shape1.Pen.Color;

Новый режим позволяет помещать на изображение текст, содержащийся в поле ввода Edit1. Текст вставляется при нажатии левой кнопки мыши, место нажатия определяет начальную позицию текста. Цвет текста совпадает с текущим фоном.

. Нажатие кнопки Font позволяет изменить шрифт вставляемой надписи.

Для кнопки Button5 напишем обработчик OnClick

with FontDialog1 do:=Image1.Canvas.Font;execute then.Canvas.Font:=font;;

. Занесем в свойство Items ComboBox1 6 строк, содержащих числа 0,1,2,3,4,5. В компонент ComboBox2 занесем 8 строк (0,1,2,3,4,5,6,7).

Опишем OnDrawItem для ComboBox1:

with comboBox1.Canvas,Rect do

begin.Color:=clWhite;.Color:=clBlack;.Style:=TPenStyle(StrToInt(Combobox1.Items[index]));(Left,(top+Bottom) div 2);(Right,(top+Bottom) div 2);;

Создадим для ComboBox1 обработчик OnChange:

with ComboBox1, Shape1.pen do:=TPenStyle(StrToInt(Items[ItemIndex]));.Canvas.Pen.Style:=Style;Change(Sender);;

Аналогично поступим с ComboBox2:для ComboBox2:ComboBox2.Canvas do.Color:=clGray;.Style:=TBrushStyle(StrToInt(ComboBox2.Items[Index]));(Rect);;событие OnChange:ComboBox2, Shape1.Brush do:=TBrushStyle(StrToInt(Items[ItemIndex]));.Canvas.Brush.Style:=Style;.Enabled:=Style<> bsClear;Change(Sender);;

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

Результатом выполнения данной лабораторной работы являются созданный согласно заданию программный продукт. Выполненное задание должно быть предъявлено преподавателю в электронном виде. В ходе защиты лабораторной работы студент должен продемонстрировать свои навыки работы с изученными компонентами и методами проектирования интерфейса пользователя.


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


1.Borland Delphi 6. Руководство разработчика

.Paradox for Windows: Практическое руководство. Под редакцией Оспищева Д.А. Издательство АОЗ "Алевар"

.Александровский А.Д. Delphi 5. Разработка корпоративных приложений. Среда визуальной разработки RAD

.Алексей Архангельский. Интегрированная среда разработки Delphi (версии 1 - 5). Практическое пособие с примерами

.Архангельский А.Я. Работа с локальными базами данных в Delphi 5.

6. Архангельский А.Я. Object Pascal в Delphi. Настольная книга программиста.

. Бобровский С. И. Delphi 7. Учебный курс

. Горев А., Ахаян Р., Макашарипов С. «Эффективная работа с СУБД».СПб.:Питер, 2001.

. Дарахвелидзе П.Г. Программирование в Delphi 7.

. Дж. Мартин., "Организация баз данных в вычислительных системах" М: Мир 1998г.

. Джон Матчо, Дэвид Р.Фолкнер. «Delphi» - пер. с англ. - М.:Бином, 1999г.

. Дунаев С.В. Borland-технологии. SQL-Link. Interbase. Paradox for Windows. Delphi

. Епанешников А.М., "Программирование в среде Delphi 5.0"

. Кириллов В.В. Структуризованный язык запросов (SQL). - СПб.: ИТМО, 2001.

. Когловский М.Р., "Технология баз данных на персональных ЭВМ", Москва, 'Финансы и статистика', 1992 г.

. Кожедуб О.А., Скиба С.А., Подольский С.В. Разработка интернет-приложений в Delphi

. Мейер М. Теория реляционных баз данных. - М.: Мир, 1997.

. Наталия Елманова. ADO в Delphi.

. Попов В.Б. Паскаль и Дельфи. Самоучитель

. С.М. Диго "Проектирование и использования баз данных". Москва: Финансы и статистика 2000.

. Тиори Т., Фрай Дж. Проектирование структур баз данных. В 2 кн., - М.: Мир, 1995.

. Фаронов В. Программирование баз данных в Delphi 6: учебный курс


Методические указания к выполнению лабораторных работ Компьютерное проектирование интерфейса пользоват

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ