Лабораторная работа № 2 - Северо

advertisement
ПРОГРАММИРОВАНИЕ
НА DELPHI
Методические указания
к выполнению лабораторных работ
для студентов направления подготовки 230100.62
«Информатика и вычислительная техника»
Составитель А. А. Будаева
ВЛАДИКАВКАЗ 2015
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ
Федеральное государственное бюджетное образовательное учреждение
высшего профессионального образования
«СЕВЕРО-КАВКАЗСКИЙ ГОРНО-МЕТАЛЛУРГИЧЕСКИЙ ИНСТИТУТ
(ГОСУДАРСТВЕННЫЙ ТЕХНОЛОГИЧЕСКИЙ УНИВЕРСИТЕТ)»
Кафедра автоматизированной обработки информации
ПРОГРАММИРОВАНИЕ
НА DELPHI
Методические указания
к выполнению лабораторных работ
для студентов направления подготовки 230100.62
«Информатика и вычислительная техника»
Составитель А. А. Будаева
Допущено редакционно-издательским советом
Северо-Кавказского горно-металлургического
института (государственного технологического
университета).
Протокол заседания РИСа № 1 от 17.01.2014 г.
ВЛАДИКАВКАЗ 2015
1
УДК 004.432.2
ББК 32.973.26-0.18.1
Б90
Рецензент:
Кандидат технических наук, доцент Даурова А. А.
Б90
Программирование на Delphi. Методические указания к выполнению лабораторных работ для студентов направления подготовки 230100.62
«Информатика и вычислительная техника» / Сост.: А. А. Будаева; СевероКавказский горно-металлургический институт (государственный технологический университет). – Владикавказ: Северо-Кавказский горно-металлургический институт (государственный технологический университет).
Изд-во «Терек», 2015. – 99 с.
УДК 004.432.2
ББК 32.973.26-0.18.1
Методические указания содержат описание 12 лабораторных работ, соответствующих рабочей программе по дисциплине «Программирование на Delphi» для студентов направления подготовки «Информатика и вычислительная техника» 230100.62.
В методических указаниях на примерах рассматриваются средства
языка Delphi, используемые в рамках объектно-ориентированной парадигмы. Приведены индивидуальные задания по каждой лабораторной
работе. Методические указания способствуют практическому освоению
всех этапов разработки программы для эффективного решения поставленной задачи на ПЭВМ, начиная от анализа условия задачи и заканчивая сдачей отчета по написанной программе.
Редактор: Иванченко Н. К.
Компьютерная верстка: Кравчук Т. А.
 Составление. ФГБОУ ВПО «Северо-Кавказский
горно-металлургический институт (государственный
технологический университет)», 2015
 Будаева А. А., составление, 2015
Подписано в печать 27.02.2015. Формат бумаги 60х84 1/16. Бумага офсетная. Гарнитура «Таймс».
Печать на ризографе. Усл. п.л. 5,75. Уч.-изд.л. 3,93. Тираж 20 экз. Заказ № ____.
Северо-Кавказский горно-металлургический институт (государственный
технологический университет). Изд-во «Терек».
Отпечатано в отделе оперативной полиграфии СКГМИ (ГТУ).
362021. Владикавказ, ул. Николаева, 44.
2
Оглавление
Общие методические указания к выполнению лабораторных работ ......... 4
Лабораторная работа № 1 ................................................................................ 5
Лабораторная работа № 2 ................................................................................ 13
Лабораторная работа № 3 ................................................................................ 20
Лабораторная работа № 4 ................................................................................ 24
Лабораторная работа № 5 ................................................................................ 29
Лабораторная работа № 6 ................................................................................ 34
Лабораторная работа № 7 ................................................................................ 48
Лабораторная работа № 8 ................................................................................ 59
Лабораторная работа № 9 ................................................................................ 76
Лабораторная работа № 10 .............................................................................. 80
Лабораторная работа № 11 .............................................................................. 88
Лабораторная работа №1 2 .............................................................................. 95
Список литературы ........................................................................................... 98
Приложение. Пример оформления отчета по лабораторной работе .......... 99
3
Общие методические указания
к выполнению лабораторных работ
При выполнении лабораторных работ необходимо:
1. В соответствии с целью работы сформулировать задачу, которая должна быть решена с помощью приложения.
2. Разработать алгоритм решения задачи.
3. Разработать приложение, включающее интерфейс, программные модули вычислительных процедур, формы представления результатов.
4. Выполнить компьютерное моделирование.
5. Произвести тестирование алгоритма и приложения.
6. Сделать выводы и обобщения.
7. Составить электронный вариант отчета с результатами выполнения приложения. Образец оформления титульного листа приведен в
приложении. При выполнении работ рекомендуется обратиться к литературе [1–9].
4
Лабораторная работа № 1
ПРОЕКТИРОВАНИЕ И РЕАЛИЗАЦИЯ
КЛАССОВ ПОЛЬЗОВАТЕЛЯ
Цель:
1) Изучение теоретических основ объектно-ориентированного
программирования;
2) Приобретение практических навыков проектирования интерфейсов классов;
3) Приобретение практических навыков создания иерархии классов.
ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
Объектно-ориентированное программирование (ООП) основано
на понятиях класса и экземпляра. Класс представляет собой объединенный набор данных и подпрограмм, предназначенных для обработки
этих данных. Например, класс данных «ученик» мог бы включать набор
переменных, содержащих информацию об ученике (имя и фамилия,
класс, в котором он учится, баллы по предметам и т. д.) – их называют
свойства класса данных, и набор операций (их называют методами),
предназначенных для управления данными класса «ученик» (перевод в
другой класс, выставление оценки и т. д.).
Общие принципы ООП
Инкапсуляция – объединение данных и методов их обработки;
разделение доступа к данным между классами.
Наследование – классы объектов могут наследовать свойства
друг друга; пример – классы «ученик» и «преподаватель» наследуют
некоторые свойства класса «человек».
Полиморфизм – методы объектов могут переопределяться. Пример – классы объектов «прямоугольник» и «круг» могут иметь разные
методы рисования с одним и тем же именем Draw()
В ООП программа представляет собой не просто последовательно
исполняемый набор инструкций, а совокупность подпрограмм, реагирующих на внешние события, такие как нажатие клавиши, кнопки
мыши и т. д.
5
Все современные языки программирования основаны на концепции ООП, позволяющей значительно увеличить сложность программ и
сократить время их разработки за счет более эффективного повторного
использования кода.
Пример. Пример объявления элементов класса
type
TForm1 = class(TForm) {Объявление класса-потомка через класспредок}
{Опубликованные элементы, заданные средой Delphi}
Button1: TButton;
Button2: TButton;
procedure ButtonlClick(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{Приватные элементы}
FNumber: Integer;
protected
{Защищенные элементы}
procedure SetNumber(ANumber: Integer); virtual;
public
{Общедоступные элементы}
Count: Integer;
published
(Опубликованные элементы}
property Number: Integer read FNumber write SetNumber;
end;
В этом классе с именем TForm1, являющемся непосредственным
потомком класса TForm, используются все перечисленные выше
секции.
Элементы Button1, Button2, Button1Click и Button2Click созданы
самой средой Delphi и являются опубликованными.
Элемент FNumber является приватным, и его нельзя использовать
вне модуля, в котором описан класс TForm1.
Элемент SetNumber является защищенным, и его можно использовать только в классе TForm1 и его потомках, независимо от того, в каких модулях они будут описаны.
6
Элемент Count является общедоступным, и его можно использовать в любом месте программы.
Наконец, элемент Number также является опубликованным, но созданным программистом, и его можно использовать всюду.
В потомках класса можно изменять область доступности отдельных компонентов, за исключением компонентов, объявленных в секции
private. При этом можно лишь расширять диапазон доступности, т. е.
возможны следующие трансформации:
protected —> public,
protected -> published,
public —> published.
Методы
Методы – это обычные подпрограммы (процедуры и функции),
объявленные внутри класса. Объявляются и описываются они так же,
как и обычные подпрограммы в модулях, т. е. в интерфейсе модуля
внутри соответствующего класса записывается лишь заголовок, а в исполнительной части – само содержание метода.
При описании методов в исполнительной части допускается записывать сокращенный заголовок без указания формальных параметров, а
для функции – и без указания типа возвращаемого результата. Если же
заголовок записывается полностью, список формальных параметров и
тип возвращаемого результата для функции должны быть идентичны
первоначальному объявлению. При описании метода перед его именем
должен быть поставлен квалификатор, в качестве которого выступает
имя класса (но не имя соответствующей переменной).
В отличие от обычных подпрограмм при обращении к методу ему
передается параметр Self – указатель на конкретный объект или класс, с
которым осуществляется работа.
При обращении к методу внутри класса, которому он принадлежит, используется его имя с набором соответствующих параметров, а
при обращении извне класса перед именем метода ставится квалификатор, в качестве которого выступает либо имя объекта, которому принадлежит метод (для обычных методов), либо имя класса, которому
принадлежит этот метод (для методов класса).
В самом методе может быть обращение к методам предков. При
обращении к методам предков перед именем метода ставится квалификатор, в качестве которого выступает имя класса-предка, для которого
7
определен применяемый метод, либо используется зарезервированное
слово inherited. В последнем случае вызывается метод с указанным
именем ближайшего предка, обладающего этим методом.
Конструкторы и деструкторы
Конструкторы и деструкторы являются специальными подпрограммами, предназначенными для создания и удаления конкретных
объектов в процессе выполнения программы. Они настолько важны и
специфичны, что определяются специальными зарезервированными
словами.
Конструктор предназначен для создания в динамической области
памяти объекта соответствующего класса и инициализации.
Объявляется конструктор с помощью зарезервированного слова
constructor, после которого, как и для других подпрограмм, следует
имя конструктора с помещенным в круглых скобках списком формальных параметров. По возможности конструктору следует давать имя
Create.
При описании конструктора, как правило, сначала вызывается
наследуемый конструктор предка. Далее идет заполнение полей теми
или иными значениями. Так как при создании объекта все байты полей
заполняются нулями, что соответствует нулевым значениям чисел, пустым строкам, значению False логических величин, значению nil указателей и т. д., то задавать следует только ненулевые значения.
Для создания объекта конструктор вызывается как подпрограммафункция, значение которой присваивается имени объекта. При этом
имя конструктора используется с квалификатором, в качестве которого
выступает имя класса, но не объект. Вызов этот осуществляется, когда
соответствующий объект еще не создан, с этой точки зрения конструктор родствен так называемым методам класса, которые могут вызываться без создания реальных объектов.
Для объектов, создаваемых Delphi, конструктор, как правило, не
используется, так как они создаются автоматически вместе с объектом
(например, с формой), в который они входят.
Деструктор предназначен для удаления из динамической области
памяти объекта и выполнения других побочных действий, связанных с
удалением объекта.
Объявляется деструктор с помощью зарезервированного слова
destructor, после которого, как и для других подпрограмм, следует имя
деструктора, как правило, без списка параметров. Как правило, де8
структор является виртуальным методом. Наиболее распространенными являются деструкторы с именем Destroy, родоначальниками которых является деструктор класса TObject.
При описании деструктора, обычно сначала выполняются действия, специфические для данного класса, а затем вызывается наследуемый деструктор предка. При этом заботиться об удалении объекта из
динамической области памяти не следует, так как оно выполняется
наследуемым деструктором. Как правило, в деструкторе выполняются
действия, противоположные тем, которые выполнялись в конструкторе,
и в обратном порядке.
Для удаления объекта деструктор вызывается как обычная подпрограмма. При этом имя деструктора используется без квалификатора,
если он вызывается внутри метода удаляемого объекта, или с квалификатором, в качестве которого выступает имя объекта, если он вызывается извне объекта.
Для объектов, создаваемых Delphi, деструктор, как и конструктор,
как правило, не используется, так как они удаляются автоматически
вместе с объектом (например, с формой), в который входят. Конечно,
если такой объект следует удалить, не удаляя объекта, в который он
входит, надо использовать деструктор.
ЗАДАНИЕ К РАБОТЕ
1. Требуется описать и реализовать соответствующий класс, в котором обязательно присутствуют следующие методы:
 Метод инициализации Init;
 Ввод с клавиатуры Read;
 Вывод на экран Display.
2. Все задания должны быть реализованы тремя способами:
 Тип данных представляется структурой с необходимыми полями, а операции реализуются как внешние функции, которые получают
объекты данного типа в качестве аргументов;
 Как класс с закрытыми полями, где операции реализуются как
методы класса;
 Инкапсулировать поля класса в независимой структуре и в ней
реализовать указанные методы; в основном классе должно быть одно
поле данных, представленное объектом-структурой.
9
Задание 1 – Проектирование интерфейса класса
Вариант
1
1, 7, 13
a.
b.
c.
d.
e.
f.
2, 8, 14
a.
b.
c.
d.
e.
3, 9
4, 10
5, 11
6, 12
Задание
2
Комплексное число представляется парой действительных чисел
(a,b), где f – действительная часть, b – мнимая часть. Реализовать
класс Complex для работы с комплексными числами. Обязательно
должны присутствовать операции:
Сложения add, (a,b)+(c.d) = (a+b, c+d);
Вычитания sub, (a,b)-(c.d) = (a-b, c-d);
Умножение mul, (a,b)*(c,d) = (aс-bd, ad+bc);
Деление div, (a,b)/(c,d) = (ac + bd, bc-ad)/(c2 + d2);
Сравнение equ, (a,b) = (c,d), Если (a=c) и (b = d );
Сопряженное число conj, conj(a,b) = (a, -b).
Рациональная (несократимая) дробь представляется парой целых чисел (а, b), где а — числитель, b — знаменатель. Создать класс
Rational для работы с рациональными дробями. Обязательно должны
быть реализованы операции:
сложения add, (а, b) + (с, d) = (ad + be, bd);
вычитания sub, (a, b) – (с, d) = (ad – be, bd);
умножения mul, (a, b) x (c,d) = (ac, bd);
деления div, (a, b) / (с, d) = (ad, be);
сравнения equal, greate, less.
Должна быть реализована приватная функция сокращения дроби
reduce, которая обязательно вызывается при выполнении арифметических операций.
Создать класс vector3D, задаваемый тройкой координат. Обязательно
должны быть реализованы: сложение и вычитание векторов, скалярное произведение векторов, умножение на скаляр, сравнение векторов, вычисление длины вектора, сравнение длины векторов.
Создать класс Money для работы с денежными суммами. Число должно
быть представлено двумя полями: рубли и копейки. Дробная часть (копейки) при выводе на экран должна быть отделена от целой части запятой. Реализовать сложение, вычитание, деление сумм, деление суммы на
дробное число, умножение на дробное число и операции сравнения
Создать класс Triangle для представления треугольника. Поля данных
должны включать углы и стороны. Требуется реализовать операции:
получения и изменения полей данных, вычисления площади, вычисления периметра, вычисления высот, а также определения вида треугольника (равносторонний, равнобедренный или прямоугольный)
Создать класс Point для работы с точками на плоскости. Координаты
точки — декартовы. Обязательно должны быть реализованы: перемещение точки по оси X, перемещение по оси Y, определение расстояния до начала координат, расстояния между двумя точками, преобразование в полярные координаты, сравнение на совпадение и несовпадение
10
Вариант
1
1.
2.
3.
4.
5.
6.
7.
8.
Задание 2 – Создание иерархии классов
Задание
2
Создать абстрактный базовый класс с виртуальной функцией – площадь. Создать производные классы: прямоугольник, круг, прямоугольный треугольник, трапеция со своими функциями площади.
Для проверки определить массив ссылок на абстрактный класс, которым присваиваются адреса различных объектов. Площадь трапеции:S=(a+b)h/2.
Создать абстрактный класс с виртуальной функцией: норма. Создать
производные классы: комплексные числа, вектор из 10 элементов, матрица (2х2). Определить функцию нормы – для комплексных чисел –
модуль в квадрате, для вектора – корень квадратный из суммы элементов по модулю, для матрицы – максимальное значение по модулю.
Создать абстрактный класс (кривые) вычисления координаты y для некоторой x. Создать производные классы: прямая, эллипс, гипербола со своими функциями вычисления y в зависимости от входного параметра x.
Уравнение прямой: y=ax+b , эллипса: x2/a2+y2/b2=1, гиперболы: x2/a2y2/b2=1.
Создать абстрактный базовый класс с виртуальной функцией – сумма прогрессии. Создать производные классы: арифметическая прогрессия и геометрическая прогрессия. Каждый класс имеет два поля
типа double. Первое – первый член прогрессии, второе (double) – постоянная разность (для арифметической) и постоянное отношение
(для геометрической). Определить функцию вычисления суммы, где
параметром является количество элементов прогрессии.
 Арифметическая прогрессия aj=a0+jd, j=0,1,2,…
 Сумма арифметической прогрессии: sn=(n+1)(a0+an)/2
 Геометрическая прогрессия: aj=a0rj, j=0,1,2,…
 Сумма геометрической прогрессии: sn=(a0-anr)/(1-r)
Создать базовый класс список. Реализовать на базе списка стек и
очередь с виртуальными функциями вставки и вытаскивания.
Создать базовый класс – фигура, и производные класс – круг, прямоугольник, трапеция. Определить виртуальные функции площадь, периметр и вывод на печать.
Создать базовый класс – работник и производные классы – служащий с почасовой оплатой, служащий в штате и служащий с процентной ставкой. Определить функцию начисления зарплаты.
Создать абстрактный базовый класс с виртуальной функцией – площадь поверхности. Создать производные классы: параллелепипед,
тетраэдр, шар со своими функциями площади поверхности. Для проверки определить массив ссылок на абстрактный класс, которым
присваиваются адреса различных объектов.
Площадь поверхности параллелепипеда: S=6xy. Площадь поверхности шара: S=4 r2. Площадь поверхности тетраэдра: S=a2 3
11
Окончание таблицы
1
9.
10.
11.
12.
13.
14.
2
Создать класс человек, производные от которого девушки и молодые
люди. Определить виртуальную функцию реакции человека на вновь
увиденного другого человека.
Создать абстрактный базовый класс с виртуальной функцией – объем. Создать производные классы: параллелепипед, пирамида, тетраэдр, шар со
своими функциями объема. Для проверки определить массив ссылок на абстрактный класс, которым присваиваются адреса различных объектов.
Объем параллелепипеда – V = xyz (x, y, z – стороны пирамиды: V = xyh (x, y, – стороны, h – высота), тетраэдра: V = a3 2/12, шара: V = 4 r3/3.
Создать абстрактный класс – млекопитающие. Определить производные классы – животные и люди. У животных определить производные классы собак и коров. Определить виртуальные функции
описания человека, собаки и коровы.
Создать базовый класс – Предок, у которого есть имя. определить
виртуальную функцию печати. Создать производный класс Ребенок,
у которого функция печати дополнительно выводит имя. Создать
производный класс от последнего класса – Внук, у которого есть отчество. Написать свою функцию печати.
Создать класс живущих с местоположением. Определить наследуемые классы – лиса, кролик и трава. Лиса ест кролика. Кролик ест
траву. Лиса может умереть – определен возраст. Кролик тоже может
умереть. Кроме этого определен класс – отсутствие жизни. Если в
окрестности имеется больше травы, чем кроликов, то трава остается,
иначе трава съедена. Если лис слишком старый он может умереть.
Если лис слишком много (больше 5 в окрестности), лисы больше не
появляются. Если кроликов меньше лис, то лис ест кролика.
Создать абстрактный базовый класс с виртуальной функцией – корни
уравнения. Создать производные классы: класс линейных уравнений
и класс квадратных уравнений. Определить функцию вычисления
корней уравнений.
Содержание отчета
1. Номер, тема, цель лабораторной работы.
2. Задание к работе.
3. Описание входных, промежуточных и результирующих данных
с указанием их типа.
4. Математическая модель задачи.
5. Схема алгоритма решения задачи по ГОСТу.
6. Программа на языке программирования.
7. Результат выполнения программы.
8. Вывод о проделанной работе.
12
Лабораторная работа № 2
ЗНАКОМСТВО С ОСНОВАМИ
ВИЗУАЛЬНОГО ПРОГРАММИРОВАНИЯ
Цель:
1. Овладение основными приемами работы с формами
2. Приобретение практических навыков разработки приложения с
использование компонентов с ввода и отображения информации (Edit,
Memo, MaskEdit, Bitbtn, Button, Label).
3. Приобретение практических навыков разработки приложения с
использование компонентов переключателей: RadioButton, GroupBox,
CheckBox.
ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
2.1. Работа с формами
Форма – это компонент Form класса TForm. На ее основе конструируется приложение.
Существуют 2 класса форм:
1. Немодальные – те, которые позволяют переключаться в другую
форму приложения без своего закрытия;
2. Модальные – те, которые требуют обязательного закрытия перед обращением к другой форме. Премером модальных форм могут
служить стандартные диалоги ShowMessage, MessageDlg, InputBox.
Каждое приложение имеет одну главную форму и, возможно, несколько второстепенных. Главная форма загружается автоматически
при запуске приложения. Чтобы сделать форму главной надо в файле
проекта оператор, отвечающий за создание данной формы, поставить на
первое место.
Каждая форма имеет две области:
1. Клиентская область – та часть формы, в которой размещаются
визуальные компоненты;
2. Неклиентская область – занята рамкой, заголовком формы и
строкой главного меню.
Свойства и методы форм:
- visible – позволяет скрывать и отображать данную форму;
- left, top – задают координаты расположения формы на экране;
- width, height – задают размеры формы;
13
- active – определяет активность формы;
- clientwidth – возвращает ширину клиентской области;
- clientheight – возвращает высоту клиентской области;
- windowstate – определяет состояние отображаемой формы;
- show – отображает форму в немодальном режиме, при этом свойство visible автоматически устанавливается в True;
- showmodal – отображает форму в модальном режиме;
- hide – скрывает форму;
- close – закрывает форму (форма делается невидимой но не уничтожается);
- destroy – уничтожает форму.
В приложении формы могут взаимодействовать друг с другом
тремя способами:
1. Если одна форма выполняет действия с другой формой, то в
списке Uses раздела Implementation модуля первой формы должна быть
ссылка на модуль второй формы;
2. Delphi позволяет выполнить автоматизированную вставку
ссылки. Для этого выбираем File/UseUnit и в появившемся диалоговом
окне выбираем нужную форму;
3. Форма может выполнять различные действия с компонентами
другой формы. В этом случае при обращении к нужному компоненту
указывается форма, которой он принадлежит, и вставляется ссылка на
модуль другой формы.
ЗАДАНИЕ К РАБОТЕ
1. Написать приложение, состоящее из 2-х форм. На первой расположить:
 два текстовых поля, в которых задаются координаты вывода
второй формы;
 кнопку «Форма 2», при нажатии на которую открывается вторая форма и располагается в заданном месте экрана;
 кнопку «Движение», при нажатии на которую Форма 2 осуществляет движение по горизонтали в одну и другую стороны до границ экрана.
2. Написать приложение, состоящее из 2-х форм. На первой расположить:
 два текстовых поля, в которых задаются координаты вывода
второй формы;
14
 кнопку «Форма 2», при нажатии на которую открывается вторая форма и располагается в заданном месте экрана;
 кнопку «Движение», при нажатии на которую Форма 2 осуществляет движение по вертикали вверх и вниз до границ экрана
3. Написать приложение, состоящее из 2-х форм. На первой расположить:
 два текстовых поля, в которых задаются размеры второй формы;
 кнопку «Форма 2», при нажатии на которую открывается вторая форма заданного размера;
 кнопку «Изменить», при нажатии на которую Форма 2 то увеличивает, то уменьшает размеры до определенных пределов. Визуальные компоненты, расположенные на Форме2, закрепить на ней таким
образом, чтобы они перемещались вместе с границами формы.
4. Написать приложение, состоящее из 2-х форм. На первой расположить:
 четыре текстовых поля, в которых задаются максимально и минимально возможные размеры второй формы;
 кнопку «Форма 2», при нажатии на которую открывается вторая форма заданного размера;
 На второй форме расположить кнопку «Изменить», при нажатии на которую Форма1 то увеличивает, то уменьшает размеры до заданных пределов.
5. Написать приложение, состоящее из 2-х форм. На первой расположить:
 кнопку «Форма 2», при нажатии на которую открывается вторая форма, размещается в центре экрана и не допускается изменение
размеров Формы2;
 кнопку «Закрыть», при нажатии на которую Форма 2 закрывается;
 кнопку «Уничтожить», при нажатии на которую Форма2 уничтожается.
Создать главную форму разместить на ней кнопки Button. Каждая
кнопка соответствует номеру лабораторной работы и одна кнопка является выходом из приложения. Все компоненты Button должны иметь
всплывающую подсказку, указывающую номер лабораторной работы.
Каждая лабораторная работа должна начинаться с загрузки
формы, на которой в соответствующих компонентах должны быть
указаны тема, цель и задание к работе, а также реализованы 2 кноп15
ки: запускающая программу и осуществляющая возврат к главной
форме.
2.2. Компоненты ввода и отображения информации
Однострочный редактор – это поле ввода информации, в котором можно отображать и изменять текст.
1. Edit – позволяет вводить с клавиатуры и редактировать различные символы и имеет следующие свойства:
- Text – позволяет получить доступ к содержимому текстового
редактора;
- CharCase – служит для изменения регистра;
- PasswordChar – задает символ для ввода пароля.
2. MaskEdit – дополнительно к обычному редактору предоставляет возможность ограничения вводимой информации по шаблону и имеет дополнительное свойство EditMask, которое задает маску.
Многострочный редактор – это поле для ввода или отображения
информации, которое имеет несколько строк. К ним относится компонент Memo.
Для работы с ним рекомендуется использовать следующие свойства:
 Text – используется для доступа ко всему содержимому редактора;
 Lines – массив строк данного редактора с помощью которого
можно получить доступ к любой строке;
 ScroolBar – задает расположение полосы прокрутки;
 Alignment- задает выравнивание;
Все компоненты редактирования имеют набор общих свойств, методов и событий.
 MaxLength – максимальное количество символов, которые могут отображаться в редакторе;
 AutoSelect – определяетбудет ли автоматически выделен текст
в элементе редактирования;
 SelText – выделенный фрагмент;
 SelStar, SelLength – начальная позиция и длина выделенного
фрагмента;
 SelectAll – выделяет весь текст в элементе редактирования;
 CopyToClipBoard – копирует в буфер обмена выделенный
фрагмент;
16
 PastFromClipBoard – вставляет текст из буфера обмена в место
текущего расположения курсора;
 Add – добавляет новую строку в многострочный редактор.
ЗАДАНИЕ К РАБОТЕ
1. Разработать интерфейс приложения с применением компонентов Edit, Memo, MaskEdit, Bitbtn, Button, Label.
2. Разработать алгоритм решения задачи в соответствии с вариантом задания.
3. Реализовать разработанный алгоритм в рамках ранее созданного интерфейса.
4. Проверить работоспособность с помощью тестового набора
данных.
Даны две квадратные матрицы A(n, n) и B(n,n), где n <=10. Выполнить действия с матрицами. Ввод матриц произвести из блока данных
или путем присваивания.
Вариант
1
2
3
4
5
6
7
8
Задание
2(A-0.5B)-AB
A2-(A+B)(A-3B)
(A2+B2)-2AB
(3A-2B)-4AB
A2-(4a+3B)
5(B+3A)+AB
(A+4B)(3A-B)-A
AB-(3B+A)
2.3. Использование компонентов переключателей
Переключатели позволяют выбирать какое-либо значение из определенного множества.
Checkbox – это переключатель с независимой фиксацией (или
флажок)
 Checked – определяет состояние флажка (истина или ложь)
 Enabled – определяет активность флажка.
RadioButton – это переключатель с зависимой фиксацией. Выбор
переключателей взаимоисключающий. Каждый переключатель, поме17
щенный на контейнер, включается в группу. Контейнерами могут быть
Form, Panel, GroupBox.
Для работы с группой переключателей можно использовать следующие свойства и методы:
 Items – позволяет получить доступ к отдельным переключателям в группе;
 Add – добавляет переключатель в группу;
 Delete – удаляет переключатель из группы;
 Itemindex – номер выбранного переключателя.
Контейнер – это визуальный компонент, который позволяет размещать на своей поверхности другие компоненты, объединяет их и становится их владельцем.
GroupBox – рамка с заголовком. Может служить для объединения
переключателей или флажков по смыслу. Заголовок рамки задает свойство Caption.
Panel – панель, которая имеет край с двойной фаской.
 BevelWidth – ширина каждой фаски в пикселах;
 BevelInner – вид внутренней фаски;
 BevelOuter – вид внешней фаски;
 BorderWidth – промежуток между фасками в пикселах.
ScrollBox – окно с полосами прокрутки для просмотра информации.
 Align – выравнивание области прокрутки внутри контейнера;
 ScrollInView – автоматически изменяет позиции полос прокрутки, чтобы интересующий компонент появился в видимой области.
Frame – контейнер для других компонентов, который на этапе разработки создается как и форма, но может быть размещен в другом контейнере. Ссылка на компоненты Frame осуществляется через имя компонента Frame.
ЗАДАНИЕ К РАБОТЕ
Разработать приложение «Тест» в соответствии с вариантом задания. Тест должен содержать 10 вопросов. На каждый вопрос должны
быть предусмотрены 3 варианта ответов. По результатам теста проставляется оценка и выводится в информационном окне.
На форме расположить:
- 1 компонент Memo,
- 3 компонента RadioButton,
18
- 2 компонента BitBtn;
- 1 компонент GroupBox.
Номер вопроса должен выводиться в заголовке GroupBox. Сообщение о полученной оценке должно выводится с помощью функции вводавывода ShowMessage, в котором находится сообщение и кнопка OK.
Вариант
1
2
3
4
5
6
7
8
Задание
Тест «Знаете ли Вы историю России?»
Тест «Знаете ли Вы Delphi?»
Тест «Знаете ли Вы русский язык?»
Тест «Любите ли Вы олимпийские игры?»
Тест «Хорошо ли Вы знаете новые компьютерные игры?»
Тест «Хорошо ли Вы знаете направления музыки?»
Тест «Знаете ли Вы названия картин?»
Тест «Знаете ли Вы города России?»
Содержание отчета
1. Номер, тема, цель лабораторной работы.
2. Задание к работе.
3. Описание входных, промежуточных и результирующих данных
с указанием их типа.
4. Математическая модель задачи.
5. Схема алгоритма решения задачи по ГОСТу.
6. Программа на языке программирования.
7. Результат выполнения программы.
8. Вывод о проделанной работе.
19
Лабораторная работа № 3
ОБРАБОТКА
СИМВОЛЬНОЙ ИНФОРМАЦИИ
Цель: приобретение практических навыков разработки приложения для обработки символьной информации с использованием компонентов ListBox, ComboBox.
ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
Список – это прямоугольная область, в которой расположены
его элементы. Для работы с простым списком используется компонент
ListBox. При необходимости в нем появляются горизонтальные и
вертикальные полосы прокрутки. Комбинированный список объединяет
поле редактирования и список. Для работы с ним используется
компонент ComboBox. Для него свойство Style определяет внешний
вид и поведение списка. Свойство DropDounCount определяет
количество строк, которые отображаются в раскрывающемся списке.
Для простых и комбинированных списков применяют схожие свойства
и методы:
 Items – массив строк данного списка
 ItemIndex – номер выбранного элемента списка
 MultiSelect – предоставляет возможность множественного выбора
 SelCount – возвращает число выбранных элементов
 Selected – массив логических значений, каждый элемент которого соответствует состоянию выбора соответствующего элемента
списка при множественном выборе
 Count – число элементов в списке
 Add – добавляет строку в конец списка
 Insert – вставляет строку в список на позицию с указанным номером
 Assign – копирует информацию из одного списка в другой с заменой его содержимого
 Delete – удаляет элемент с заданным номером
 Sorted – сортирует элементы списка
 Clear – очищает весь список
20
ЗАДАНИЕ К РАБОТЕ
1. Разработать интерфейс приложения с применением компонентов ListBox, ComboBox, CheckBox, RadioButton и др.
2. Разработать алгоритм решения задачи в соответствии с вариантом задания.
3. Реализовать разработанный алгоритм в рамках ранее созданного интерфейса.
4. Проверить работоспособность с помощью тестового набора
данных.
5. Оформить отчет.
Задание 1
По выбранному из списка СomboBox дню недели вывести в список ListBox расписание занятий группы на выбранный день.
На форме расположить:
- 1 компонент ListBox,
- 1 компонент ComboBox,
- 2 компонента BitBtn.Выбор заданного параметра производится
из компонента ComboBox. Выбранные данные отображаются в компоненте ListBox.
21
Задание 2
Вариант
1
1, 8
2, 9
3, 10
4, 11
5, 12
6, 13
Задание
2
Создать приложение, в котором организовано взаимодействие двух
списков. При запуске первый список заполняется названиями месяцев, а второй список очищается. Оба списка допускают множественный выбор элементов. При нажатии кнопок «» и «» выбранные
элементы одного списка перемещаются в другой.
Организовать программную прорисовку элементов списка. Для выделенных элементов отображается рисунок, загруженный из одного
файла, а для невыделенных – из другого. Выделенные элементы дополнительно отмечаются желтым цветом символов на синем фоне.
Написать приложение, которое помогает получить любую информацию об успеваемости группы студентов. На первой форме расположено текстовое поле и список. В поле заносится фамилия студента и
оценка, полученная на экзамене. Введенная информация добавляется
в качестве очередной записи в список. На второй форме расположены
два списка: комбинированный и простой. В комбинированном списке
находятся оценки, полученные студентами на экзамене. При выборе
оценки, во втором списке отображаются фамилии студентов, получивших данную оценку.
Написать приложение, которое помогает получить любую информацию о репертуаре кинотеатров. На первой форме расположено текстовое поле и список. В поле заносится название кинотеатра и фильм.
Введенная информация добавляется в качестве очередной записи в
список. На второй форме расположены два списка: комбинированный
и простой. В комбинированном списке находятся названия кинотеатров. При выборе кинотеатра во втором списке отображаются фильмы,
которые идут в нем.
Написать приложение, которое позволяет работать со списком товаров. На форме расположено текстовое поле, в которое вводится
название товара. Введенный товар помещается в список всех товаров
только в том случае, если там такого товара не существовало. Кнопка
«Удалить» позволяет удалять выбранные товары из списка. Кнопка
«Результат» помещает все выбранные товары на метку, расположенную на форме.
Написать приложение, которое позволяет работать со списком растений цветочного магазина. На форме расположено текстовое поле, в
которое вводится название растения. Введенный цветок помещается в
список всех растений только в том случае, если там такого растения
не существовало. Кнопка «Удалить» позволяет удалять выбранные
растения из списка. Кнопка «Результат» помещает все выбранные
растения на метку, расположенную на форме.
22
Окончание таблицы
1
7, 14
2
Написать приложение, которое позволяет работать со списком музыкальных групп. На форме расположено текстовое поле, в которое
вводится название группы. Она помещается в список всех групп
только в том случае, если там такой группы не существовало. Кнопка
«Удалить» позволяет удалять выбранные группы из списка. Кнопка
«Результат» помещает все выбранные группы на метку, расположенную на форме.
Содержание отчета
1. Номер, тема, цель лабораторной работы.
2. Задание к работе.
3. Описание входных, промежуточных и результирующих данных
с указанием их типа.
4. Математическая модель задачи.
5. Схема алгоритма решения задачи по ГОСТу.
6. Программа на языке программирования.
7. Результат выполнения программы.
8. Вывод о проделанной работе.
23
Лабораторная работа № 4
ПРОЕКТИРОВАНИЕ
ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА
Цель:
1) Приобретение практических навыков разработки приложения с
использованием компонентов таблиц, а также главного и вспомогательного меню: (MainMenu, PopupMenu, StringGrid);
2) Приобретение практических навыков разработки приложений с
использованием компонентов OpenPictureDialog, FontDialog, ColorDialog, Open Dialog.
Часть 1. Использование компонентов
MainMenu, PopupMenu, StringGrid
В Delphi есть два компонента, используемые для создания меню:
MainMenu – главное меню и PopupMenu – контекстное меню.
MainMenu – невизуальный компонент. Наиболее важным свойством этого компонерта является свойство Items. Для его заполнения
нужно вызвать Menu Designer, которое появляется при двойном щелчке
по компоненту MainMenu. Каждый элемент свойства Items – это отдельный пункт меню, который обладает следующими свойствами:
 Caption – заголовок пункта меню;
 Count – указывает количество элементов;
 Dafault – устанавливает данный пункт меню в качестве используемого по умолчанию;
 MenuIndex – Вычисляет индекс указанного пункта меню;
 ShortCut – позволяет указать «горячую» клавишу для данного
пункта меню.
PopupMenu – невизуальный компонент, который в отличие от
главного меню, которое постоянно находится на экране, выводится в
случае необходимости при нажатии правой кнопки мыши на компонент, с которым оно связано.
Для того, чтобы связать это меню с определенным компонентом,
используется свойство PopupMenu визуальных компонентов.
StringGrid – позволяет хранить и автоматически отображать текстовую информацию.
24
Основные свойства
 ColCount, RowCount – задают число строк и число столбцов
таблицы (нумерация с нуля);
 ColWidth, RowHeigth – задают высоту строк и ширину столбцов;
 FixedCols,FixedRows – задают число фиксированных строк и
столбцов(остаются недвижимыми при прокрутке);
 Cells[aCol, aRow] – используется для доступа к отдельной
ячейке, aCol – номер столбца, aRow – номер строки;
 Cols[index], Row[index] – обеспечивает доступ к любому столбцу и строке таблицы.
ЗАДАНИЕ К РАБОТЕ
1) При выборе 1 пункта на экране должно раскрываться
подменю, состоящее из 2 пунктов: «Условие задачи 1», «Решение задачи 1».
При выборе пункта «Условие задачи 1» должна появляться форма,
на которой расположены условие и рисунок с соответствующим графиком. При щелчке мышью на рисунке должно появляться всплывающее
меню, состоящее из двух пунктов: «Показать рисунок», «Скрыть рисунок». (Рисунок области создать в графическом редакторе Paint и вставить на форму как картинку).
При выборе пункта «Решение задачи 1» должна появляться форма,
на которой производится ввод исходных данных, и вывод полученных
результатов.
2) При выборе 2 пункта на экране должно раскрываться подменю,
состоящее из 2 пунктов: «Условие задачи 2», «Решение задачи 2».
При выборе пункта «Условие задачи 2» должна появляться форма,
на которой расположены условие задачи.
При выборе пункта «Решение задачи 2» должна появляться форма,
на которой должны выводиться таблица значений функции и график
заданной функции. (График построить с помощью Excel и вставить на
форму как картинку)
При щелчке мышью на таблице должно появляться всплывающее
меню, состоящее из 3 пунктов: «Очистить таблицу», «Скрыть таблицу»,
«Показать таблицу».
3) При выборе 3 пункта осуществляется выход на главную форму
приложения.
25
Задание 1
По заданным координатам точки M(x,y) определить попадает или
нет точка М в заштрихованную область.
Вариант 1, 9
Вариант 2, 10
Вариант 3, 11
Вариант 4, 12
3
1
1
2
-3
3
1
0
0
0
-1
2
Вариант 5, 13
1
-1
0
Вариант 6, 14
Вариант 7, 15
-1
Вариант 8, 16
3
-5
-4
2
-2
0
0
-1
-1
-5
Задание 2
№
Функция
а
1, 9
sin 𝑥 − cos 𝑥
0
2, 10
sin 2𝑥 − 3
0
3, 11
sin2 3𝑥
−𝜋
4, 12
cos 3𝑥 + sin 𝑥
5, 13
−5 + 𝑡𝑔 𝑥
6, 14
𝑐𝑡𝑔 3𝑥 − cos 𝑥
7, 15
8, 16
b
𝜋
2
𝜋
N
20
15
20
𝑙𝑛|3𝑥 − 4| + 2
0
𝜋
−
3
𝜋
6
2
𝜋
𝜋
6
𝜋
3
𝜋
2
4
2𝑥+3 − 4
-3
4
20
26
15
15
20
15
Часть 2. Использование стандартных диалоговых окон
В Delphi имеется ряд диалогов для операционной системы Windows.
OpenDialog – компонент представляет собой стандартное диалоговое окно выбора и открытия файлов.
OpenPictureDialog – предназначен для открытия графических файлов.
Основные свойства:
 FileName – содержит имя выбранного файла;
 Files – содержит список имен выделенных файлов;
 Filter – позволяет задавать фильтр для файлов, которые будут
отображаться в диалоговом окне;
 InitialDir – позволяет установить начальный каталог поиска в
Инспекторе объектов.
FontDialog – предназначен для настройки шрифта и его характеристик.
Основные свойства
 Font – результат изменения характеристик шрифта;
 MaxFontSize – установка максимального размера шрифта;
 MinFontSize – установка минимального размера шрифта.
ColorDialog – предоставляет возможность выбора определенного
цвета из палитры.
Основным свойством является свойство Color – содержит данные
о выбранном пользователем цвете.
ЗАДАНИЕ К РАБОТЕ
На форме расположить следующие компоненты: Panel, Image,
RichEdit, , OpenPictureDialog, FontDialog, Open Dialog, ColorDialog, 3
PopupMenu, BitBtn.
PopupMenu компонента Image должно содержать пункт вызова
окна OpenPictureDialog.
PopupMenu компонента RichEdit должно содержать пункты вызова
окна FontDialog и Open Dialog.
PopupMenu формы должно содержать пункт вызова окна ColorDialog
При выборе изображения с помощью компонента OpenPictureDialog в компоненте Image должно отображаться выбранное изображение,
одновременно с этим в компоненте RichEdit должна отображаться ин27
формация, соответствующая выбранному изображению. И наоборот,
при выборе информационного файла с помощью компонента OpenDialog в компоненте RichEdit должна выводится информация из выбранного файла и одновременно в Image загружаться изображение, соответствующее выбранному текстовому файлу. Кроме того, с помощью ColorDialog должно быть предусмотрено смена цвета формы, а с помощью
FontDialog, изменение настроек RichEdit.
Каждый визуальный компонент должен быть снабжен всплывающей подсказкой
Напишите программу, использующую 7 изображений.
Вариант
1, 9
2, 10
3, 11
4, 12
5, 13
6, 14
7, 15
8, 16
Задание
Картинная галерея
Автомобили
Компьютерные игры
Телефоны
Семь чудес света
Семь чудес России
Великие ученые
Столицы мира
Содержание отчета
1. Номер, тема, цель лабораторной работы.
2. Задание к работе.
3. Описание входных, промежуточных и результирующих данных
с указанием их типа.
4. Математическая модель задачи.
5. Схема алгоритма решения задачи по ГОСТу.
6. Программа на языке программирования.
7. Результат выполнения программы.
8. Вывод о проделанной работе.
28
Лабораторная работа № 5
ОБРАБОТКА ИСКЛЮЧИТЕЛЬНЫХ СИТУАЦИЙ
Цель: приобретение практических навыков обработки исключительных ситуаций.
ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
Исключительная ситуация – это нарушение условий выполнения
программы, вызывающее прерывание или полное прекращение ее работы. Обработка исключительных ситуаций состоит в нейтрализации динамической ошибки, вызвавшей ее.
Базовым классом для всех исключений является класс Exception.
Объекты данного класса имеют следующие свойства и методы:
 Message – описание исключительной ситуации;
 HelpContext – номер идентификатора контекстной помощи для
объекта исключения;
 Create – метод, который служит для создания объекта исключительной ситуации.
Класс Exception имеет множество потомков, каждый из которых
служит для обработки определенной динамической ошибки.
Обработка исключительных ситуаций может происходить по двум
направлениям:
1. Глобальная обработка исключений. Механизм ее реализуется
через объект Application. При получении от системы сообщения об исключении объект Application генерирует событие OnException. Программист может создать свой глобальный обработчик. С этой целью
удобно использовать компонент ApplicationEvents, для которого пишется обработчик события OnException/
2. Локальная обработка исключений. Для обеспечения возможности использования специализированных обработчиков исключений, в
состав языка введены две конструкции try… finally и try…exept.
Try
//операторы, выполнение которых может вызвать ошибку
Finally
//операторы, которые должны быть выполнены в случае ошибки
End;
29
Данная конструкция применяется для выполнения всех необходимых действий перед передачей управления на следующий уровень обработки ошибки или глобальному обработчику. Если в любом из операторов секции try возникает исключительная ситуация, то управление
передается первому оператору секции finally для выполнения всех операторов секции. Если исключительная ситуация не возникла, то последовательно выполняются все операторы обеих секций.
Try
//операторы, выполнение которых может вызвать ошибку
Except
//операторы, которые должны быть выполнены в случае ошибки
End;
Эта конструкция применяется для перехвата исключительной ситуации и предоставляет возможность ее обработки. Если в операторах
секции try возникла исключительная ситуация, то управление передается первому оператору секции except. Если исключительная ситуация не
возникла, то операторы секции Except не выполняются. Секция except
может быть разбита на несколько частей конструкциями on…do. Это
позволяет анализировать класс исключительной ситуации с целью ее
обработки.
При необходимости исключительную ситуацию можно вызвать
программно. Для этого используется оператор Raise, выполнение которого приводит к созданию объекта исключения класса Exception или
одного из его потомков. Оператор имеет следующий синтаксис:
Raise ClassException.Method;
Процесс отладки исключительных ситуаций в Delphi имеет некоторые особенности. По умолчанию при возникновении динамической
ошибки Delphi перехватывает исключительную ситуацию и выдает соответствующее сообщение. Если работу приложения надо продолжить,
то необходимо выбрать из меню Run команду Run и возникшее исключение будет обработано средствами приложения.
Исключительные ситуации:
 EConvertError – происходит в случае возникновения ошибки
при выполнении функций StrToInt и StrToFloat, когда конвертация
строки в соответствующий числовой тип невозможна.
 EIntError – предок исключений, случающихся при выполнении
целочисленных операций.
30
 EDivByZero – вызывается в случае деления на ноль, как результат RunTime Error 200.
 EIntOverflow – вызывается при попытке выполнения операций,
приводящих к переполнению целых переменных, как результат
RunTime Error 215 при включенной директиве {$Q+}.
 ERangeError – вызывается при попытке обращения к элементам
массива по индексу, выходящему за пределы массива, как результат
RunTime Error 201 при включенной директиве {$R+}.
 EInvalidCast – происходит при попытке приведения переменных одного класса к другому классу, не совместимому с первым
(например, приведение переменной типа TListBox к TMemo).
 EListError – вызывается при обращении к элементу наследника
TList по индексу, выходящему за пределы допустимых значений
(например, объект TStringList содержит только 10 строк, а происходит
обращение к одиннадцатому).
 EMathError – предок исключений, случающихся при выполнении операций с плавающей точкой.
 EOverflow – происходит как результат переполнения операций
с плавающей точкой при слишком больших величинах. Соответствует
RunTime Error 205.
 Underflow – происходит как результат переполнения операций
с плавающей точкой при слишком малых величинах. Соответствует
RunTime Error 206.
 EZeroDivide – вызывается в результате деления на ноль.
 EMenuError – вызывается в случае любых ошибок при работе с
пунктами меню для компонент TMenu, TMenuItem, TPopupMenu и их
наследников.
ЗАДАНИЕ К РАБОТЕ
Вариант
Задание
1
2
1
Создать программу, позволяющую пользователю ввести
два числа, которые программа разделит. Необходимо поместить на форму три объекта класса TEdit – два для операндов, один – для результата и кнопку (объект класса
TButton), нажимая на которую пользователь выполняет деление. Исключить попытку деления на ноль а также введения символов вместо цифр. Выдать сообщение о типе возникшей ошибки.
31
Продожение таблицы
1
2
3
4
5
6
7
8
2
Создать программу, вычисляющую корни квадратного уравнения
(ax2+bx+c=0). Необходимо поместить на форму четыре объекта
класса TEdit – три для коэффициентов квадратного уравнения, один
– для результата и кнопку (объект класса TButton), нажимая на которую пользователь выполняет нахождение корней. Исключить
ввод символов вместо цифр, получение отрицательного дискриминанта и ввод а = 0. Вывести при всех типах ошибок одно и то же
сообщение.
Создать программу с “бесконечным” циклом типа while. В цикле
увеличивать переменную I до значения, заданного пользователем.
При достижении этого значения выходить из цикла с помощью
возбуждения исключения EAbort. Выдать сообщение о выходе из
цикла в блоке Except. Необходимо поместить на форму кнопку
(объект класса TButton), которая запускает цикл; сообщение можно
выдать с помощью функции ShowMessage, или поместить на форму
метку (объект класса TLabel), в которую помещается сообщение.
Создать программу, вычисляющую тангенс угла. Необходимо поместить в форму два компонента TEdit для ввода значения и результата и кнопку TButton для вычисления значения тангенса. Исключить ввод символов вместо цифр и получение значения тангенса угла 90 градусов. Предусмотреть возможность ввода значений в
радианах.
Создать программу, вычисляющую логарифм числа. Для этого
необходимо поместить в форму два компонента TEdit для ввода
значения и результата и кнопку TButton для вычисления значения
логарифма. Исключить ввод символов вместо цифр и получение
значения логарифма 0.
Создать программу обработки исключения при обращении к несуществующему элементу массива. В форму поместите поля редактирования для ввода – вывода значений и номеров элементов массива и кнопку для обработки события.
Разработать приложение для обработки результатов соревнований.
Исходные данные: время старта, время финиша, контрольное время. Отметить те результаты, которые укладываются в контрольное
время. Время старта и время финиша вводить в таблицу. Отметить
спортсменов, уложившихся в контрольное время, специальным
символом или сообщением «Норма выполнена» в свободном
столбце таблицы. Использование механизма защищенного блока
обязательно!
С помощью таблицы TStringGrid ввести элементы матрицы и подсчитать сумму квадратов его столбцов. Использование механизма
защищенного блока обязательно!
32
Окончание таблицы
1
9
10
11
2
Рассчитать средние параметры группы студентов. Исходные данные: количество баллов, набранных каждым студентом при тестировании; рост и вес каждого студента. Рассчитать средний балл,
средний вес и средний рост студентов в группе. В приложении использовать таблицу TStringGrid для ввода и вывода информации.
Использование механизма защищенного блока обязательно!
Представить в виде таблицы итоги деятельности четырех агентов
фирмы по сбыту n-ой продукции. Исходной информацией считать
объем продаж по кварталам. Рассчитать объем продаж каждого
агента за год. Использование механизма защищенного блока обязательно!
Представить в виде таблицы ведомость сведений о пропусках занятий студентами. Исходной информацией является: количество часов, пропущенных по уважительной и неуважительной причине.
Для ввода и хранения информации использовать таблицу TStringGrid. Студентов, пропустивших более XXX часов по неуважительной причине, отметить в свободном столбце таблицы специальным
сообщением. XXX – вводимая величина. Использование механизма
защищенного блока обязательно!
Содержание отчета
1. Номер, тема, цель лабораторной работы.
2. Задание к работе.
3. Описание входных, промежуточных и результирующих данных
с указанием их типа.
4. Математическая модель задачи.
5. Схема алгоритма решения задачи по ГОСТу.
6. Программа на языке программирования.
7. Результат выполнения программы.
Вывод о проделанной работе.
33
Лабораторная работа № 6
РЕАЛИЗАЦИЯ МЕХАНИЗМА DRAG & DROP.
Цель: приобретение практических навыков разработки приложений с использованием механизма перетаскивания данных Drag & Drop.
ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
Перетаскивание информации с помощью мыши стало стандартом
для программ, работающих в Windows. Часто это бывает удобно и позволяет добиться более быстрой работы. Здесь приводится большое количество примеров использования данной технологии при разработке
приложений в среде Delphi. Конечно, результат может быть достигнут
различными путями, продемонстрированные приемы не являются
единственными и, возможно, не всегда самые оптимальные, но вполне
работоспособны, и указывают направление поиска. Надеюсь, что они
побудят начинающих программистов к более широкому использованию
Drag & Drop в своих программах, тем более что пользователи, особенно
неопытные, быстро привыкают к перетаскивание и часто его применяют.
Проще всего делать Drag из тех компонентов, для которых однозначно ясно, что именно перетаскивать. Для этого устанавливаем у источника DragMode = dmAutomatic, а у приемника пишем обработчики
событий OnDragOver – разрешение на прием, и OnDragDrop – действия,
производимые при окончании перетаскивания.
procedure TForm1.StringGrid2DragOver(Sender, Source: TObject; X,
Y: Integer; State: TDragState; var Accept: Boolean);
begin
Accept := Source = Edit1;
// разрешено перетаскивание только из Edit1,
// при работе программы меняется курсор
end;
procedure TForm1.StringGrid2DragDrop(Sender, Source: TObject; X,
Y: Integer);
var
ACol, ARow: Integer;
begin
34
StringGrid2.MouseToCell(X, Y, ACol, ARow);
// находим, над какой ячейкой произвели Drop
StringGrid2.Cells[Acol, Arow] := Edit1.Text;
// записываем в нее содержимое Edit1
end;
Теперь рассмотрим копирование в упорядоченный список
ListBox1 из другого списка. В OnDragOver проверяем, выбран ли хоть
один элемент в источнике:
Accept := (Source = ListBox2) and (ListBox2.ItemIndex >= 0);
В OnDragDrop ищем отмеченные в источнике строки (установлен
множественный выбор) и добавляем только те, которых еще нет в приемнике:
for i := 0 to ListBox2.Items.Count – 1 do
if (ListBox2.Selected[i]) and
(ListBox1.Items.IndexOf(ListBox2.Items[i]) < 0) then
ListBox1.Items.Add(ListBox2.Items[i]);
Для ListBox2 реализуем перенос строк из ListBox1 и перестановку
элементов в желаемом порядке. В OnDragOver разрешаем Drag из любого ListBox:
Accept := (Source is TListBox) and ((Source as TListBox).ItemIndex
>= 0);
А OnDragDrop будет выглядеть так:
var
s: string;
begin
if Source = ListBox1 then
begin
ListBox2.Items.Add(ListBox1.Items[ListBox1.ItemIndex]);
ListBox1.Items.Delete(ListBox1.ItemIndex);
//удаляем перенесенный элемент
end
else //внутренняя перестановка
begin
s := ListBox2.Items[ListBox2.ItemIndex];
ListBox2.Items.Delete(ListBox2.ItemIndex);
ListBox2.Items.Insert(ListBox2.ItemAtPos(Point(X, Y), False), s);
35
//находим, в какую позицию переносить и вставляем
end;
end;
Научимся переносить текст в Memo, вставляя его в нужное место.
Поскольку в качестве источника выбран любой из ListBox, подключим
в Инспекторе Объектов для OnDragOver уже написанный ранее обработчик ListBox2DragOver, а в OnDragDrop напишем
if not CheckBox1.Checked then // при включении добавляется в конец текста
begin
Memo1.SelStart := LoWord(Memo1.Perform(EM_CHARFROMPOS,
0, MakeLParam(X, Y)));
// устанавливаем позицию вставки согласно координатам мыши
Memo1.SelText
:=
TListBox(Source).Items[TListBox(Source).ItemIndex];
end
else
memo1.lines.add(TListBox(Source).Items[TListBox(Source).ItemInde
x]);
Заметим, что для RichEdit EM_CHARFROMPOS работает несколько иначе, что продемонстрировано в следующем примере. Перенос из Memo реализован с помощью правой кнопки мыши, для того,
чтобы не изменять стандартное поведение Memo, и поскольку нажатие
левой кнопки снимает выделение. Для Memo1 установлено DragMode =
dmManual, а перетаскивание инициируется в OnMouseDown
if (Button = mbRight) and (Memo1.SelLength > 0) then
Memo1.BeginDrag(True);
Обработчик RichEdit1DragOver очевиден, а в RichEdit1DragDrop
пишем
var
p: tpoint;
begin
if not CheckBox1.Checked then
36
begin
p := point(x, y);
RichEdit1.SelStart := RichEdit1.Perform(EM_CHARFROMPOS, 0,
Integer(@P));
RichEdit1.SelText := Memo1.SelText;
end
else
RichEdit1.Lines.Add(Memo1.SelText);
end;
Рассмотрим теперь перетаскивание в ListView1 (ViewStyle =
vsReport). В OnDragOver разрешим прием из ListBox2 и из себя же:
Accept := ((Source = ListBox2) and (ListBox2.ItemIndex >= 0)) or
(Source = Sender);
А вот OnDragDrop теперь будет посложнее
var
Item, CurItem: TListItem;
begin
if Source = ListBox2 then
begin
Item := ListView1.DropTarget;
if Item <> nil then
// случай перетаскивания на Caption
if Item.SubItems.Count = 0 then
Item.SubItems.Add(ListBox2.Items[ListBox2.ItemIndex])
// добавляем SubItem, если их еще нет
else
Item.SubItems[0] := ListBox2.Items[ListBox2.ItemIndex]
// иначе заменяем имеющийся SubItem
else
begin
// при перетаскивании на пустое место создаем новый элемент
Item := ListView1.Items.Add;
Item.Caption := ListBox2.Items[ListBox2.ItemIndex];
end;
end
37
else // случай внутренней перестановки
begin
CurItem := ListView1.Selected;
// запомним выбранный элемент
Item := ListView1.GetItemAt(x, y);
// другой метод определения элемента на который делаем Drop
if Item <> nil then
Item := ListView1.Items.Insert(Item.Index)
// вставляем новый элемент перед найденным
else
Item := ListView1.Items.Add;
// или добавляем новый элемент в конец
Item.Assign(CurItem);
// копируем исходный в новый
CurItem.Free;
// уничтожаем исходный
end;
end;
Для ListView2 установим ViewStyle = vsSmallIcon и покажем, как
вручную расставлять значки. В OnDragOver зададим условие
Accept := (Sender = Source) and ([htOnLabel, htOnItem, htOnIcon] *
ListView2.GetHitTestInfoAt(x, y) = []);
// пересечение множеств должно быть пустым – запрещаем
накладывать элементы,
а код в OnDragDrop очень простой:
ListView2.Selected.SetPosition(Point(X, Y));
Перетаскивание в TreeView – довольно любопытная тема, здесь
порой приходится разрабатывать алгоритмы обхода ветвей для достижения желаемого поведения. Для TreeView1 разрешим перестановку
своих узлов в другое положение. В OnDragOver проверим, не происходит ли перетаскивание узла на свой же дочерний во избежание бесконечной рекурсии:
var
Node, SelNode: TTreeNode;
38
begin
Node := TreeView1.GetNodeAt(x, y);
// находим узел-приемник
Accept := (Sender = Source) and (Node <> nil);
if not Accept then
Exit;
SelNode := Treeview1.Selected;
while (Node.Parent <> nil) and (Node <> SelNode) do
begin
Node := Node.Parent;
if Node = SelNode then
Accept := False;
end;
Код OnDragDrop выглядит так:
var
Node, SelNode: TTreeNode;
begin
Node := TreeView1.GetNodeAt(X, Y);
if Node = nil then
Exit;
SelNode := TreeView1.Selected;
SelNode.MoveTo(Node, naAddChild);
// все уже встроено в TreeView
end;
Теперь разрешим перенос в TreeView2 из TreeView1
Accept := (Source = TreeView1) and (TreeView2.GetNodeAt(x, y)
<> nil);
И в OnDragDrop копируем выбранную в TreeView1 ветвь со всеми
подветвями, для чего придется сделать рекурсивный обход:
var
Node: TTreeNode;
procedure CopyNode(FromNode, ToNode: TTreeNode);
var
TempNode: TTreeNode;
i: integer;
39
begin
TempNode := TreeView2.Items.AddChild(ToNode, '');
TempNode.Assign(FromNode);
for i := 0 to FromNode.Count – 1 do
CopyNode(FromNode.Item[i], TempNode);
end;
begin
Node := TreeView2.GetNodeAt(X, Y);
if Node = nil then
Exit;
CopyNode(TreeView1.Selected, Node);
end;
Рассмотрим теперь перенос ячеек в StringGrid1. Поскольку, как и в
случае с Memo, простое нажатие левой кнопки занято под другие действия, установим DragMode = dmManual и будем запускать Drag при
нажатии левой кнопки, удерживая клавиши Alt или Ctrl. Запишем в
OnMouseDown:
var
Acol, ARow: Integer;
begin
with StringGrid1 do
if (ssAlt in Shift) or (ssCtrl in Shift) then
begin
MouseToCell(X, Y, Acol, Arow);
if (Acol >= FixedCols) and (Arow >= FixedRows) then
// не будем перетаскивать из фиксированных ячеек
begin
if ssAlt in Shift then
Tag := 1
else if ssCtrl in Shift then
Tag := 2;
// запомним что нажато – Alt или Ctrl – в Tag StringGrid1
BeginDrag(True)
end
else
Tag := 0;
end;
40
end;
Код OnDragOver учитывает также возможность перетаскивания из
StringGrid2 (описание ниже)
var
Acol, ARow: Integer;
begin
with StringGrid1 do
begin
MouseToCell(X, Y, Acol, Arow);
Accept := (Acol >= FixedCols) and (Arow >= FixedRows)
and (((Source = StringGrid1) and (Tag > 0))
or (Source = StringGrid2));
end;
Часть OnDragDrop, относящаяся к внутреннему переносу:
var
ACol, ARow, c, r: Integer;
GR: TGridRect;
begin
StringGrid1.MouseToCell(X, Y, ACol, ARow);
if Source = StringGrid1 then
with StringGrid1 do
begin
Cells[Acol, Arow] := Cells[Col, Row];
//копируем ячейку-источник в приемник
if Tag = 1 then
Cells[Col, Row] := '';
// очищаем источник, если было нажато Alt
Tag := 0;
end;
А вот из StringGrid2 сделаем перенос выбранного диапазона ячеек
с помощью правой кнопки, для этого в OnMouseDown:
if Button = mbRight then StringGrid2.BeginDrag(True);
И теперь часть StringGrid1DragDrop, относящаяся к переносу из
StringGrid2:
41
if Source = StringGrid2 then
begin
GR := StringGrid2.Selection;
// Selection – выделенные в StringGrid2 ячейки
for r := 0 to GR.Bottom – GR.Top do
for c := 0 to GR.Right – GR.Left do
if (ACol + c < StringGrid1.ColCount) and
(ARow + r < StringGrid1.RowCount) then
// проверка выхода за границы StringGrid1
StringGrid1.Cells[ACol + c, ARow + r] :=
StringGrid2.Cells[c + GR.Left, r + GR.Top];
end;
Теперь покажем, как этот диапазон ячеек из StringGrid2 перенести
в Memo2. Для этого в OnDragOver Memo2 пишем:
Accept := (Source = StringGrid2) or (Source = DBGrid1);
и в OnDragDrop Memo2:
var
c, r: integer;
s: string;
begin
Memo2.Clear;
if Source = StringGrid2 then
with StringGrid2 do
for r := Selection.Top to Selection.Bottom do
begin
s := '';
for c := Selection.Left to Selection.Right do
s := s + Cells[c, r] + #9;
// разделим ячейки табуляцией
memo2.lines.add(s);
end
Кроме того, в Memo2 можно переносить выбранную запись из
DBGrid1, у которого установлено в Options dgRowSelect = True. В сетке
отображается таблица из стандартной поставки Delphi DBDEMOS –
Animals.dbf. Перетаскивание осуществляется аналогично StringGrid2,
правой кнопкой мыши, только по событию OnMouseMove
42
if ssRight in Shift then
DBGrid1.BeginDrag(true);
Код в Memo2DragDrop, относящийся к переносу из DBGrid1:
else
with DBGrid1.DataSource.DataSet do
begin
s := '';
for c := 0 to FieldCount – 1 do
s := s + Fields[c].AsString + ' | ';
memo2.lines.add(s);
end;
// в случае dgRowSelect = False для переноса одного поля достаточно сделать
// memo2.lines.add(DbGrid1.SelectedField.AsString);
Drag из DBGrid1 принимается также на Panel3, условие приема
очевидно, а OnDragDrop выглядит так:
Panel3.Height := 300; // раскрываем панель
Image1.visible := True;
OleContainer1.Visible := false;
Image1.Picture.Assign(DBGrid1.DataSource.DataSet.FieldByName('BM
P'));
// показываем графическое поле текущей записи таблицы
Теперь покажем, как можно передвигать мышью визуальные компоненты в Run-Time. Для Panel1 установим DragMode = dmAutomatic, в
OnDragOver формы пишем:
var
Ct: TControl;
begin
Ct := ControlAtPos(Point(X + Panel1.Width, Y + Panel1.Height),
True, True);
// для упрощения проверяем перекрытие с другими контролами
только правого нижнего угла
Accept := (Source = Panel1) and ((Ct = nil) or (Ct = Panel1));
43
и в OnDragDrop формы очень просто
Panel1.Left := X;
Panel1.Top := Y;
Другой метод перетаскивания можно встретить в каждом FAQ по
Delphi:
procedure TForm1.Panel2MouseDown(Sender: TObject;
TMouseButton;
Shift: TShiftState; X, Y: Integer);
const
SC_DragMove = $F012;
begin
ReleaseCapture;
Panel2.Perform(WM_SysCommand, SC_DragMove, 0);
end;
Button:
И в завершение реализация популярной задачи перетаскивания
значков файлов на форму из Проводника. Для этого следует описать
обработчик сообщения WM_DROPFILES
private
procedure WMDropFiles(var Msg: TWMDropFiles); message
WM_DROPFILES;
В OnCreate формы разрешить прием файлов
DragAcceptFiles(Handle, true);
и в OnDestroy отключить его
DragAcceptFiles(Handle, False);
Процедура обработки приема файлов может выглядеть так:
procedure TForm1.WMDropFiles(var Msg: TWMDropFiles);
const
maxlen = 254;
var
h: THandle;
//i,num:integer;
pchr: array[0..maxlen] of char;
fname: string;
begin
h := Msg.Drop;
// дана реализация для одного файла, а
44
//если предполагается принимать группу файлов, то можно добавить:
//num:=DragQueryFile(h,Dword(-1),nil,0);
//for i:=0 to num-1 do begin
// DragQueryFile(h,i,pchr,maxlen);
//...обработка каждого
//end;
DragQueryFile(h, 0, pchr, maxlen);
fname := string(pchr);
if lowercase(extractfileext(fname)) = '.bmp' then
begin
Image1.visible := True;
OleContainer1.Visible := false;
image1.Picture.LoadFromFile(fname);
Panel3.Height := 300;
end
else if lowercase(extractfileext(fname)) = '.doc' then
begin
Image1.visible := False;
OleContainer1.Visible := True;
OleContainer1.CreateObjectFromFile(fname, false);
Panel3.Height := 300;
end
else if lowercase(extractfileext(fname)) = '.htm' then
ShellExecute(0, nil, pchr, nil, nil, 0)
else if lowercase(extractfileext(fname)) = '.txt' then
Memo2.Lines.LoadFromFile(fname)
else
Memo2.Lines.Add(fname);
DragFinish(h);
end;
При перетаскивании на форму файла с расширением Bmp он отображается в Image1, находящемся на Panel3, Doc загружается в
OleContainer, для Htm запускается Internet Explorer или другой браузер
по умолчанию, Txt отображается в Memo2, а для остальных файлов в
Memo2 будет просто показано имя.
Полагаю, на основе содержащихся в статье приемов будет нетрудно организовать перетаскивание и для других, не описанных здесь, визуальных компонентов.
45
ЗАДАНИЕ К РАБОТЕ
1. Разработать интерфейс приложения с применением компонентов TChar, TImage, TShape.
2. Разработать алгоритм решения задачи в соответствии с вариантом задания.
3. Реализовать разработанный алгоритм в рамках ранее созданного интерфейса.
4. Проверить работоспособность с помощью тестового набора
данных.
5. Оформить отчет и сдать работу преподавателю.
Задания
Вариант
1, 6, 11
2, 7, 12
3, 8, 13
4, 9, 14
5, 10
Задание
Реализовать перенос и копирование выделенных фрагментов и всего
текста между тремя компонентами TMemo. Текст вставлять в позицию, в которой находится курсор в момент окончания переноса. Перенос текста я сделал а вот вставлять текст в позицию, в которой находится курсор в момент окончания переноса не получается.
Реализовать конвертер валют. Предусмотреть список различных валют. Курсы валют задавать относительно рубля при помощи таблиц.
Перевод любых валют осуществлять через рубли. Нужные валюты выбирать из списка на форме путем перетаскивания их мышкой в поля
ввода TEdit. Сохранять результаты конвертирования в TMemo
Реализовать перенос и копирование данных между списками. Первый
список разрешает перенос только одного элемента, второй список –
группу выбранных элементов. Новые элементы в любой из списков
добавлять через перенос текста из компонента Edit.
Требуется реализовать следующую программу: на форме расположены
4 метки, каждая из которых окрашена некоторым цветом. При переносе данных с указанных меток на компонент Shape, он окрашивается
указанным цветом.
На форме размещены: окно редактирования Memo1, четыре списка
ListBox1, ListBox2, ListBox3 и ListBox4, индикатор CheckBox1. Разрешается перетаскивание выделенной строки из любого списка в другой список или в окно Memo1. При перенесении строки из списка в
список строка перемещается, т. е. вычеркивается из списка-источника
(исключением является ListBox2, из которого строка не вычеркивается). При перемещении строки в Memo1 строка копируется, т. е. остается и в исходном списке.
Можно перетаскивать также тексты всех меток в окно Memo1.
Если индикатор сообщений CheckBox1 внизу формы установлен, то
результаты каждого успешного или неуспешного перетаскивания выдаются в виде сообщения, получающегося как реакция на событие
OnEndDrag.
46
Содержание отчета
1. Номер, тема, цель лабораторной работы.
2. Задание к работе.
3. Описание входных, промежуточных и результирующих данных
с указанием их типа.
4. Математическая модель задачи.
5. Схема алгоритма решения задачи по ГОСТу.
6. Программа на языке программирования.
7. Результат выполнения программы.
Вывод о проделанной работе.
47
Лабораторная работа № 7
ИСПОЛЬЗОВАНИЕ ГРАФИЧЕСКИХ ВОЗМОЖНОСТЕЙ
Цель:
1) Изучение основных графических компонент, их свойств и методов;
2) Приобретение практических навыков разработки приложения,
поддерживающих создание графических изображений;
3) Приобретение практических навыков разработки приложений с
использованием компонентов TChart, TImage, TShape.
ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
Часть 1. Разработка приложений,
поддерживающих создание графических изображений
Любая Windows-программа осуществляет вывод информации на
экран с помощью GDI (Graphic Device Interface). Функции, реализованные в GDI, являются аппаратно независимыми. Эти функции взаимодействуют с конкретным устройством не напрямую, а через специальную программу, которая называется драйвером устройства. Для любых устройств (мониторов, принтеров, плоттеров и т. д.) используется
соответствующий драйвер.
Функции GDI взаимодействуют с драйвером устройства через
специальную структуру, называемую контекстом устройства (Device
Context). В качестве контекста в Delphi выступает объект Canvas.
В Delphi имеется несколько независимых классов, которые определяют средства создания изображений. К ним можно отнести TCanvas
– холст, TPen – перо, TBrush – кисть, TFont – шрифт. Данные классы
Delphi иногда называют классами-надстройками, так как связанные с
ними объекты самостоятельно в программе не используются, а выступают как свойства того или иного элемента управления (Form, Edit, ...).
Рассмотрим основные свойства этих классов.
Класс TPen
С помощью этого класса производится рисование линий и контуров различных геометрических фигур. Перо характеризуется цветом,
стилем и толщиной. Основные свойства класса:
48
Color: TColor – для задания конкретного цвета. Цвет в Windows задается в формате RGB, т. е. тройкой чисел, определяющих степени интенсивности трех его цветовых составляющих – красной, зеленой и синей.
Для задания конкретного цвета используется тип TColor, описанный в
Unit Graphics как: Type TColor = -$7FFFFFFF..$7FFFFFFF, т. е. для задания конкретного цвета выделяется целое число в 4 байта. Самый
крайний байт определяет интенсивность красной составляющей. В
шеснадцатиричной системе счисления соответствующие составляющие
изменяются в диапазонах:
$00 00 00 00 – $00 00 00 FF – красная составляющая,
$00 00 00 00 – $00 00 FF 00 – зеленая составляющая,
$00 00 00 00 – $00 FF 00 00 – синяя составляющая.
Левый байт задает палитру.
Для наиболее часто используемых цветов определены соответствующие константы. Они разбиваются на 2 группы:
1. Цвета, безотносительно к какому элементу они применяются,
например: clBlack .. clWhite, clNone.
2. Цвета, предназначенные для окрашивания каких-либо деталей
изображения: полос скроллинга, фона рабочего окна Windows, фона
меню и т. д. Это такие цвета как: clWindows, clMenu и т. д.
Цвета второй группы могут меняться в зависимости от настроек
Windows.
Замечания. Получить составной цвет можно также смешав три составляющие при вызове функции RGB:
Color:= RGB(255, 0, 0); //ярко-красный цвет.
Если требуется выделить из смешанного цвета одну из его составляющих, то это можно сделать функциями GetRValue, GetGValue, GetBValue, например:
RedValue:=
GetRValue(Color).
Style : TPenStyle – задает тип линии
путем использования констант:
Width: Integer – задает толщину линий.
49
Класс TBrush
С помощью этого класса задаются характеристики кисти. Основные свойства, определенные в классе
Color: TColor – задает цвет кисти. По умолчанию clWhite.
Style: TBrushStyle – определяет стиль кисти. Для задания стиля используются константы:
bsSolid bsClear bsBDiagonal bsFDiagonal bsCross bsDiagCross
bsHorizontal bsVertical
Класс TFont
С помощью этого класса задаются характеристики текста с помощью свойств:
Color: TColor – - задает цвет шрифта. По умолчанию clBlack.
Name: TFontName – задает название шрифта, например: 'Arial'.
Size: Integer – задает размер букв.
Style: TFontStyle – задает стиль букв. Для задания стиля используются константы: [fsBold], [fsItalic] [fsUnderline], [fsStrikeOut].
Способы отображения графики
Delphi предоставляет программисту 4 способа отображения графики:
• использование заранее созданных графических изображений;
• создание изображений с помощью графических компонентов;
• создание изображений с помощью примитивов (линия, круг и
т. д.) непосредственно во время работы программы;
• представление информации в виде графиков.
1-й способ. Компонента TImage
Если графическое изображение уже создано, например, с помощью графического редактора (например, Paint), то его можно показать с
помощью компоненты TImage. В Delphi с помощью этого компонента
можно отобразить следующие графические изображения:
1) растровое (*.bmp);
2) пиктограммы (*.ico);
3) типа метафайла (*.wmf);
50
4) курсора (*.cur).
Вместе с тем известны и другие способы хранения изображений
(*.pcx, *.gif, *.tiff, *.jpeg, *.dwg). Для того, чтобы включить изображения других форматов, их нужно перевести в формат *.bmp.
Основные свойства компонента TImage:
Canvas – содержит канву для прорисовки изображения;
Center – указывает, надо ли центрировать изображение в границах
компонента. Игнорируется, если: AutoSize := True; или Stretch := True; и
изображение не является пиктограммой (ICO);
Increment – разрешает/запрещает показ большого изображения по
мере его загрузки;
Picture – центральное свойство класса. Служит контейнером
изображения TPicture;
Proportional – разрешает/запрещает пропорционально уменьшать
высоту и ширину изображения, если оно не может целиком уместиться
в рабочей зоне компонента;
Stretch – разрешает/запрещает изменять размер изображения так,
чтобы оно целиком заполнило клиентскую область компонента;
Transparent – запрещает/разрешает накладывать собственный
фон изображения на фон компонента.
Компонент TImage позволяет поместить графическое изображение
в любое место на форме. Собственно картинку можно загрузить во время дизайна в редакторе свойства Picture (Инспектор Объектов). Картинка должна храниться в файле в формате BMP (bitmap), WMF (Windows Meta File) или ICO (icon). При проектировании следует помнить,
что изображение, помещенное на форму во время дизайна, включается
в файл .DPR и затем прикомпилируется к EXE-файлу. Поэтому такой
EXE-файл может получиться достаточно большой. Как альтернативу
можно рассмотреть загрузку картинки во время выполнения программы, для этого у свойства Picture (которое является объектом со своим
набором свойств и методов) есть специальный метод LoadFromFile.
Пример. По нажатию кнопки необходимо загрузить в компоненту
TImage изображение.
Обработчик нажатия кнопки Button1Click выглядит следующим
образом:
procedure TForm1.Button1Click(Sender: TObject); begin
if OpenPictureDialog1.Execute then begin
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
51
Image1.Stretch := True;
end; end;
Если изображение, находящееся в TImage, нужно сохранить в
файле, можно применить метод SaveToFile, который также принадлежит свойству Picture.
2-й способ. Компоненты TShape, TBevel
С помощью этого способа имеется возможность рисовать простейшие геометрические фигуры (прямоугольник, квадрат, скругленный прямоугольник, скругленный квадрат, эллипс, окружность). Фигура полностью занимает пространство компонента. Если задан квадрат
или круг, а размеры элемента по горизонтали и вертикали отличаются,
фигура чертится с размером меньшего измерения. Для создания таких
фигур используется компонента TShape, расположенная на закладке
Additional под пиктограммой
.
Могут быть использованы следующие свойства компонента:
Shape: TShapeType = (stRectangle, stSquare, stRoundRect, stRoundSquare, stEllipse, stCircle) – тип геометрической фигуры, где stRectangle
– прямоугольник, stSquare – квадрат, stRoundRect – скругленный прямоугольник, stRoundSquare – скругленный квадрат, stEllipse – эллипс,
stCircle – окружность.
Выбранная фигура рисуется на весь экран компонента TShape.
Изменение свойства Shape приводит к немедленной перерисовке изображения;
Brush: TBrush – используется для заливки области;
Pen: TPen – используются для изменения параметров рамки.
Пример:
Procedure TForm1.FormCreate( ); begin
with Shape1 do
begin
Shape := stRectangle; //Фигура – прямоугольник Brush.Color :=
clRed; //Красный цвет заливки Pen.Color := Blue;
//Синий цвет
рамки
Brush.Style := bsHorizontal; //Дискретная заливка в виде горизонтальных линий
Pen.Style := psSolid; //Сплошной тип линии рамки
52
Pen.Width := 2; //Толщина линии рамки
end; end;
Bitmap: TBitmap – позволяет в качестве закраски или заливки использовать растровое изображение, например: Shape1.Brush.Bitmap:
= Image1.Picture.Bitmap;.
Компонент TBevel
Этот компонент
используется для выделения группы элементов или отделения их друг от друга. Компонент TBevel служит для
украшения программ и может принимать вид рамки или линии. Объект
предоставляет меньше возможностей по сравнению с TPanel, но не занимает ресурсов. Компонент класса TBevel используют для оформительского дизайна, выделяя ГРУППУ элементов или отделяя их друг от
друга.
Изменение внешнего вида компонента осуществляется с помощью
свойств:
Shape: TBevelShape = (bsBox, bsFrame, bsTopLine, bsBottomLine,
bsLeftLine, bsRightLine) – геометрия компонента;
Style: TBevelStyle = (bsLowered, bsRaised) – вид (вдавленный, выпуклый) компонента.
3-й способ. Поддержка графических операций низкого уровня
Для создания графических изображений в области некоторых
компонент (TForm, TImage, TPaintBox, TPrinter, TListBox, TComboBox,
TDrawGrid), используется свойство Canvas. С каждым из перечисленных компонент связано событие OnPaint. Это событие возникает, когда
ядру Windows необходимо перерисовать содержимое компонента
(например, при активизации формы, когда один из перечисленных компонентов становится видимым). Чтобы отрисовать графическое изображение внутри рабочей области перечисленных компонент нужно обработать событие OnPaint, т. е. записать соответствующий обработчик.
Можно воспроизвести на соответствующих компонентах любые
графические объекты без использования компонент TImage, TShape,
TLabel.
53
Класс TCanvas
Класс TCanvas имеет свойства:
Pen: TPen – устанавливает цвет, толщину, стиль линий и границ
геометрических фигур, например:
with Canvas do
begin
Pen.Color := clBlue;
Pen.Width := 2;
Pen.Style := psDash; end;
Brush: TBrush – это свойство позволяет устанавливать цвет и
шаблон кисти;
Font: TFont – это свойство позволяет устанавливать параметры
текста;
PenPos: TPoint – выдает текущую позицию пера;
Pixels : TColor – двухмерный массив, содержащий цвета пикселей,
например:
Procedure TForm1.Button1Click( );
Var
i, j : LongInt; begin
Button1.Visible := false; with Canvas do begin for i:=1 to Width do for
j:=1 to Height do Pixels[i,j] := Button1.Visible := true; end; end;
Методы класса TCanvas
Большое количество методов класса TCanvas позволяют отображать различные геометрические фигуры с помощью свойства Pen. Если
фигура замкнута, то ее поверхность закрашивается Brush. Все тексты
изображаются шрифтом Font.
В процессе работы программы эти характеристики можно изменять. Так:
Arc(x1, y1, x2, y2, x3, y3, x4, y4) – рисует дугу;
Chord(x1, y1, x2, y2, x3, y3, x4, y4) – рисует сегмент из дуги эллипса и хорды
Ellipse(x1, y1, x2, y2) – рисует эллипс;
54
FillRect(Rect) – закрашивание прямоугольника;
MoveTo (x, y) – перемещает перо в точку с координатами x, y;
LineTo(x, y) – рисует линию из текущего положения пера в точку
с координатами x и y;
Pie(x1, y1, x2, y2, x3, y3, x4, y4) – рисует сектор эллипса;
Poligon(Point: array of TPoint) – вычерчивание заданного многоугольника.
Пример.
var
P: array[1..3] of TPoint; begin
P[1].x := 10; P[1].y := 300; P[2].x := 200; p[2].y := 300;
P[3].x := 100; P[3].y := 20;
Canvas.Poligon(P); end;
Poliline(Point: array of TPoint) – рисует ломаную;
RoundRect(x1, y1, x2, y2, x3, y3) – вычерчивание и заполнение
прямоугольника со скругленными углами;
TextOut(x, y, S: String) – осуществляет вывод строки;
Метод TextRec выводит текст только внутри указанного прямоугольника. Длину и высоту текста можно узнать с помощью функций
TextWidth и TextHeight;
Draw(x, y, Graphic: TGraphic) – прорисовка графического объекта
Graphic так, чтобы левый верхний угол располагался в (x, y). Объект
Graphic может быть типа Bitmap, Icon и Metafile;
StretchDraw(Rect: TRect; Graphic: TGraphic) – вычерчивание и
масштабирование объекта Graphic до полного заполнения Rect.
Пример. На форме имеется Image1. С помощью свойства Picture в
нее помещена картинка. Требуется переместить эту картинку в другое
положение.
Procedure TForm1.FormPaint( ); begin
with Canvas do
begin
Draw (0, 0, Image1.Picture.Bitmap);
StretchDraw (Rect(250,0,350,50), Image1.Picture.Bitmap);
end; end;
55
Как правило, все графические операции осуществляются не на
форме, а посредством специальных графических компонент, например
компонента Image, который позволяет разместить на экране растровое
изображение, пиктограмму, метафайл, либо собственное изображение.
Для более простых графических операций используется компонент TPaintBox.
Часть 2. Построение диаграмм и графиков
с использование компонента TChart
Для работы с диаграммами и графика предназначен компонент
Chart. Работа с данным компонентом осуществляется с помощью редактора Editing Chart. Редактор имеет 5 основных вкладок:
 Chart – предоставляет доступ к массиву диаграмм и позволяет
настраивать внешний вид панели для их отображения;
 Series – применяется для настройки свойств диаграммы;
 Data – отображает таблицу данных для построения диаграммы;
 Export – позволяет экспортировать график в графический файл
формата WMF или BMP;
 Print – служит для вывода диаграммы на принтер.
Самым главным свойством компонента Chart является свойство
Series[Index] – массив диаграмм, выводимых в области компонента
Chart. Это свойство в свою очередь является объектом и обладает набором собственных свойств и методов.
Основные методы объекта Series:
 Add – добавляет к диаграмме значение;
 Delete – удаляет значение диаграммы;
 Clear – выполняет удаление всех значений диаграммы.
ЗАДАНИЯ К РАБОТЕ
Задание 1
1) Разработать приложение, поддерживающее основные функции
простейшего графического редактора:
 Разработать приложение, содержащее три формы – три способа
представления графической информации;
 На 1-й форме продемонстрировать отображение графических
картинок, созданных в других графических редакторах;
56
 На 2-й форме с помощью кнопочного меню рисовать различные
графические фигуры посредством компоненты класса TShape;
 На 3-й форме реализовать рисование простейшими примитивами, типа линия, прямоугольник, эллипс и т. д.
2) Разработать интерфейс приложения с применением компонентов TChar, TImage, TShape.
3) Разработать алгоритм решения задачи в соответствии с вариантом задания.
4) Реализовать разработанный алгоритм в рамках ранее созданного интерфейса.
5) Проверить работоспособность с помощью тестового набора
данных.
6) Оформить отчет и сдать работу преподавателю.
Задание 2
Вычислить n значений функции y=f(x) на отрезке [a,b] и построить
график функции. Вычисленные значения должны выводиться на форме
в компоненте TStringGrid. График построить с помощью компонента
TChart.
Вариант
1, 9
Задание
𝐹(𝑥) = 3𝑥 − cos(𝑥) − 1
2, 10
3, 11
𝐹(𝑥) = 3𝑥 + 2
𝐹(𝑥) = 2sin(𝑥) + 3
4, 12
5, 13
6, 14
𝐹(𝑥) = ln(3𝑥) + 5
𝐹(𝑥) = 3𝑥 3 + 2𝑥 − 6
𝐹(𝑥) = 5 − sin(𝑥) + 2𝑥
7
8
𝐹(𝑥) = |𝑥 3 + 3𝑥 − 4|
𝐹(𝑥) = 5 − 4𝑥 − 𝑥 2
Интервал
𝜋 𝜋
[− , ]
2 2
[−2,3]
𝜋
[− , 𝜋]
3
[3,10]
[−10,10]
𝜋
[−2𝜋, ]
2
[−6,3]
[−10,5]
Задание 3
Сгенерировать последовательность случайных чисел с заданным
законом распределения и построить диаграмму с помощью компонента
TChart. Выбор вида диаграммы (круговая или гистограмма) производить с помощью компонента TRadioButton. Сгенерированные значения
выводить в компоненте StringGrid.
57
Содержание отчета
1. Номер, тема, цель лабораторной работы.
2. Задание к работе.
3. Описание входных, промежуточных и результирующих данных
с указанием их типа.
4. Математическая модель задачи.
5. Схема алгоритма решения задачи по ГОСТу.
6. Программа на языке программирования.
7. Результат выполнения программы.
8. Вывод о проделанной работе.
58
Лабораторная работа № 8
ОСНОВЫ РАБОТЫ С БАЗАМИ ДАННЫХ
Цель: приобретение практических навыков создания программных приложений с использованием баз данных.
Часть 1. Подключение БД и работа с полями
Цель: подключение базы данных к программе по универсальному
механизму доступа ADO.. Работа с полями набора данных
ЗАДАНИЕ К РАБОТЕ
1.
2.
3.
4.
Разработать интерфейс.
Разработать алгоритм решения задачи.
Проверить работоспособность .
Оформить отчет и сдать работу.
Разработать базу данных для отдела кадров, содержащую следующую информацию о сотруднике: фамилия, имя, отчество, пол, семейное положение, количество детей, дата рождения, дата поступления,
стаж, образование (полное среднее, неполное среднее, высшее техническое и т. д.), военнообязанный, место жительства, телефон, отдел,
должность.
Ход работы
1. Создать в базе данных MS Access следующие таблицы
Таблица 1
LichData
Поле
Идентификатор
1
Идентифика- ID
ционный номер
Фамилия
Fam
Имя
Im
2
Тип
данных
3
числовой
Дополнительные
характеристики
4
Ключевое поле
текстовый
25 символов, индексированное
(совпадения допускаются)
25 символов, индексированное
(совпадения допускаются)
текстовый
59
Окончание таблицы 1
1
Отчество
Пол
Семейное положение
Дети
Дата рождения
Дата поступления
Стаж
Образование
Военнообязанный
2
Ot
Pol
Sem_p
3
текстовый
текстовый
логический
Deti
Dtr
числовой
дата/время
Dtp
дата/время
Stag
Obraz
VOb
числовой
текстовый
логический
4
25 символов.
3 символа, формат «муж/жен»
Формат «да/нет»
Байт
Краткая форма даты, маска
«00.00.0000»
Краткая форма даты, маска
«00.00.0000»
Байт
30 символов
Формат «Да/Нет»
Таблица 2
Telephones
Сотрудник
Телефон
Sotr
Tel
Тип
данных
числовой
текстовый
Примечание
Prim
текстовый
Поле
Идентификатор
Дополнительные
характеристики
Длинное целое. Не ключевое
17 символов, маска #(###)-###-####,
10 символов, формат «Рабочий/домашний/мобильный»
Таблица 3
Doljnost
Поле
Сотрудник
Отдел
Должность
Идентификатор
Sotr
Otdel
Doljn
Тип
данных
числовой
текстовый
текстовый
Дополнительные
характеристики
Длинное целое. Не ключевое
15 символов
20 символов
Таблица 4
Поле
Сотрудник
Страна
Город
Домашний
адрес
Идентификатор
Sotr
Strana
Gorod
Dom_adr
Address
Тип данных
числовой
текстовый
текстовый
текстовый
60
Дополнительные характеристики
Длинное целое. Не ключевое
15 символов
20 символов
100 символов
1. Создайте модуль данных( File-New-Data Module). Переименуйте его в DM.
2. В модуль данных добавьте c вкладки ADO: компонент ADOConnection и 4 компонента ADOTable; с вкладки Data Access: 4 компонента DataSource.
3. Подключение базы данных к программе
Размещаем на форме компонент со страницы ADO –
ADOConnection. Редактируем свойство ConnectionString:
В открывшемся окне нажимаем на кнопку «Build»
В открывшемся окне выбираем поставщика данных и нажимаем
кнопку «Далее».
61
Далее настраиваем соединение, выбрав пункт «Использовать строку
соединения», нажимаем на кнопку «Сборка»
В появившемся окне выбираем источник данных «MS Access Database» и нажимаем кнопку «OK»:
В открывшемся окне нажимаем на кнопку «База данных» для
подключения своей базы
.
62
4. Дополнительная настройка ADOConnection: установите False в
Login Prompt, чтобы приложение не запрашивало пароль при подключении БД. Далее установите True
в свойствах Connected и
KeepConnection.
5. Далее выделите 4 компонентаADOTable и в свойстве Connection выберете компонент ADOConnection1
6. Выберете компонент ADOTable1. Переименуйте его, указав в
свойстве Name TLichData. В свойстве TableName, выберете из списка
таблицу LichData.
7. Проделайте те же действия с 3 другими компонентами ADOTable.
8. Далее выберете компонент DataSource1. Переименуйте в
DSLichData и в свойстве DataSet выберете TLichData.
9. Выполните те же действия с 3 другими компонентами Data
Source.
10. Теперь между таблицами установим связь.
11. Выделите модуль данных. Щелкните дважды по первой таблице, чтобы открыть редактор полей. Правой кнопкой щелкните по
этому редактору и выберете команду Add all fields. В редакторе полей
появятся все поля таблицы. Редактор полей предназначен для настройки параметров каждого поля, для добавления новых полей или удаления имеющихся. В редакторе для каждого поля мы можем изменить
различные параметры.
12. В таблице LichData скроем поле ID, для этого выделим его, и в
свойстве Visible установим False. Теперь для пользователя это поле будет невидимым. Выберете поле Sem_p, в свойстве DisplayValues, присвойте значение «Женат; холост». Для поля VOb в этом же свойстве
укажите «Да;Нет». Для полей типа Дата в свойстве MaskEdit введите
маску «##.##.####».
13. Таким же образом добавьте поля в остальные 3 таблицы. У
них невидимым следует сделать поле «Sotr». Для поля «Tel» таблицы
Telephones следует изменить свойство EditMask. Открыв редактор маски введите маску, «#(###)-###-##-##» и сохраните ее.
14. Далее кнопкой F12 перейдите в редактор кода. Перейдите на
вкладку Diagram, расположенную в нижней части окна. Для начала в
окно диаграмм нужно добавить наши таблицы. Перетащите их в окно
диаграмм из Object TreeView. Таблицы вместе с полями должны отобразиться в окне. Установим связи. Для этого нажмите кнопку Master/Detail Connector, расположенную в верхней части окна. Подведите
указатель мыши к боковой границе главной таблицы, нажмите левую
63
кнопку и, удерживая ее, проведите линию к боковой границе другой
таблицы. Как только вы отпустите кнопку, появится окно связей. В поле Detail Fields выберете поле по которому осуществляется связь (поле
«Sotr»). В поле Master Fields выбираем ключевое поле (ID). Затем
нажимаем кнопку ADD и кнопку OK. Связь установлена. Установите
связи со всеми таблицами.
Содержание отчета
1. Номер, тема, цель лабораторной работы.
2. Задание к работе.
3. Вывод о проделанной работе.
Часть 2. Работа с таблицами. Навигация по набору данных
Цель: приобретение практических навыков работы с таблицами и
навигации по наборам данных.
Задание к работе
1. Создайте форму следующего вида.
2. Поместите три обычных панели. Свойству Align верхней панели присвойте значение alTop (весь верх). Затем свойству Align нижней
64
панели присвойте значение alBottom. Затем поместите компонент
Splitter с вкладки Additional панели инструментов, и его свойству Align
также присвойте alBottom, после чего он прижмется к нижней панели.
Splitter – это разделитель между панелями. С его помощью пользователь мышью сможет передвигать нижнюю панель, меняя ее размеры. И,
наконец, свойству Align средней панели присвойте значение alClient,
чтобы она заняла все оставшееся место на форме. Не забудьте очистить
свойство Caption всех трех панелей.
Далее на верхнюю панель поместите три компонента RadioButton
с вкладки Standard палитры компонентов. В их свойствах Caption
напишите, соответственно, "Адрес", "Телефоны" и "Должность". Переключаясь между ними, пользователь сможет выводить в нижнюю, подчиненную сетку DBGrid нужные данные. Свойству Checked первой радиокнопки присвойте значение True, чтобы включить ее. Раздел с переключателями разделите компонентом Bevel с вкладки Additional палитры компонентов. Его ширину (свойство Width) сделайте равным 2 пикселям, превратив его в вертикальную разделительную полосу.
Далее сделайте раздел поиска, поместив в него обычные Label,
Edit и кнопку BitBtn. Этот раздел понадобиться позже.
В последнем разделе верхней панели находятся еще две кнопки
BitBtn. Одна из них предназначена для редактирования текущей записи,
другая – для добавления новой.
Вторая и третья панели содержат только по одному компоненту
DBGrid из вкладки DataControls палитры компонентов, свойствам Align
которых присвоено значение alClient.
3. Подключите модуль данных нажатием File-Use Unit.
4. Во всех таблицах в свойстве Active установите True.
5. Выделите верхнюю сетку DBGrid, в ее свойстве DataSource выберите DM.DSLichData. В таком же свойстве нижней сетки выберите
DM.DSAdres. Сетки среагировали, и вы можете видеть названия полей.
Разумеется, таблица еще пуста, данных пока нет. Кстати, выделите обе
сетки и установите в True их свойства ReadOnly – только чтение. Таблицы ведь будут связаны, и нам не нужно, чтобы пользователь вводил
данные фрагментарно. Мы для этого сделаем отдельную форму, а эти
сетки нужны только для просмотра.
6. Теперь нужно сделать окно редактора данных. Создайте новую
форму (File -> New -> Form). Ее свойство. Командой File -> Use Unit
подключите к форме модуль данных DM. Теперь нам нужно установить
на форму такие компоненты:
65
Установите на форму четыре панели GroupBox с вкладки Standard,
на каждую таблицу свой GroupBox.
Для таблицы LichData: в свойстве Caption компонента GroupBox1
впишите "Личные данные", это название отразится в заголовке панели.
Далее на эту панель следует установить девять компонентов DBEdit с
вкладки DataControls палитры компонентов, два DBCheckBox для редактирования логических данных и один компонент DBComboBox для
списка. Поясняющие компоненты Label установите и настройте самостоятельно.
DBComboBox. Щелкните дважды по свойству Items компонента
DBComboBox, открыв редактор. В нем введите две строки:
муж
жен
Сохраните текст, нажав кнопку ОК. Теперь пользователь сможет
указать пол сотрудника, выбрав нужную строку из списка.
Для таблицы Doljnost: на панели GroupBox установите два компонента DBEdit и два поясняющих Label.
Для таблицы Address используйте три DBEdit.
66
А для таблицы Telephones понадобится один DBEdit, один
DBComboBox, сетка DBGrid и кнопка BitBtn. Сетка нужна для контроля
введенных телефонов, ведь здесь связь один-ко-многим, и телефонов
может быть несколько. В редакторе Items компонента DBComboBox
введите три строки:
Рабочий
Домашний
Мобильный
7. Теперь займемся подключением компонентов контроля. Удерживая <Shift>, выделите все компоненты контроля на первой панели
(все компоненты, кроме Label). В их свойстве DataSource выберите
DM.DSLichData, подключив компоненты к нужному набору данных
(таблице). Снимите общее выделение и выделите первый DBEdit. В его
свойстве DataField выберите поле "Фамилия". Это свойство подключает
выбранный компонент к определенному полю таблицы. Таким же образом подключите к соответствующим полям остальные компоненты. Затем подключайте компоненты других таблиц, каждое к своей таблице и
к соответствующему полю. Сетка DBGrid подключается к
DM.DSTelephones, она отображает все видимые поля таблицы.
8. В правой нижней части для удобства пользователя установите
навигационный компонент DBNavigator с вкладки Data Controls. В его
свойстве DataSource установите DM.DSLichData, чтобы подключить
компонент к главной таблице. В свойстве VisibleButtons переведите в
False все кнопки, кроме nbFirst, nbPrior, nbNext и nbLast. Нажатие на эти
кнопки приведет к вызову соответствующих методов компонента.
9. Для сохранения информации после ввода информации в первой
таблице при переходе к следующей необходимо прописать процедуру.
Для этого выделите первый GroupBox и дважды щелкните по событию
onExit на вкладке Events инспектора объектов. Это событие происходит
всякий раз, когда пользователь перейдет к другой панели GroupBox,
либо к кнопкам, расположенным в нижней части окна. В сгенерированной процедуре впишите код:
begin
if DM.TLichData.Modified then DM.TLichData.Post;
end;
10. Сгенерируйте событие onExit для оставшихся панелей
GroupBox и таким же образом сохраните изменения записей в соответствующих таблицах.
67
11. Далее сгенерируйте событие нажатия на кнопку "Добавить" в
GroupBox с телефонными данными. Этой кнопкой мы будем добавлять
новые записи в таблицу, ведь один сотрудник может иметь более одного телефона. Код в процедуре будет такой:
if DM.TTelephones.Modified then DM.TTelephones.Post;
DM.TTelephones.Append;
DBEdit14.SetFocus;
Вначале мы сохраняем измененные значения, если они были. Затем методом Append мы добавляем в таблицу новую запись.
После добавления новой записи таблица уже будет в режиме редактирования, поэтому можно не вызывать метод Edit, который переводит таблицу в этот режим. Далее мы переводит фокус ввода на DBEdit с
телефонными номерами, чтобы пользователю не пришлось делать это
самому.
12. В процедуре нажатия на кнопку "Сохранить и выйти" код
простой:
if dm.TLichData.Modified then dm.TLichData.Post;
if DM.TDoljnost.Modified then
begin
dm.TDoljnost.FieldByName('sotr').AsInteger:=DBEdit15.Field.A
sInteger;
dm.TDoljnost.Post;
end;
if DM.TAdres.Modified then
begin
dm.TAdres.FieldByName('sotr').AsInteger:=DBEdit15.Field.AsIn
teger;
dm.TAdres.Post;
end;
if DM.TTelephones.Modified then
begin
dm.TTelephones.FieldByName('sotr').AsInteger:=DBEdit15.Field
.AsInteger;
dm.TTelephones.Post;
end;
Form3.Close;
68
13. Здесь мы лишь сохраняем изменения во всех таблицах, если
они были, и закрываем окно. Напоследок у нас осталась кнопка "Добавить сотрудника". Добавить новую запись в каждую таблицу и перевести курсор в первый DBEdit, в котором редактируется фамилия. Это и
делаем:
procedure TForm3.BitBtn3Click(Sender: TObject);
var
k:integer;
begin
k:=0;
dm.TLichData.Open;
while not dm.TLichData.Eof do
begin
k:=dm.TLichData.FieldByName('ID').AsInteger;
dm.TLichData.Next;
end;
if k=0 then k:=1
else k:=k+1;
dm.TLichData.Append;
dm.TLichData.FieldByName('ID').AsInteger:=k;
dm.TDoljnost.Append;
dm.TAdres.Append;
dm.TTelephones.Append;
DBEdit1.SetFocus;
end;
14. Откройте предыдущую форму и пропишите процедуру нажатия на кнопку "Новый сотрудник". Как и в предыдущем примере, нам
потребуется добавить новую запись в каждую таблицу, после чего открыть окно редактора:
procedure TForm1.BitBtn3Click(Sender: TObject);
var k:integer;
begin
k:=0;
dm.TLichData.Open;
while not dm.TLichData.Eof do
begin
k:=dm.TLichData.FieldByName('ID').AsInteger;
69
dm.TLichData.Next;
end;
if k=0 then k:=1 else k:=k+1;
dm.TLichData.Append;
dm.TLichData.FieldByName('ID').AsInteger:=k;
dm.TAdres.Append;
dm.TDoljnost.Append;
dm.TTelephones.Append;
Form3.Show;
end;
15. Сгенерируйте процедуру onClick для кнопки "Редактировать".
Тут будет лишь одна строчка кода:
Form3.ShowModal;
16. Пропишем также редактирование информации на двойной
щелчок по записи в верхней сетке DBGrid. Поэтому выделите сетку с
главной таблицей и сгенерируйте для нее событие onDBLClick. Там
введите такую же строчку кода как и в 15 пункте.
17. По нашему замыслу, при открытии программы в верхней сетке
DBGrid будут отображаться данные из главной таблицы, а в нижней –
из таблицы Adres. Также будет выделена радиокнопка с надписью "Адрес". Если пользователю захочется посмотреть должность или телефоны текущего сотрудника, он будет щелкать соответствующую радиокнопку, и эти данные должны быть отображены в нижней DBGrid. Выделите первую радиокнопку с надписью "Адрес" и сгенерируйте для
нее событие onClick, которое будет возникать, когда пользователь
щелкнет по ней. В процедуре этого события впишите следующий код:
if RadioButton1.Checked then DBGrid2.DataSource := DM.DSAdres;
Для события onClick радиокнопки с надписью "Телефоны" код будет
таким:
If RadioButton2.Checked then DBGrid2.DataSource :=
DM.DSTelephones;
А для события onClick радиокнопки с надписью "Должность", соответственно, код будет следующим:
if RadioButton3.Checked then DBGrid2.DataSource := DM.DSDoljnost;
70
Содержание отчета
1. Номер, тема, цель лабораторной работы.
2. Задание к работе.
3. Вывод о проделанной работе.
Часть 3. Осуществление поиска и фильтрации набора данных
Цель: ознакомление с механизмами поиска данных, фильтрации
записей.
ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
Метод Locate
Метод Locate ищет первую запись, удовлетворяющую условию
поиска. Если запись найдена, метод делает ее текущей и возвращает
True. В противном случае метод возвращает False и курсор не меняет
положения. Поле, по которому ведется поиск, не обязательно должно
быть индексировано. Однако, если поле индексировано, то метод ищет
запись по индексу, что значительно ускоряет поиск. Поиск может вестись как по одному полю, так и по нескольким полям. Метод имеет
три параметра:
function Locate (const KeyFields: String; const KeyValues: Variant;
Options: TLocateOptions) : Boolean;
Параметр KeyFields задает поле или список полей, по которым ведется поиск. Если имеется несколько полей, их разделяют точкой с запятой.
Параметр KeyValues является вариантным массивом, в котором
задаются критерии поиска. При этом первое значение KeyValues ставится в соответствие с первым полем, указанным в KeyFields. Второе –
со вторым, и так далее.
Третий параметр Options позволяет задать некоторые опции поиска:
loCaseInsensitive – поиск ведется без учета высоты букв, то есть,
считаются одинаковыми строки "строка", "Строка" или "СТРОКА".
loPartialKey – запись будет удовлетворять условию, если ее часть
содержит искомый текст. То есть, если мы ищем "ст", то удовлетворять
условию будут "строка", "станция", "стажер" и т. п.
71
Пустой набор [] указывает, что настройки поиска игнорируются.
То есть, строка ищется "как есть".
Примеры использования метода Locate:
Table1.Locate('Фамилия', Edit1.Text, []);
Table1.Locate('Фамилия;Имя', VarArrayOf(['Иванов', 'Иван']),
[loCaseInsensitive]);
Метод Lookup
Метод Lookup, в отличие от Locate, не меняет положение курсора
в таблице. Вместо этого он возвращает значения некоторых ее полей.
Причем в отличие от Locate, этот метод осуществляет поиск лишь на
точное соответствие. Такой способ поиска востребован реже, однако в
иных случаях этим методом очень удобно пользоваться. Рассмотрим
синтаксис этого метода.
function Lookup (const KeyFields: String; const KeyValues: Variant;
const ResultFields: String) : Variant;
Как вы видите, первые два параметра такие же, как у Locate. А вот
третий параметр и возвращаемое значение отличаются. В строке
ResultFields через точку с запятой перечисляются поля таблицы, значения которых метод должен вернуть. Возвращаются эти значения в виде
вариантного массива. Проблема в том, что вернуться может значение
Null, то есть, ничего, или Empty (пустой) и это нужно проверять.
Фильтрация данных
Фильтрацию данных применяют не реже а, пожалуй, даже чаще,
чем поиск. Разница в том, что при поиске данных пользователь видит
все записи таблицы, при этом курсор либо переходит к искомой записи,
либо он получает данные этой записи в виде результата работы функции. При фильтрации дело обстоит иначе. Пользователь в результате
видит только те записи, которые удовлетворяют условиям фильтра,
остальные записи становятся скрытыми. Конечно, таким образом искать нужные данные проще. Можно указать в условиях фильтра, что
требуется вывести всех сотрудников, чья фамилия начинается на "И".
72
Пользователь увидит только их. Воспользуемся событием
onFilterRecord
Это событие возникает при установке значения True в свойстве
Filtered. Применение этого способа имеет большой плюс, и большой
минус. Плюс в том что, сгенерировав это событие, программист получает возможность задать гораздо более сложные условия фильтрации.
Минус же заключается в том, что проверка заключается перебором всех
записей таблицы. Если таблица содержит очень много записей, процесс
фильтрации может затянуться.
В событие передаются два параметра. Первый параметр – набор
данных DataSet. С ним можно обращаться, как с именем фильтруемой
таблицы. Второй параметр – логическая переменная Accept. Этой переменной нужно передавать результат условия фильтра. Если условие
возвращает False, то запись не принимается, и не будет отображаться.
Соответственно, если возвращается True, то запись принимается.
Задание к работе
1. Откройте проект. Перейдите на модуль DM, где хранятся компоненты доступа к базе данных. Процедуру поиска реализуем в этом
модуле, а чтобы с ней можно было работать из других форм, опишем ее
в разделе public:
public
procedure MLocate(s: string);
2. В процедуру передается параметр – строка. В ней мы будем передавать искомую фамилию.
В процедуру пропишите следующий код:
procedure TDM.MLocate(s: string);
begin
TLichdata.Locate('Fam',s,[loPartialKey]);
end;
Таким образом, при нахождении подходящей записи курсор будет перемещаться к ней.
3. На главной форме выделите компонент Edit, предназначенный
для поиска по фамилии. Создайте для него событие onChange, которое
73
наступает при изменении текста в поле компонента. В созданной процедуре пропишите вызов поиска:
procedure TForm1.Edit1Change(Sender: TObject);
begin
DM.MLocate(Edit1.Text);
end;
4. Далее организуем поиск методом Lookup.
5. Для поиска воспользуемся кнопкой с надписью "Найти", расположенной в верхней части главной формы. Идея такова: пользователь
вводит в поле Edit1 какую то фамилию и нажимает кнопку "Найти".
Событие onClick этой кнопки собирает в строковую переменную значения четырех указанных полей найденной записи. Причем после каждого значения в строку добавляется символ "#13" (переход на новую
строку), формируя многострочный отчет. Затем эту строку мы выведем
на экран функцией ShowMessage().
6. Для этого сгенерируем событие onClick по кнопке «Найти».
procedure TForm1.BitBtn1Click(Sender: TObject);
var
mlookup:variant;
s: string;
begin
mlookup:=dm.TLichData.Lookup('Fam',edit1.Text,'Fam;im;ot;Obraz');
if varType(mlookup)=varnull then
showmessage('Сотрудник с такой фамилией не найден') else
if vartype (mlookup)= varEmpty then showmessage('Запись не
найдена')
else if varisarray(mlookup) then
begin
s:=mlookup[0]+#13+mlookup[1]+#13+ mlookup[2]+#13+
mlookup[3];
showmessage(s);
end;
end;
7. Помимо поиска организуем фильтрацию.
8. Добавьте компонент Edit2 на главную форму.
9. Перейдите к модулю данных и создайте глобальную переменную Ed.
74
var
DM: TDM;
ed:string;
10. Далее выделите TLichData. На вкладке Events (События) инспектора объектов найдите событие onFilterRecord и дважды щелкните
по нему, сгенерировав процедуру.
11. В процедуре запишите следующий код:
procedure TDM.TLichDataFilterRecord(DataSet: TDataSet; var Accept: Boolean);
var s:string;
begin
s:=Copy (DataSet['Fam'],1,length(ed));
accept:=s=ed;
end;
12. Перейдите на главную форму и сгенерируйте событие onChange компонента Edit2
procedure TForm1.Edit2Change(Sender: TObject);
begin
if Edit2.text<>' ' then begin
DM.TLichData.Filtered:=False;
ed:=Edit2.text;
dm.TLichData.Filtered:=True;
end
else dm.TLichData.Filtered:=false;
end;
Содержание отчета
1.
2.
3.
4.
5.
Номер, тема, цель лабораторной работы.
Задание к работе.
Интерфейс приложения
Текст программы.
Вывод о проделанной работе.
75
Лабораторная работа № 9
ПОИСК ДАННЫХ С ПОМОЩЬЮ СТАТИЧЕСКИХ
И ДИНАМИЧЕСКИХ ЗАПРОСОВ
Цель: приобретение практических навыков создания программ,
позволяющих выполнять поиск записей в базе данных с помощью компонента TADOQuery.
Задание к работе
1. Откройте проект, созданный в предыдущей работе. Создайте
форму 4. На первой форме создайте кнопку «Расширенный поиск», открывающую форму 4.
2. Осуществим поиск адреса сотрудников по введенному городу.
Для этого на форму 4 поместим компоненты 2 Label,Edit, Button,
DBGrid.
3. Перейдите на модуль DM, где хранятся компоненты доступа к
базе данных. Добавьте в модуль компонент ADOQuery и DataSource.
4. Переименуйте их в QAdres и DSQAdres соответственно.
5. У компонента QAdres выберете в свойстве Connection компонент ADOConnection1 и DSLichData в свойстве DataSource (ссылается
на компонент TDataSource, из набора данных которого задаются значения параметров).
76
6. У компонента DSQAdres в свойстве DataSet QAdres.
7. У компонента DBGrid в свойстве DataSource
DM.DSQAdres.
8. Далее пропишите процедуру нажатия кнопки
укажите
procedure TForm4.Button1Click(Sender: TObject);
begin
DM.QAdres.Close;
DM.QAdres.SQL.Clear;
DM.QAdres.SQL.Add('SELECT Fam,Im,Ot,Gorod,Dom_adr');
DM.QAdres.SQL.Add('FROM LichData,Adres ');
DM.QAdres.SQL.Add('Where
(Adres.gorod='+QuotedSTR(Edit1.Text)+')');
DM.QAdres.SQL.Add('AND(LichData.ID=Adres.Sotr)');
DM.QAdres.Open;
end;
9. Осуществим расчет среднего стажа всех сотрудников и разобьем эти данные по отделам. Для этого будем использовать агрегатную
функцию AVG.
10. На форму 4 добавим компоненты label, button, DBGrid.
11. Перейдите на модуль DM, где хранятся компоненты доступа к
базе данных. Добавьте в модуль компонент Query и DataSource.
12. Переименуйте их в QStag и DSQStag соответственно.
77
13. У компонента QStag выберете псевдоним Otdel в свойстве DataBase Name и DSLichData в свойстве DataSource. В свойстве SQL укажите следующие команды:
Select AVG(Stag), Otdel
From LichData, Doljnost
Where ID=Sotr
Group By Otdel
14. У компонента DSQStag в свойстве Data Set QStag.
15. У компонента DBGrid в свойстве DataSource укажите
DM.DSQStag.
16. Далее пропишите процедуру нажатия кнопки
procedure TForm4.Button2Click(Sender: TObject);
begin
DM.QStag.Close;
DM.QStag.Open;
end;
17. Осуществим поиск сотрудников по введенной должности и
стаж работы которых находится введенных пределах.
18. Для этого на форму 4 добавим 3 компонента Edit, 1 Button, 5
Label b 1 DBGrid
78
19. Перейдите на модуль DM. Добавьте в модуль компонент Query и DataSource.
20. Переименуйте их в QDoljn и DSQDoljn соответственно.
21. У компонента QDoljn выберете псевдоним Otdel в свойстве
DataBase Name и DSLichData в свойстве DataSource.
22. У компонента DSQDoljn в свойстве Data Set QDoljn.
23. У компонента DBGrid в свойстве DataSource укажите
DM.DSQDoljn.
24. Далее пропишите процедуру нажатия кнопки
procedure TForm4.Button3Click(Sender: TObject);
begin
DM.QDoljn.Close;
DM.QDoljn.SQL.Clear;
DM.QDoljn.SQL.Add('SELECT Fam,Im,Ot,Doljn,Otdel');
DM.QDoljn.SQL.Add('FROM LichData,Doljnost ');
DM.QDoljn.SQL.Add('Where
(Doljnost.doljn='+QuotedSTR(Edit2.Text)+')');
DM.QDoljn.SQL.Add('AND(LichData.ID=Doljnost.Sotr)');
DM.QDoljn.SQL.Add('AND (lichdata.stag BETWEEN '+
it3.Text+' AND '+ Edit4.Text+')');
DM.QDoljn.Open;
end;
Ed-
25. Создайте еще один динамический или статический запрос на
ваше усмотрение
Содержание отчета
1.
2.
3.
4.
5.
Номер, тема, цель лабораторной работы.
Задание к работе.
Интерфейс приложения
Текст программы.
Вывод о проделанной работе.
79
Лабораторная работа № 10
СОЗДАНИЕ ОТЧЕТА
Цель: приобретение практических навыков создания приложений,
позволяющих выполнять просмотр и печать отчетов с помощью Quick
Report.
Задание к работе
1. Откройте проект. Если пакет Quick Report еще не установлен
(на палитре компонентов отсутствует вкладка QReport), то загрузите
Delphi и закройте все открытые проекты (File -> Close All).
2. Выбрерите пункт меню "Component -> Install Packages".
3. Нажмите кнопку "Add" и выберите пакет "dclqrt70.bpl", который по умолчанию устанавливается по адресу: c:\Program
Files\Borland\Delphi7\bin\dclqrt70.bpl
4. Нажмите кнопку "Открыть". Далее, нажмите кнопку "ОК" – пакет компонентов Quick Report установится, и его вкладка будет самой
последней на Палитре компонентов. При желании можно перетащить
ее мышью на другое место, поближе к началу.
5. На главной форме установите компонент Main Menu и создайте разделы
Раздел
Файл
Отчеты
Подраздел
Выход
Кадры, по телефонам, по адресам
6. Создайте новую форму и подключите к ней модуль данных.
7. Установите QuickRep на новую форму, и он примет вид разлинованного листа.
8. Выделите QuickRep и обратите внимание на его свойства. В самом верху находится свойство Bands (Ленты, полосы – англ.). Это раскрывающееся свойство, оно содержит шесть параметров. Щелкните по
плюсу слева от свойства, чтобы раскрыть его. По умолчанию, все параметры имеют значение False, то есть, не установлены. Если какой-либо
параметр перевести в значение True, на холсте появится соответствующая полоса. Попробуйте установить все параметры. Разберемся с их
назначением.
80
HasColumnHeader – Заголовки колонок. Здесь мы будем вписывать
названия колонок таблицы.
HasDetail – Детальная информация. На этой ленте формируются
строки таблицы.
HasPageFooter – Подвал (нижний колонтитул). Здесь можно установить информацию, которая будет появляться в нижней части каждой
страницы.
HasPageHeader – Шапка (верхний колонтитул). Здесь можно установить информацию, которая будет появляться в верхней части каждой
страницы.
HasSummary – Суммарная информация. Содержимое этой полосы
печатается один раз в самом конце отчета.
HasTitle – Заголовок отчета.
9. Переведите в True полосы HasPageHeader, HasTitle, HasColumnHeader, HasDetail и HasPageFooter. Не установленной останется
только полоса HasSummary. Если вы дважды щелкните мышью по свободному месту холста, появится настроечное окно:
10. В этом окне можно выполнить большинство настроек, причем
в Инспекторе объектов соответствующие свойства будут изменены автоматически. Как видите, установленные нами полосы отмечены "галочкой" в разделе Bands окна. Выше располагается раздел Page frame, в
котором можно задать обрамление для верхней (Top), нижней (Bottom),
левой (Left) и правой (Right) границ холста, а также изменить цвет и
ширину обрамления. Те же действия можно выполнить в Инспекторе
81
объектов с помощью параметров раскрывающегося свойства
Frame(пока открыто окно настроек, менять свойства в Инспекторе Объектов не получится).
Еще выше располагается раздел Other, где можно установить общие данные для холста – шрифт, размер шрифта и единицы измерения
(по умолчанию mm – миллиметры). В Инспекторе объектов за это отвечают свойства Font и Units.
Далее находится раздел Margins (Границы, края), где можно задать
расстояния от краев листа до рабочей части холста. На самом верху окна располагается раздел Paper size (Размер бумаги), где задаются тип
листа и его размеры. Данные этих двух разделов можно изменить в Инспекторе объектов в раскрывающем свойстве Page.
Еще следует обратить внимание на свойство Options, которое имеет три параметра:
FirstPageHeader – Разрешает печать заголовков (шапку) первой
страницы, если равно True.
LastPageFooter – Разрешает печать подвала последней страницы,
если равно True.
Compression – Разрешает сжатие отчета при формировании из него
метафайла (отчет представляет собой изображение), если равно True.
Свойство PrintIfEmpty разрешает (True) или запрещает (False) печатать отчет, если в нем нет никаких данных.
Свойство ShowProgress разрешает или запрещает показывать индикатор процесса печати отчета. По умолчанию индикатор разрешен.
Свойство SnapToGrid разрешает или запрещает привязывание
компонентов к сетке. По умолчанию привязка разрешена.
Свойство Zoom имеет тип Integer и позволяет изменить масштаб
отображения отчета при его разработке. Значение 100 указывает, что
отчет показывается в 100 % от листа бумаги. Изменение этого свойства
не влияет на масштаб печати отчета или его предварительного просмотра.
11. Теперь приступим к формированию отчета. На холсте у нас
уже должны быть расположены пять полос. Теперь мы можем на эти
полосы устанавливать другие компоненты. На самом верху холста
находится полоса Page Header, которая, как мы уже знаем, является
верхним колонтитулом. Установите в левой части этой полосы компонент QRSysData – компонент с различного рода системной информацией. Нас интересует свойство Data этого компонента. Data содержит несколько свойств, формирующих отображаемую информацию. Разберем
эти свойства.
82
qrsDate (Вывод текущей даты)
qrsDateTime (Вывод текущих даты и времени)
qrsDetailCount (Количество строк формируемой таблицы)
qrsDetailNo (Номер текущей строки таблицы)
qrsPageNumber (Номер текущей страницы отчета)
qrsReportTitle (Заголовок отчета)
qrsTime (Вывод текущего времени)
12. Установим для этого свойства значение qrsDateTime, чтобы
пользователь мог видеть, когда был сформирован отчет. Далее выделим
всю полосу Page Header и в свойстве Frame переведем в True параметр
DrawBottom. Это свойство позволяет задать обрамление выделенной
полосе, а параметр DrawBottom рисует линию в нижней части полосы.
То есть, мы визуально отделили колонтитул от данных листа.
13. В нижней части холста располагается полоса Page Footer (подвал). Здесь желательно установить верхнюю линию в свойстве Frame,
отделив от данных нижний колонтитул. А по центру полосы установить
еще один компонент QRSysData, установив свойство Data в значение
qrsPageNumber. Этот компонент будет выводить номер текущей страницы в нижней части листа.
14. Напишем заголовок отчета. Для этого установите компонент
QRLabel в центре полосы Title. В его свойстве Caption напишите "Отчет
по кадрам". Чтобы заголовок был красивым, щелкните дважды по свойству Font, чтобы открылось окно шрифта. Здесь установите шрифт
Times New Roman, начертание выберите жирное, а размер шрифта
пусть будет 18.
15. Далее займемся полосой Column Header (Заголовки колонок).
Здесь установите рядом пять компонентов QRLabel, в свойстве Caption
которых напишите
Фамилия
Имя
Отчество
Дата рождения
Образование
16. Это будут названия колонок таблицы. Шрифт этих компонентов также желательно сделать крупнее, но не больше заголовка.
17. Далее займемся полосой Detail, на которой, собственно, и будет формироваться таблица. Здесь нам нужно будет в самом крайнем
83
положении слева установить компонент QRSysData, в свойстве Data которого выбрать qrsDetailNo – перед каждой строкой будет выходить ее
номер. Далее установите пять компонентов QRDBText, в которых будут
отражаться данные из соответствующих полей таблицы. Эти компоненты соответствуют обычному DBText, с которым мы неоднократно сталкивались. Расположите их точно под названиями столбцов, чтобы таблица была красивой. При этом может оказаться, что компонент
QRSysData "наплывает" на QRDBText – ничего страшного, данные все
равно не будут мешать друг другу. Выделите все QRDBText, и в их
свойстве DataSet выберите нашу таблицу fDM.TLichData, затем поочередно в свойстве DataField этих компонентов выберите соответствующие поля таблицы:
Fam
Im
Ot
Dtr
Obraz
18. Кроме того, сам компонент QuickRep1, который является "холстом" отчета, также должен знать, из какой таблицы ему нужно брать
данные. Поэтому выделите его, и в свойстве DataSet также выберите
нашу таблицу DM.TLichData. Если этого не сделать, то в отчете будет
выходить лишь текущая запись таблицы, а не все ее записи.
19. Вернитесь в главное окно проекта и сгенерируйте обработку
команды меню "Отчеты – Кадры".
procedure TForm1.N5Click(Sender: TObject);
begin
form5.QuickRep1.PreviewModal;
end;
20. На вкладке QReport имеется компонент QRShape, который
позволяет рисовать простейшие линии и фигуры. Он имеет свойство
Shape, в котором можно задать нужную фигуру. Возможные значения
этого свойства:
qrsCircle (Круг)
qrsHorLine (Горизонтальная линия)
qrsRectangle (Прямоугольник)
qrsRightAndLeft (Прямоугольник с очерченными левым и правым
краями)
84
qrsTopAndBottom (Прямоугольник с очерченными верхним и
нижним краями)
qrsVertLine (Вертикальная линия)
21. Этот компонент можно использовать по-разному. Например,
можно установить по одной горизонтальной линии сверху и снизу полосы Detail, а затем вертикальными линиями отделить каждый столбце
страницы. Можно проще: каждый столбец заключил в прямоугольник
(шесть компонентов QRShape), а чтобы QRShape не перекрывал текст,
щелкните по ним правой кнопкой и выберите команду Control -> Send
to Back (поместить на задний план).
22. Создадим отчет по телефонам. Для этого создайте в проекте
новую форму,подключите модуль с наборами данных DM.
23. Установите на новую форму основу отчета QuickRep.В свойстве DataSet компонента-основы выберите DM.TLichData, то есть, таблицу с личными данными.
24. Теперь создайте на основе полосы Page Header, Title, Column
Header и Detail.
25. На верхнюю полосу Page Header установите по краям два
компонента QRSysData, в свойстве Data у первого выберите
qrsDateTime, а у второго qrsPageNumber. Кроме того, переведите в True
параметр DrawBottom у свойства Frame полосы Page Header, чтобы отделить линией верхний колонтитул.
26. Далее, на полосу Title установите один компонент QRLabel, на
котором напишите заголовок "Отчет по телефонам сотрудников". Измените шрифт, начертание и размер, как в прошлом примере, и отцентрируйте заголовок по полосе.
27. Ниже идет полоса Column Header с заголовками таблицы. Как
и в прошлом примере, требуется из компонентов QRLabel сформировать заголовки столбцов, но в этот раз ограничимся только тремя заголовками: "Фамилия", "Имя" и "Отчество".
28. Далее у нас идет полоса Detail, на которой нам нужно разместить три компонента QRDBText, которые привязать к соответствующим полям (не забудьте про свойства DataSet и DataField этих компонентов). Еще в свойстве Frame полосы Detail желательно перевести параметр DrawTop в True, чтобы каждая запись отчета отделялась линией.
29. Теперь добавим в отчет связанные данные из другой таблицы.
Установите компонент QRSubDetail – эта полоса должна быть самой
нижней. Сначала нужно выбрать главный по отношению к этому компонент: в свойстве Master выберите QuickRep1. Кроме того, полоса
85
QRSubDetail должна знать, откуда листать данные, поэтому в свойстве
DataSet полосы выберите DM.TTelephones.
30. Далее установим на полосу один компонент QRLabel, напишем на нем "Телефон:".
31. Слева от него установите два компонента QRDBText, в свойстве Dataset которых выберите fDM.TTelephones, а в свойстве DataField
выберите соответственно, поля "Телефон" и "Примечание". Теперь
мышью немного перетащите нижний край полосы, чтобы сделать ее
поуже.
32. Создайте процедуру вызова этого окна в команде главного
меню Отчеты -> По телефонам, и пропишите там вызов
Form6.QuickRep1.PreviewModal;
33. Отчет по адресам сотрудников создается точно таким же образом, сделайте его самостоятельно.
Отчет можно не только распечатать. Его также можно сохранить в
специальном формате *.qrp, а затем загрузить в окно предварительного
просмотра. Для этого соответственно служат кнопки "Save Report" и
"Load Report" на панели инструментов окна предварительного просмотра.
Однако бывают случаи, когда отчет желательно сохранить в каком-нибудь общем формате, например, в текстовом, или html (webстраница). Тогда отчет можно было бы просмотреть в стандартном
Блокноте или web-броузере, переслать сотруднику, у которого ваша
программа не установлена. На вкладке QReport имеются компоненты,
которые позволяют это сделать.
QRTextFilter – позволяет сохранить отчет в виде текстового файла.
QRCSVFilter – позволяет сохранить отчет в специальном формате
CSV (Comma Separated).
QRHTMLFilter – позволяет сохранить отчет в формате webстраницы.
Это не визуальные компоненты, на отчете они не отобразятся. Достаточно установить один из них (или все вместе) на основу отчета
QuickRep, и при сохранении отчета пользователю станут доступны соответствующие форматы.
Причем если у вас в проекте имеется несколько окон с отчетами,
компоненты добавляются только в один из них, в остальных отчетах
эти форматы также станут доступны.
86
Содержание отчета
1.
2.
3.
4.
5.
Номер, тема, цель лабораторной работы.
Задание к работе.
Интерфейс приложения
Текст программы.
Вывод о проделанной работе.
87
Лабораторная работа № 11
РАЗРАБОТКА ПРИЛОЖЕНИЯ
С СОХРАНЕНИЕМ ПАРАМЕТРОВ
И УСТАНОВОК В INI-ФАЙЛАХ
Цель: изучить возможности автоматического сохранения параметров и установок, принятых в программе.
ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
Удобным средством запоминания текущих настроек приложения
являются ini-файлы. Ini-файлы – это текстовые файлы, предназначенные для хранения информации о формах или о настройках различных
приложений. Информация в файле логически группируется в разделы,
каждый из которых начинается оператором заголовка, заключенным в
квадратные скобки, например, [Desktop]. В строках, следующих за заголовком, содержится информация, относящаяся к данному разделу, в
виде:
<ключ>=<значение>
Любое приложение можно зарегистрировать в системном реестре
и зафиксировать там же текущие настройки приложения (в 32разрядных Windows и выше). Для 32-разрядных приложений Microsoft
не рекомендует работать с Ini-файлами. Ннесмотря на это, и 32разрядные приложения, наряду с реестром, часто используют эти файлы. Да и разработки Microsoft не обходятся без этих файлов.
Ini-файлы, как правило, хранятся в каталоге Windows, который
можно найти с помощью функции GetWindowsDirectory.
В Delphi работу с Ini-файлами проще всего осуществлять с помощью создания в приложении объекта типа TIniFile. Этот тип описан в
модуле IniFiles, который надо подключать к приложению оператором
uses (автоматически это не делается).
Создается объект типа TIniFile методом Сгеаtе(<имя файла>), в
который передается имя Ini-файла, с которым он связывается.
Для записи значений ключей существует несколько методов: WriteString, WriteInteger, WriteFloat, WriteBool и др. Каждый из них записывает значение соответствующего типа. Объявления всех этих методов
очень похожи. Например:
88
procedure WriteString (const Section, Ident, Value: string);
procedure WriteInteger(const Section, Ident: string; Value: Longint);
Здесь Section — раздел Ini-файла, Ident — имя ключа, Value —
значение ключа. Если соответствующий раздел или ключ отсутствует в
файле, он автоматически создается.
Имеются аналогичные методы чтения значений ключей:
ReadString, ReadInteger, ReadFloat, ReadBool и др. Например:
function ReadString(const Section, Ident, Default: string) : string;
function ReadInteger(const Section, Ident: string; Default: Longint) :
Longint;
В этих примерах методы чтения возвращают значение ключа Ident
раздела Section. Параметр Default определяет значение, возвращаемое в
случае, если в файле не указано значение соответствующего ключа.
Проверить наличие значения ключа можно методом ValueExists, в
который передаются имена раздела и ключа. Метод DeleteKey удаляет
из файла значение указанного ключа в указанном разделе.
Проверить наличие в файле необходимого раздела можно методом
SectionExists. Метод EraseSection удаляет из файла указанный раздел
вместе со всеми его ключами. Имеется еще ряд методов, которые можно посмотреть во встроенной справке Delphi.
Рассмотрим на примере, как запоминать и удалять настройки программы. Создадим простое тестовое приложение. Поместим на форму
три компонента Button и компонент FontDialog.
Первой кнопку присвоим имя (Name) BInst и зададим Install в ее
свойстве Caption. Эта кнопка будет имитировать установку программы.
Точнее, не саму установку, поскольку копировать файлы с установочной дискеты мы не будем, а только создание Ini-файла в каталоге Windows.
Вторую кнопку назовем BUnInst и зададим UnInstall в ее свойстве
Caption. Эта кнопка будет имитировать удаление программы. Здесь мы
не будем удалять программу с диска, а только удалим из каталога Windows наш ini-файл.
Третью кнопку назовем BFont и зададим Font в ее свойстве Caption.
С помощью этой кнопки будем менять имя шрифта, используемого в
форме. Имя этого шрифта надо будет запоминать в Ini-файле, чтобы в
дальнейшем при запуске приложения можно было читать эту настройку
и задавать ее форме. Текст программы:
89
unit LabRab_10;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, IniFiles;
type
TForm1 = class(TForm)
BInst: TButton; BUnInst: TButton; BFont: TButton;
FontDialog1: TFontDialog;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure BInstClick(Sender: TObject);
procedure BUnInstClick(Sender: TObject);
procedure BFontClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1; Ini : TIniFile; sFile: string;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
APchar: array[0..254] of Char;
begin
//Формирование имени каталога Windows
GetWindowsDirectory(APchar, 255); //Формирование имени iniфайла в каталоге Windows
sFile := string(APchar) + '\My.ini';
if FileExists(sFile) then
begin
Ini := TIniFile.Create(sFile); // Чтение в имя шрифта формы значения ключа Шрифт Font.Name := Ini.ReadString('Параметры',
'Шрифт', 'MS Sans Serif1);
90
end; end;
procedure TForm1.BInstClick(Sender: TObject);
var f: File;
begin
//Проверка существования ini-файла
if (not FileExists(sFile)) then begin
// Создание ini-файла
AssignFile(f, sFile); Rewrite(f);
CloseFile(f);
Ini := TIniFile.Create(sFile); end;
//Создание раздела Files, ключа main и запись в него имени
//выполняемого файла вместе с путем
Ini.WriteString('Files','main', ParamStr(O)); //Создание раздела Параметры, ключа Шрифт и //запись в него имени шрифта формы
Ini.WriteString('Параметры', 'Шрифт', Font.Name); end;
procedure TForm1.BUnInstClick(Sender: TObject); var
F: File;
begin
//Удаление с диска ini-файла, если он существует
if FileExists(sFile) then begin AssignFile(F, sFile); Erase(F); end;
end;
procedure TForm1.BFontClick(Sender: TObject); begin
//Выбор шрифта
if (FontDialog1.Execute) then begin
// Присваивание выбранного шрифта форме
Font.Assign(FontDialog1.Font);
if (Ini<>nil) and Ini.ValueExists('Параметры','Шрифт') then
// Запись шрифта в ключ "Шрифт" раздела "Параметры"
Ini.WriteString('Параметры','Шрифт', Font.Name); end; end;
procedure TForm1.FormDestroy(Sender: TObject); begin
if (Ini = nil) then Exit; //Очистка буфера и запись файла на диск
Ini.UpdateFile; //Освобождение памяти
Ini.Free; end;
end.
91
В начале текста следует подключение к приложению модуля IniFiles и объявление переменной Ini типа TIniFile, а также переменной
sFile, в которой будет формироваться имя файла и путь к нему.
Ini : TIniFile;
sFile: string;
При создании формы приложения в процедуре TForm1.FormCreate
формируется имя файла (My.Ini) вместе с путем к нему – каталогом
Windows. Путь Windows определяется функцией GetWindowsDirectory.
Далее функцией FileExists проверяется, существует ли этот файл,
т.е. проведена ли уже установка программы. Если существует, то создается объект Ini, связанный с этим файлом, и значение MS Sans Serif
ключа Шрифт раздела Параметры читается в имя шрифта формы. Тем
самым читается настройка, произведенная при предыдущем выполнении приложения.
Теперь рассмотрим процедуру TForm1.BInstClick, имитирующую
установку программы. В этой процедуре сначала функцией FileExists
проверяется, существует ли в каталоге Windows файл My.Ini. Если не
существует, то последовательным применением функций AssignFile,
Rewrite и CloseFile этот файл (пока пустой) создается. Затем создается
связанный с этим файлом объект Ini. Последующие операторы записывают в этот файл два раздела Files и Параметры с соответствующими
ключами.
В ключ main записывается имя приложения с путем к нему. Для
этого используется функция ParamStr(0).
В результате в созданный файл записывается, например, такой
текст:
[Files]
main = D:\DEMO Delphi\DEMO1_INI.EXE
[Параметры]
Шрифт = MS Sans Serif
Процедура TForml.BUnInstClick имитирует удаление приложения
и его файла настройки. В данном случае просто удаляется Ini-файл, но в
настоящем приложении надо было бы прочитать имя файла (или файлов) приложения из раздела Files и удалить их с диска.
92
Процедура TForm1.FormDestroy, срабатывающая при закрывании
формы приложения, сначала методом UpDateFile переписывает содержимое объекта Ini в файл на диске, а затем методом Free удаляет из памяти этот временный объект.
Процедура TForml.BFontClick вызывает стандартный диалог выбора шрифта и если пользователь выбрал шрифт, то он присваивается
форме и его имя заносится в ini-файл.
Сохраните свое приложение и запустите его на выполнение.
Нажмите кнопку Install. После этого убедитесь в наличии файла My.Ini
в каталоге Windows. Можете воспользоваться для этого программой
Windows «Проводник» или любой другой. В частности, можно открыть
этот файл просто из среды Delphi. При нажатии кнопки UnInstall файл
должен удаляться с диска. Проверьте запись в файл настройки шрифта
и чтение ее при последующих запусках. Для этого опять нажмите кнопку Install, а затем нажмите кнопку Font и выберите шрифт с какимнибудь другим именем. Затем закройте свое приложение и запустите
его повторно. Вы увидите, что на форме применен тот шрифт, который
вы зарегистрировали в файле настройки. Таким образом, приложение
проимитировало установку программы, удаление программы и запоминание ее текущих настроек.
После запуска программы и нажатия затем кнопки Install, используя проводник, в директории c:\windows можно увидеть файл MyIni.ini.
Содержание файла:
[Files]
main = D:\DEMO DELPHI EXAMPLES\
DEMO1 INIF ILES\PROJECTDEMO 1INIFILES.EXE
[Параметры]
Шрифт = Times New Roman
После запуска программы и нажатия кнопки UnInstall в упомянутой директории файл MyIni.ini отсутствует.
ЗАДАНИЕ К РАБОТЕ
1. Разработать приложение, поддерживающее чтение и сохранение
настроек в Ini -файлах.
2. Реализовать чтение и сохранение параметров при запуске и завершении программы. В качестве задания использовать лабораторную
работу № 3
93
Содержание отчета
1.
2.
3.
4.
Номер, тема, цель лабораторной работы.
Задание к работе.
Результаты работы программы.
Вывод о проделанной работе.
94
Лабораторная работа № 12
СОЗДАНИЕ СПРАВОЧНОЙ СИСТЕМЫ ПРИЛОЖЕНИЯ
Цель: приобретение практических навыков разработки справочной системы приложения.
ЗАДАНИЕ К РАБОТЕ
1.
2.
3.
4.
Разработать файл тем справок.
Скомпилировать файл справки.
Проверить работоспособность .
Оформить отчет и сдать работу.
Ход работы
1. В текстовом редакторе Word создайте новый документ.
2. На первой странице по центру напечатайте «Оглавление». Перед словом вставьте сноску “#gl”. Для этого в пункте «Ссылки» на панели «Сноски» нажмите кнопку «Вставить сноску». В открывшемся
окне в окне редактирования «Формат/ другой» вставьте символы «#gl».
Для того, чтобы перед заголовком не выводился идентификатор заголовка, в сноске «#gl» удалите «gl»
3. На следующей строке слева наберите «Справка по Delphi». Все
выражение подчеркните двойной чертой. Затем без пробела наберите sp
(идентификатор данного раздела справочной информации). Выделите
sp и в контекстном меню на вкладке Шрифт сделайте данный текст
скрытым.
4. Таким же образом создайте следующие разделы: Проект (pr),
Объект (ob), Компоненты (km).
5. Далее вставьте «Разрыв страницы».
6. Каждый раздел должен начинаться с новой страницы и заканчиваться разрывом страницы.
7. Раздел «Справка по Delphi».
По центру наберите «Справка по Delphi». Перед выражением
вставьте сноску «#sp». Внизу листа в разделе сносок должна также отражаться сноска «#sp». Для того, чтобы перед заголовком не выводился
идентификатор заголовка, в сноске «#sp» удалите «sp». Далее перейдите на новую строку и слева наберите следующий текст: «Delphi – это
объектно-ориентированная среда программирования, использующая
95
язык Object Pascal. В основе объектно-ориентированного программирования лежит не действие, а объект. Интегрированная среда разработчика обеспечивает проектирование, запуск и тестирование создаваемого
приложения. В Delphi интегрированная среда разработчика содержит
редактор кодов, отладчик, редактор изображений, наборы инструментов для работы с базами данных и т.д.»
Слово «объект» в данном тексте подчеркните двойной чертой и
без пробела укажите скрытый текст «ob».
8. Раздел «Проект». Также как и в предыдущем пункте создайте
заголовок со сноской с идентификатором.
Ниже разместите текст: «Проект – это совокупность различных
файлов, необходимых для построения приложений.». После этого перечислите все файлы проекта.
9. Раздел «Объект».
Также как и в предыдущем пункте создайте заголовок со сноской
с идентификатором.
Ниже разместите текст: «Объект – это совокупность свойств и методов, а также событий на которые он реагирует. Совокупность данных
и методов чтения, записи называется свойством. Также у каждого объекта существует свой набор событий, то есть набор процедур и функций, реализовывающих какое-либо действие с объектом »
10. Раздел «Компоненты»
В этом разделе перечислите и создайте ссылки на соответствующие группы визуальных компонентов.
11. После создания файла тем справок сохраните полученный документ с расширением rtf.
12. Для компиляции его в help-файл из папки Delphi/Help/Tools
запустите приложение HCW.exe. Выберете команду File-New-Help Project. Далее укажите имя файла справки с расширением .hjp. В открывшемся окне нажмите кнопку Files-Add и укажите путь и созданный
файл rtf. Далее в главном окне нажмите на кнопку Windows и на вкладке General в окне Window Type укажите main, также можно указать
размеры окна файла справки и цвет внося изменения на вкладках Position и Color. Далее в главном окне нажмите кнопку Map и присвойте
каждому разделу номер. После этого в главном окне нажмите кнопку
Save and Compile. После чего в папке указанной ранее будет отражаться
файл с расширением HLP.
13. Откройте свое приложение в Delphi. Свяжите созданный файл
справки с приложением для этого выберете Project-Options-Application
и выберете файл в окне Help file.
96
14. В свойстве HelpContext Form1 укажите номер самой первой
темы. При запуске приложения при нажатии клавиши F1 должна отразиться созданная вами справка.
Содержание отчета
1.
2.
3.
4.
Номер, тема, цель лабораторной работы.
Задание к работе.
Результаты работы программы.
Вывод о проделанной работе.
97
Список литературы
1. Фаронов В. В. Delphi. Программирование на языке высокого
уровня: [Учеб. для вузов. Допущено МО РФ].- М. [и др.]: Питер, 2007.
639 с.
2. Фаронов В. В. Программирование баз данных в Delphi 7: Учеб.
курс. СПб.: Питер, 2006. 458 с.
3. Климова Л. М. Delphi 7.Основы программирования.Решение
типовых задач: Самоучитель / Л. М. Климова. 3-е изд. М.: КУДИЦОБРАЗ, 2005. 480 с.
4. Delphi 7 / А. Д. Хомоненко, В. Гофман, Е. Мещеряков, В. Никифоров; Под ред. А. Д. Хомоненко. СПб.: БХВ-Петербург, 2008.
1200 с.
5. Бобровский С. И. Delphi 7: Учебный курс / С. И. Бобровский.
СПб.: Питер, 2007. 735 с.
6. Жуков А. Изучаем Delphi. СПб.: Питер, 2003. 346 с.
(Сер."Компас").
7. Архангельский А. Я. Программирование в Delphi 7. М.: Изд-во
ООО "Бином-Пресс", 2004. 1152 с. +Дискета.
8. Культин Н. Б. Delphi в задачах и примерах. СПб.: БХВПетербург, 2005. 288с. +CD-ROM.
9. Поган А. М. Программирование в Delphi / А. М. Поган,
Ю. А. Царенко. М.: Эксмо, 2006. 309 с. (Просто как дважды два).
98
Приложение
Пример оформления отчета по лабораторной работе
СЕВЕРО-КАВКАЗСКИЙ ГОРНО-МЕТАЛЛУРГИЧЕСКИЙ ИНСТИТУТ
Кафедра автоматизированной обработки информации
ОТЧЕТ
ПО ЛАБОРАТОРНОЙ РАБОТЕ № 3
«Проектирование пользовательского интерфейса»
ПО КУРСУ: Программирование на Delphi
Выполнил:
____________________
Проверил:
____________________
Владикавказ 201__
99
Download