Министерство России по связи и информатизации Поволжская Государственная Академия Телекоммуникаций и Информатики
МЕТОДИ...
22 downloads
390 Views
5MB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Министерство России по связи и информатизации Поволжская Государственная Академия Телекоммуникаций и Информатики
МЕТОДИЧЕСКИЕ УКАЗАНИЯ к лабораторным работам
"Программирование в среде Delphi"
Авторы-составители: АКЧУРИН Э.А., д.т.н., профессор СТЕФАНОВА И.А., ст. преподаватель Редактор:
АКЧУРИН Э.А., д.т.н., профессор
Рецензент:
КОРАБЛИН М.А., д.т.н., профессор
Самара 2003
2
Содержание Введение....................................................................................................................................................................
3
1
ИСР Delphi..................................................................................................................................................................
4
2.
Структура программы и типы данных .....................................................................................................................
13
3.
Линейные структуры .................................................................................................................................................
17
4.
Структуры с ветвлениями.........................................................................................................................................
21
5.
Циклы с неизвестным числом повторений..............................................................................................................
26
6.
Циклы с заданным числом повторений...................................................................................................................
30
7.
Массивы .....................................................................................................................................................................
34
8.
Файлы.........................................................................................................................................................................
38
8.
Подпрограммы...........................................................................................................................................................
46
10.
Динамическая память ...............................................................................................................................................
50
11.
Исключения................................................................................................................................................................
53
12.
Списки ........................................................................................................................................................................
57
13.
Модули .......................................................................................................................................................................
61
14.
Таблицы .....................................................................................................................................................................
66
15.
Графика, отображение графиков функций .............................................................................................................
71
16.
Графика, примитивы .................................................................................................................................................
75
17.
Графика, изображения и анимация .........................................................................................................................
83
18.
Тестирование и отладка ...........................................................................................................................................
89
19.
Квадратное уравнение..............................................................................................................................................
94
20.
Класс TThread ............................................................................................................................................................
98
21.
Класс TStream............................................................................................................................................................
104
3
0. Введение Лабораторный цикл содержит 19 работ по изучению программирования на языке Delphi (Object Pascal) в интегрированной среде разработки (ИСР) Delphi. Цикл может использоваться в лабораторном практикуме по дисциплинам: "Программирование на языках высокого уровня" (специальность 220400), "Языки программирования" (специальность 071900), "Информатика и программирование" (специальность 351400), "Высокоуровневые методы информатики и программирования" (специальность 351400). Рекомендуемая литература: Основная: 1. Культин Н. Delphi 7. Основы программирования в Delphi 7. – СПб.: БХВ-Петербург, 2003. 2. Кандзюба С. Delphi 6/7. Базы данных и приложения. - К: ДиаСофт, 2002. 3. Фаронов В. Delphi 7. Учебный курс. – М.: Нолидж, 2003. 4. Карпов Б. Delphi: Специальный справочник. – СПб.: Питер, 2001. Дополнительная: 1. Гофман В. и др. Delphi 6. – СПб.: БХВ, 2001. 2. Кэнту М. Delphi 5 для профессионалов. – СПб.: Питер, 2001. Содержание отчета: 1. Название работы, цель работы, задание в соответствии с вариантом. 2. Блок-схем алгоритма в соответствии с номером варианта. 3. Коды программы. 4. Результаты выполнения программы на ПК. 5. Выводы. Сохранение кодов Каждый студент должен на локальной машине в папке D:\Users\Temp создать свою папку, в которой будут затем размещаться папки проектов. Коды программ каждому студенту рекомендуется сохранять в своей папке. ИСР Delphi для каждого проекта создает несколько файлов. Чтобы файлы разных проектов не перепутывались, следует для каждого проекта создавать свою папку с именем, содержащим номер работы и номер задания (например, папку 03_1 для задания 1 работы 3). Рекомендуется имена проектов выбирать со ссылкой на дисциплину, номер работы и номер задания (например, Prg_3_1 – проект для задания 1 работы 3 по программированию). Файлы проекта Prg_3_1 нужно сохранить в папке 03_1. Для приложений надо сохранять и файл модуля. Рекомендуется для него выбирать имя, как у проекта, с добавлением символа подчеркивания в конце. Для правильного обращения к файлам в консольных приложениях нужно использовать в именах папок только латиницу. Иерархия папок следующая: Диск С Дисциплина (например, Prg_YVU) Фамилия студента (например, Ivanov) Номер работы и задания (например, 03_1) Файлы проекта Prg_3_1. В этой папке на каждом занятии следует сохранять файлы проекта (одно задание лабораторной работы – один проект, одна папка). Рекомендуется при выполнении работы периодически сохранять незавершенные проекты в текущем состоянии, чтобы избежать потерь документов при сбоях. Методические указания МУ доступны в электронном виде. Иерархия папок с документацией следующая: Диск С Дисциплина (например, Prg_YVU) Методические указания Папка с файлами методических указаний. Рекомендуется на первом занятии скопировать файлы МУ с сервера на локальную машину. В случае изменения МУ содержимое папки с МУ на локальной машине следует обновлять с сервера. Кроме того, методические указания выложены в сети Internet на сервере кафедры ВТ ПГАТИ с именем www.pgativt.da.ru. Они находятся на Web-странице в папке «Методические руководства». Выполнение работ ИСР Delphi позволяет разрабатывать разные программы, они называются проектами. В лабораторном цикле создаются проекты двух типов: Консольное приложение (Console Application) - под операционную систему DOS с символьным интерфейсом. Приложение (Application) – под операционную систему Windows с графическим интерфейсом.
4
1. Интегрированная среда разработки Delphi Подготовка к работе По указанной литературе изучить: 1. Методику активизации интегрированной среды разработки (ИСР) Delphi. 2. Структуру главного меню и его пункты. 3. Опции выпадающих меню. Контрольные вопросы 1. Активизация ИСР и выход из среды. 2. Окна ИСР. 3. Назначение и содержание главного окна ИСР. 4. Окно Инспектора объектов 5. Окно Конструктора формы. 6. Окно Дерева объектов. 7. Окно Редактора кода. 8. Панели инструментов. 9. Палитра компонент. 10. Главное меню главного окна ИСР. Опции пунктов Файл, Правка, Поиск, Вид, Проект, Выполнить, Компоненты, База данных, Сервис, Окно, Помощь. 11. Отличия проектов Приложение, Приложение CLX и Консольное приложение. 12. Использование встроенного подсказчика. 13. Кодировки ANSI и ASCII. Зачем нужно преобразование кодировок в консольном приложении? Задание 1. Активизировать ИСР. Ознакомиться с окнами ИСР. 2. Создать проект консольного приложения Prg_1_1. Оно должно в символьном режиме выводить на экран фразу «Hello, World & Россия!». Для него использовать модуль RusTrans с функцией Rus, обеспечивающей перекодировку ANSI => ASCII для отображения кириллицы в консольном приложении. 3. Создать проект приложения Prg_1_2. Оно должно в графическом режиме при нажатии кнопки «Нажми» выводить на экран фразу «Hello World & Россия!». Пример выполнения Задание 1. Активизировать ИСР. Ознакомиться с окнами ИСР. При старте ИСР из Windows по соглашению создается заготовка проекта типа Приложение (Приложение – программа под Windows). Вид экрана при старте ИСР показан на рис. 1.1. На нем представлены: Главное окно вверху экрана. Окно Дерева объектов под главным окном слева вверху. Окно Инспектора объектов слева внизу. Окно Конструктора формы (пустая форма с именем Form1) под главным окном справа. Окно Редактора кода (позиционируется там же, где окно Конструктора формы, переключение клавишей F12). Это окно можно переместить, чтобы видеть одновременно и окно Конструктора формы (так сделано на рис. 1.1).
рис. 1.1. Окно ИСР в режиме Приложения Для Приложения код исполняемой программы находится в двух файлах: Файл проекта с расширением .dpr. Код проекта делается в ИСР автоматически, его не надо редактировать, по соглашению он не показывается. Его можно посмотреть, подключив модуль проекта командой Вид=>Модули, которая выводит окно выбора, в котором нужно выбрать модуль проекта. После этого в редакторе кода появиться закладка с именем проекта. Файл модуля формы с расширением .pas.
5
Главное окно ИСР расположено в верхней части экрана и имеет вид рис. 1.2. Окно содержит: строку заголовка с именем ИСР (Delphi 7) и именем проекта (по умолчанию Project1); под ним строка главного меню ИСР; ниже главного меню слева панели инструментов; справа от них палитра компонент со страницами с закладками; ниже палитра компонент.
рис. 1.2. Главное окно ИСР Панели инструментов содержат кнопки часто употребляемых команд для быстрого доступа (помещены в группы определенного функционального назначения): Панель Место размещения Имя Назначение Под строкой главного меню слева. Standard Стандартная View Вид Debug Отладка Custom Пользователь Component Palette Палитра Компоненты Под панелями. Desktops Настройки Список справа от панелей. Пункты главного меню главного окна ИСР. Пункт Назначение File Файл Работа с файлами. Edit Правка Редактирование. Search Поиск Поиск фрагментов. View Вид Выбор, что показывать. Project Проект Операции с проектом. Run Запуск Прогон и отладка. Component Компоненты Работа с компонентами. Database Базы Данных Работа с базами данных. Tools Инструменты Использование внешнего инструментария. Windows Окно Перечень окон для выбора фокуса. Help Помощь Контекстная. Окно Конструктора формы – стандартное окно Windows с координатной сеткой для согласованного размещения компонент внутри формы. Вид окна в начале работы приведен на Рис. 1.3.
Рис. 1.3. Окно конструктора формы Окно Дерева объектов. Обычно размещается вверху слева от окна Конструктора формы. Рекомендуется не заслонять окно другими окнами, так как оно часто требуется. Пример дан на рис. 1.4. Содержит: Заголовок. Панель инструментов. Список объектов формы в виде дерева. В начале конструирования формы там присутствует только сама форма с именем Form1. По мере заполнения формы компонентами дерево автоматически дополняется.
6
рис. 1.4 Окно Дерева объектов Окно Инспектора объектов обычно размещается слева внизу от окна Конструктора формы. Рекомендуется не заслонять окно другими окнами, так как оно часто требуется. Содержит: Заголовок. Под ним список объектов в форме с возможностью выбора Ниже описание выделенного в форме (или выбранного в списке) объекта. Описание объекта разделено на две страницы с закладками Свойства (Properties) и События (Events). Вид окна приведен на рис. 1.5 (слева - страница свойств, справа - страница событий).
рис. 1.5. Окно инспектора объектов Свойства отображаются в двух столбцах: слева имя свойства, справа значения свойства. Некоторые свойства представляются списками. Признак списка - символ (+) или (-) слева от имени. Свойства могут сортироваться по алфавиту или по категориям (как на рис. 1.5). При этом одно и то же свойство может повторяться в нескольких категориях. События также отображаются в двух столбцах: слева имя события, справа имя обработчика этого события (может выбираться из списка). Имена событий начинаются с префикса On (в переводе означает На), за которым следует имя события на английском языке. Редактор кода для Приложения. Переключаем окно Конструктора формы на окно Редактора кода клавишей F12. Если окна совмещены, то происходит смена видимого окна. Если же окна видны одновременно, то происходит просто передача фокуса управления. Код модуля формы размещается в окне Редактора кода, показанном на рис. 1.6. Обычно к нему слева "приклеивается" Проводник кода (Code Explorer), в котором в иерархической форме отображаются все объявления модуля (его можно отключить). Окно Редактора кода по соглашению имеет такие же размеры, как и окно Конструктора формы, и позиционируется там же для экономии места на экране.
7
рис. 1.6. Окно Редактора кода для Приложения В окне Редактора кода на рис. 1.6 показан код модуля формы. Его ИСР формирует автоматически. В тексте использовано синтаксическое выделение: Зарезервированные слова полужирным шрифтом. Комментарии курсивом синего цвета. Директивы компилятора зеленым цветом. Задание 2. Создать проект - Консольное приложение Prg_1_1. Оно должно выводить на экран фразу – Hello World & Россия! Создаем консольное приложение, выбирая его в диалоговом окне команды Файл=>Новый=>Другое. ИСР выводит окно выбора типа проекта, показанное на Рис. 1.7. В нем выбираем «Консольное». ИСР в окне Редактора кода формирует заготовку для проекта, показанную на рис. 1.8. Имя проекта по умолчанию содержит слово Project с номером в сеансе работы с ИСР. В консольном приложении формы (а значит и соответствующего ей модуля) нет, Инспектор объектов пустой, так как объектов в проекте нет. В заготовке программы проекта размещены: Директива {$APPTYPE CONSOLE}, которая предписывает компилятору создавать консольное приложение. Комментарий // Insert user code here (Вводите код пользователя здесь). В панели Проводника кода (на рис. 1.8 слева) указана ссылка на модуль SysUtils –системные утилиты. Этот модуль содержит наиболее часто употребляемые подпрограммы. Ссылку на него ИСР создает в строке uses автоматически.
Рис. 1.7. Окно выбора типа проекта
8
рис. 1.8. Окно Редактора кода для консольного приложения Код проекта (строки на языке Object Pascal) размещается в окне Редактора кода. Каркас кода формируется ИСР автоматически (эти строки не надо редактировать!!!). Пользователь добавляет в код строки, определяющие выполняемые проектом функции. Код проект сохраняем в папке 01_1. На Рис. 1.9 показано окно Редактора кода с кодом проекта.
Рис. 1.9. Код проекта задания 1 При запуске проекта получаем окно, показанное на Рис. 1.10 слева. Есть проблема – неправильное отображение букв кириллицы. Правильное отображение показано на этом же рисунке справа. Причина ошибки - консольное приложение создается в ИСР, где используется операционная система Windows с кодировкой ANSI, а исполняется под управлением операционной системы MS DOS, использующей кодировку ASCII. Для решения проблемы нужно делать перекодировку букв кириллицы из стандарта ANSI в стандарт ASCII. Для этого в проект Prg_1_1 добавим ссылку на модуль RusTrans с функцией Rus преобразования строк ANSI в ASCII.
Рис. 1.10. Окно проекта задания 1 при исполнении Код проекта после сделанных изменений показан на Рис. 1.11. В нем добавлена ссылка на модуль RusTrans, а в операторе вывода строка текста преобразуется функцией Rus. На Рис. 1.10 справа приведено окно работающего приложения с правильным отображением символов кириллицы.
9
Рис. 1.11. Код проекта задания 1 с модулем RusTrans Задание 3 Создать проект приложения Prg_1_2. Оно должно при нажатии кнопки «Нажми» выводить на экран фразу – Hello, World! Командой Файл => Новый => Приложение создаем новый проект Prg_1_2, файлы которого будем сохранять в папке 01_2. При этом ИСР автоматически в Редакторе кода создает заготовку модуля формы, включая в него в строке uses ссылки на подключаемые модули. Свойству caption (надпись) формы присвоим значение «Моя первая программа». В окне Конструктора формы размещаем два компонента: кнопку Button1 с надписью «Нажми!», метку Label1 для вывода текста. В разделе interface кода модуля формы ИСР автоматически добавляет эти компоненты. Окно Конструктора формы проекта на этапе конструирования показано на Рис. 1.12.
Рис. 1.12. Окно Конструктора формы проекта задания 2 Двойным щелчком левой кнопкой мыши по кнопке Button1 инициируем создание обработчика события нажатия этой кнопки. ИСР автоматически добавляет для обработчика в разделе interface заголовок, а в разделе implementation заготовку его кода. Курсор автоматически устанавливается в тело кода обработчика, куда необходимо занести исполняемые коды. Для нашего проекта это всего две команды: Label1.Caption:=’Hello, World & Россия!’; Button1.Visible:=false; Первая команда свойству caption (надпись) метки Lable1 присваивает значение строки для вывода сообщения на экран, вторая команда свойству visible (видимость) кнопки Button1 присваивает значение false (ложь), делая ее невидимой. При вводе кодов команд целесообразно использовать встроенный в ИСР подсказчик, который позволяет выбирать нужный член класса компонента из большого списка. После набора имени компонента и точки нужно сделать паузу. Появится окно списка членов класса (см. Рис. 1.13 для выбора свойства caption компонента Label1), в котором нужно выбрать нужный член и дважды щелкнуть по нему левой кнопкой мыши. Член класса переместится в код программы. После завершения ввода кодов нужно проект сохранить с заданным именем в созданной для него папке, используя команду Файл => Сохранить проект как. В диалоговом окне нужно выбрать нужную папку, задать имя и сохранить проект. Внимание! При первом сохранении проекта запись файлов в папку происходит в два этапа: Сначала сохраняется модуль формы проекта с расширением .pas. Для него рекомендуется имя Prg_1_2_. Затем сохраняется файл проекта с расширением .dpr. Для него рекомендуется имя Prg_1_2. При сохранении в папке проекта автоматически создается группа вспомогательных файлов, которые не надо удалять или редактировать.
10
Листинг модуля формы: unit Prg_1_2_; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Label1: TLabel; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin Label1.Caption:='Hello, World и Россия'; // Вывод текста Button1.Visible:=false; // Кнопка невидима end; end.
Рис. 1.13. Использование встроенного подсказчика Теперь программу можно запустить на исполнение командой «Запуск» (или клавишей F9, или кнопкой со стрелкой из палитры инструментов). Если при кодировании ошибок не было, то появится окно приложения, как в Конструкторе формы. При нажатии кнопки «Нажми», окно принимает вид Рис. 1.14.
11
Рис. 1.14. Окно формы проекта задания 2 при исполнении Если при кодировании допущены ошибки, то компиляция не происходит, в окне Редактора кода внизу выводится список обнаруженных синтаксических ошибок (логические ошибки компилятор не обнаруживает). Для каждой ошибки имеется описание. Для ошибки, помеченной стрелкой слева от кода, строка в коде выделяется цветом, как показано на Рис. 1.15. В данном примере обнаружен необъявленный идентификатор Hello. Причина - пропущены апострофы, обрамляющие текстовую строку. В результате компилятор рассматривает слово Hello не как часть строки, а как идентификатор, который в коде не определен. После исправления ошибки программу следует запустить повторно. При этом компиляция и сохранение файлов проекта произойдет автоматически. Проект приложения – это стандартная программа Windows, которая в качестве встроенного модуля использует модуль формы. При желании можно посмотреть код проекта, но редактировать его не надо. Для просмотра кода проекта нужно: Командой Вид => Модули вызвать окно со списком модулей проекта, в котором выбрать Prg_1_2. Теперь окно Редактора кода примет вид Рис. 1.16, в котором появляется страница с закладкой Prg_1_2, в которой размещен код проекта. Код проекта в строке uses содержит ссылки на модули Forms (стандартный, содержащий средства работы с окном формы) и Prg_1_2_ (модуль формы нашего приложения) со ссылкой на его исходник (файл Prg_1_2.pas). В исполняемой части проекта имеются 3 стандартные процедуры Windows: Application.Initialize – инициализация приложения, Application.CreateForm – создание формы, Application.Run – запуск формы на исполнение.
Рис. 1.15. Сообщения о синтаксических ошибках
12
Рис. 1.16. Код проекта задания 2 Выход из ИСР осуществляется стандартным для программ под Windows способом. Выводы 1. ИСР Delphi – интегрированная среда быстрой разработки приложений. 2. Приложение в Delphi создается в окне Конструктора формы путем размещения там готовых компонентов. 3. Иерархия компонентов формы отображается в Delphi в окне Дерева объектов. 4. Свойства компонентов отображаются в Delphi в окне Инспектора объектов. 5. Каркас кода проекта ИСР создает автоматически. 6. Пользователь добавляет в него функциональность, вводя коды, определяющие выполняемые действия. 7. При кодировании следует использовать встроенный в ИСР подсказчик. 8. ИСР позволяет создавать приложения под Windows и консольные приложения под DOS. 9. Для консольных приложений с выводом текста на русском языке необходима перекодировка символов ANSI в ASCII. Для этого в строку uses консольного приложения следует добавить ссылку на модуль RusTrans.
13
2. Структура программы и типы в языке Delphi Подготовка к работе 1. Изучить: Структуру программы на языке Delphi. Задание констант, переменных. Типы численных данных и ошибки при преобразованиях типов численных данных. Организацию простейшего ввода-вывода данных. 2. Составить программу решения задачи в виде консольного приложения. Контрольные вопросы 1. Алфавит языка Delphi, операции, идентификаторы. 2. Структура программы. Разделы объявления констант, переменных, меток, типов данных, подпрограмм 3. Константы. Их объявление. Константные выражения. 4. Переменные. Их объявление. 5. Форматы представления чисел (с фиксированной и плавающей точкой). 6. Типы целых чисел без знака: Byte, Word, LongWord = Cardinal. 7. Типы целых чисел со знаком: Shortint, Smallint, Integer = Longint, Int64. 8. Типы вещественных чисел: Single, Real48, Double = Real, Extended, Comp, Currency. 9. Тип TDateTime и его использование 10. Логические типы данных Boolean. 11. Символьные типы: AnsiChar = Char, WideChar. 12. Строковые типы для длинных строк: AnsiString = String, WideString. 13. Строковые типы для коротких строк: ShortString, String[N]. 14. Совместимость типов при присвоениях. 15. Тип Variant и его использование. Задание 1. Создать программу взаимных преобразований типов численных данных в соответствии с вариантами, приведенными в табл. 2.1. Нужно преобразовывать численные данные из типа Start в типы Fin1 и Fin2 для вещественных и целых чисел. 2. Создать программу взаимных преобразований строковых и символьных типов. Она должна отображать фамилию студента строками разного типа и добавлять к строке символ. 3. Создать программу работы с типом TDateTime. Она должна запрашивать дату и время рождения студента, выводить текущие дату/время, запрашивать желаемое время дальнейшего обучения, выводить дату/время и день недели конца обучения. табл. 2.1. Варианты заданий Типы вещественных чисел Типы целых чисел № Start Fin_1 Fin_2 Fin_3 Start Fin_1 Fin_2 Fin_3 1 Single Currency Extended Real48 Byte Cardinal Integer Smallint 2 Real48 Single Currency Double Word Byte Cardinal Integer 3 Double Real48 Single Real LongWord Word Byte LongInt 4 Real Double Real48 Single Cardinal LongWord Word Byte 5 Extended Real Double Real48 Shortint Cardinal LongWord Word 6 Comp Extended Real Double Smallint Shortint Cardinal LongWord 7 Currency Comp Extended Real Integer Smallint Shortint Cardinal 8 Single Currency Comp Extended LongInt Integer Smallint Shortint 9 Real48 Single Currency Comp Int64 LongInt Integer Smallint 10 Double Real48 Single Currency Word Int64 LongInt Integer 11 Real Double Real48 Single LongWord Byte Int64 LongInt 12 Extended Real Double Real48 Cardinal Word Int64 Int64 13 Comp Extended Real Double Shortint LongWord Byte Word 14 Currency Comp Extended Real Smallint Cardinal Word LongWord 15 Real Currency Comp Extended Integer Shortint LongWord Cardinal Пример выполнения Задание 1. Создать программу преобразования численных данных из типа Start в типы Fin1, Fin2 и Fin3: 1. Для вещественных чисел: Start = Real, Fin1 = Extended, Fin2 = Single, Fin3 = Currency. 2. Для целых чисел: Start = Smallint, Fin1 = Cardinal, Fin2 = Longint, Fin3 = Byte. Для контроля размеров данных в программе используется встроенная функция SizeOf, возвращающая размер аргумента в байтах. Каждый раз данные выводятся в виде значения, размера в байтах и типа данных. Числа для наглядности
14
отображаются в формате с фиксированной точкой. При этом задается число позиций под выводимое значение, что позволяет позиционировать выводимые данные в строке. Листинг программы program Prg_2_1; {$APPTYPE CONSOLE} uses SysUtils,RusTrans; const real_0:real=123.456789; int_0:smallint=-1111; var real_1:extended; real_2:single; real_3:currency; int_1:cardinal; int_2:longint; int_3:byte; begin writeln(Rus('Вещественное число в разных типах')); writeln; real_1:=real_0; real_2:=real_0; real_3:=real_0; writeln(Rus('Значения и размер в байтах в разных типах')); writeln('real_0=',real_0:10:6,sizeof(real_0):4,' real'); writeln('real_1=',real_1:10:6,sizeof(real_1):4,' extended'); writeln('real_2=',real_2:10:6,sizeof(real_2):4,' single'); writeln('real_3=',real_3:10:6,sizeof(real_3):4,' currency'); readln; writeln(Rus('Целое число в разных типах')); int_1:=int_0; int_2:=int_0; writeln; writeln(Rus('Значения и размер в байтах в разных типах')); writeln('int_0=',int_0:10,sizeof(int_0):4,' smallint'); writeln('int_1=',int_1:10,sizeof(int_1):4,' cardinal'); writeln('int_2=',int_2:10,sizeof(int_2):4,' longint'); writeln('int_3=',int_3:10,sizeof(int_3):4,' byte'); readln; end. В листинге программы в разделе констант const объявлены, как типизированные константы, стартовые числа Start. В разделе var объявлены группы переменных Fin1, Fin2, Fin3 для каждого вида чисел. На рис. 2.1 показан вид окна консольного приложения перед закрытием программы.
рис. 2.1. Окно задания 1 при выполнении Задание 2 Создать программу взаимных преобразований строковых и символьных типов. Она должна отображать слово World строками разного типа и добавлять к строке символ восклицательного знака !.
15
Листинг программы program Prg_2_2; {$APPTYPE CONSOLE} uses SysUtils, RusTrans; var Str_1:string; Str_2:string[10]; ShortStr:ShortString; AnsiStr:AnsiString; WideStr:WideString; MyChar:char; begin Str_1:='World'; writeln(Rus('Строки в разных типах')); writeln; Str_2:=Str_1; ShortStr:=Str_1; AnsiStr:=Str_1; WideStr:=Str_1; writeln(Rus('Значения и размер в байтах в разных типах')); writeln; writeln('AnsiStr =',AnsiStr:7,SizeOf(AnsiStr):5,' AnsiString'); writeln('Str_1 =',Str_1:9,SizeOf(Str_1):5,' String'); writeln('WideStr =',WideStr:7,SizeOf(WideStr):5,' WideString'); writeln('ShortStr =',ShortStr:6,SizeOf(ShortStr):5,' ShortString'); writeln('Str_2 =',Str_2:9,SizeOf(Str_2):5,' String[..]'); readln; writeln(Rus('Добавим к строке символ !')); writeln; MyChar:='!'; Str_2:=Str_2+MyChar; writeln('Str_2 =',Str_2:9,SizeOf(Str_2):5,' String[..]'); readln; end.
Рис. 2.2. Окно задания 2 при выполнении Задание 3 Создать программу работы с типом TDateTime. Она должна запрашивать дату и время рождения, выводить текущие дату/время, запрашивать желаемое время обучения, выводить дату/время и день недели конца обучения. На Рис. 2.3 показано окно работающего приложения задания 3. Листинг программы program Prg_2_3; {$APPTYPE CONSOLE} uses SysUtils, RusTrans; var Date_1,Date_2,Time,DateTime:string; DateTime_1,DateTime_2:TDateTime; Day:integer; begin
16
writeln(Rus('Введите дату рождения в формате день.месяц.год')); readln(Date_1); writeln; writeln(Rus('Введите время рождения в формате часы.минуты.секунды')); readln(Time); writeln; DateTime:=Date_1+Time; DateTime_1:=StrToDateTime(DateTime); DateTime_2:=Now; writeln(Rus('Сегодня '),DateTimeToStr(Now)); writeln; writeln(Rus('Сколько дней еще хотите учиться?')); readln(Day); writeln; DateTime_2:=DateTime_2+Day; Day:=DayOfWeek(DateTime_2); writeln(Rus('Вы станете совсем умным '),DateToStr(DateTime_2)); writeln(Rus('Это будет день недели номер '),Day); readln; end.
Рис. 2.3. Окно задания 3 при выполнении Выводы 1. Программа на языке Delphi имеет следующую структуру: Заголовок. Разделы объявлений констант, переменных, типов, меток, подпрограмм (процедур и функций). Раздел операторов, помещенный в операторные скобки begin…end. Точка, как признак конца программы. 2. Для чисел возможны типы: вещественные, целые без знака и со знаком, 16-ричные. 3. Вещественные числа запоминаются в формате с плавающей точкой. Для них лучше всего использовать тип real. При переходе к типу с меньшим размером теряется точность. При использовании типов с максимальными размерами потребная память увеличивается, но точность может не измениться. Для округления результатов используются типы вещественных чисел с ограниченной дробной частью: comp (0 разрядов) и currency (4 разрядов). 4. Целые числа запоминаются в формате с фиксированной точкой. Для них лучше всего использовать тип integer. При переходе к типу с меньшим размером возможна грубая ошибка, если число не умещается в отведенную под него память. Целые числа без знака целесообразно использовать для уменьшения занимаемой памяти. 5. Для работы с короткими строками используются типы ShortString, String [N до 255]. Это область в статической памяти, назначаемая при компиляции программы. 6. Для работы с длинными строками используются типы String, AnsiString, WideString. Это указатели размером 4 байта, в которые помещается адрес начала строки в динамической памяти, назначаемый при исполнении программы. 7. Операция + со строками выполняет конкатенацию (присоединение в конец) строк или символов. 8. Для работы с датой и временем определен тип TDateTime. Он в формате вещественного числа содержит и дату (целая часть - число суток, прошедших с 30.12.1899) и время (дробная часть - часть суток, прошедших с 0 часов). Тип позволяет выполнять с датой/временем операции, как с вещественными числами.
17
3. Линейные структуры Подготовка к работе 1. Изучить: Запись констант, переменных, стандартных функций. Правила записи арифметических выражений. Арифметический оператор присваивания. 2. Разработать алгоритм решения в соответствии с заданием. 3. Составить программу решения задачи в виде консольного приложения. Контрольные вопросы 1. Алфавит языка Delphi. 2. Операции. 3. Идентификаторы. 4. Типы данных. 5. Структура программы консольного приложения. 6. Где описываются константы, переменные, метки и типы данных? 7. Стандартные функции. 8. Оператор присваивания. 9. Пустой и составной операторы. 10. Процедуры ввода read и readln. 11. Процедуры вывода write и writeln. 12. Последовательность действий при выполнении оператора присваивания. 13. Приоритетность выполнения операций в выражениях. 14. Как организовать пропуск одной, двух строк при выводе? Задание 1. Вычислить значения переменных в соответствии с вариантами задания, приведенными в табл. 3.1. Вывести значения вводимых исходных данных и результаты, сопровождая их вывод именами выводимых переменных. Задание выполнить в виде консольного приложения. 2. Повторить задание 1, используя функции из модуля math. табл. 3.1. Варианты заданий № Расчетные формулы Данные x = 1.82 y = 18 1 z y− z = -3.29
s = xy/x − 2
s = 1+ x +
y y−x ; w = (y − x) 2 x 1 + (y − x)
x2 x3 x4 + + ; w = x (sin x + cos y ) 2! 3! 4!
(
x = 0.33 y = 0.02
)
3
y = e−bt sin(at + b) − bt + a ; s = b sin at2 cos(at) −1
4
b 2 sin3 (x + a) w= x +b − ; y = cos2 ( x 3 ) − x / a 2 + b 2 x a bx 2 − a 2 s = x 3tg 2 (( x + b ) ) + ; g = ax e −1 x+b
5 6 7 8 9
2
r=
x 2 ( x + 1) − sin 2 ( x + a ); s = b
(
)
2
y = sin 3 ( x 2 + a ) −
y = b ⋅ tg 2 x −
(
xb 3 + cos(( x + b ) ) a
x2 x 3 ; z= + cos(( x + b ) ) a b
a ; d =a⋅e sin ( x / a ) 2
)
a
⋅ cos(bx / a )
f = ln a + x 2 + sin 2 ( x / b ); z = e −cx ⋅
x+ x+a x − ln( x − b )
a = -0.5 b = 1.7 t = 0.44 a = -0.5 b = 15.5 x = -2.9 a = 16.5 b = 3.4 x = 0.61 a = 0.7 b = 0.05 x = 0.5 a = 1.1 b = 0.04 x = 0.2 a = 3.2 b = 17.5 x = -4.8 a = 10.2 x = 2.2 b = 9.2 c = 0.5
18
10 11 12 13 14
15
a 2 x + b − x ⋅ cos((a + b)x) 2 2 ; r = x + b − b sin( x + a) / x x +1
a = 0.3 b = 0.9 x = 0.61
z = ax ⋅ sin(2x) + e−2x ( x + b); w = cos2 (x3 ) − x / a 2 + b2 b bx − a s = x ⋅ ctg 2 ( x − a) + ; w = a− x e −1 x+b −x 2 a x + e cos(bx) u= ; f = e 2 x ln(a + x ) − b 3 x ln(b − x ) −x bx − e sin(bx) + 1
a = 0.5 b = 3.1 x = 1.4 a = 16.5 b = 3.4 x = 0.61
π 2 cos x − b a = ; 2 1 / 2 + sin ( y )
x = 1.42 y = -1.27 z = 3.5
y=
b =1+
2
z 3+ z2 /5
sin x
s = e −ax x + 1 + e −bx x + 1,5; z =
a = 0.5 b = 2.9 x = 0.3
1 + m2 sin2 x
m = 0.7 x = 1.7
− cm ⋅ ln(mx)
c = 2.1 a = 0.5
Пример выполнения Задание 1 Вычислить при x = 2.1, y = 0.59, z = -4.8 значения a и b, используя формулы:
a = y ⋅ tg ( x ) + 3
2
z2 ; y2 + x2
(
)
b = ln y + x 2 + sin 2 ( z / x)
Блок-схема алгоритма представлена на рис. 3.1. Начало Расчет a, b
4
Ввод x, y, z
1
Вывод a, b Вывод x, y, z
2
Ожидание Enter 3
5
6
Верно? Нет
Да
Конец
рис. 3.1 Блок-схема алгоритма В блоке 1 исходные данные вводятся, в блоке 2 осуществляется их контрольный вывод. В блоке 3 пользователь проверяет правильность введенных данных, при ошибке ввод повторяется. Если данные верные, то в блоке 4 функции вычисляются, а в блоке 5 их значения выводятся. Блок 6 обеспечивает паузу в исполнении программы, чтобы пользователь мог увидеть результат. На рис. 3.2 приведено окно работающего приложения. Листинг программы program Prg_3_1; {$APPTYPE CONSOLE} uses SysUtils,RusTrans; label 10; var a,b,c,x,y,z: real; proba:integer; begin 10: writeln(Rus('Введите x,y,z'));
19
readln(x,y,z); writeln; writeln(Rus('Вы ввели')); writeln('x=',x:8:3,' y=',y:8:3,' z=',z:8:3); writeln; writeln(Rus('Введите 1, если отображенные данные совпадают с заданными')); readln(proba); if proba1 then begin writeln; goto 10; end; writeln; c:=sin(x*x)/cos(x*x); a:=y*c*sqr(c)+sqrt(z*z/(y*y+x*x)); b:=ln(y+x*x)+sqr(sin(z/y)); writeln(Rus('Результат')); writeln('a=',a:8:3,' b=',b:8:3); readLn; end.
рис. 3.2. Окно работающего приложения Задание 2 Повторить задание 1, используя функции из модуля math. В листинг добавляем ссылку на модуль math, что позволяет использовать прямо функцию тангенса tan(аргумент) и возведения в степень power(основание, степень). Окно работающего приложения имеет такой же вид, как в задании 1. Листинг программы program Prg_3_2; {$APPTYPE CONSOLE} uses SysUtils,RusTrans,math; label 10; var a,b,c,x,y,z: real; proba:integer; begin 10: writeln(Rus('Введите x,y,z')); readln(x,y,z); writeln; writeln(Rus('Вы ввели'));
20
writeln('x=',x:8:3,' y=',y:8:3,' z=',z:8:3); writeln; writeln(Rus('Введите 1, если отображенные данные совпадают с заданными')); readln(proba); if proba1 then begin writeln; goto 10; end; writeln; c:=tan(x*x); a:=y*power(c,3)+sqrt(z*z/(y*y+x*x)); b:=ln(y+x*x)+sqr(sin(z/y)); writeln(Rus('Результат')); writeln('a=',a:8:3,' b=',b:8:3); readLn; end. Выводы 1. Консольное приложение – программа под DOS. Проект – программа. Используется единственное окно. Ввод/вывод осуществляется процедурами read, readln, write и writeln. 2. Программа с линейной структурой содержит операторы, завершаемые символом «точка с запятой». Рекомендуется один оператор в строке. 3. Выражения используются для нахождения новых значений переменных. В выражениях можно использовать стандартные математические функции. Основные функции определены в модуле SysUtils. 4. Дополнительные математические функции определены в модуле math. Чтобы они были доступны, нужно включить модуль math в строку uses кода программы. 5. Для безусловного перехода можно использовать оператор goto metka, который передает управление помеченному оператору. Метка должна быть предварительно описана в разделе объявления меток label. В исполняемой части программы метка размещается слева от оператора, за именем метки следует вертикальное двоеточие. 6. Несколько операторов можно объединить в один составной, поместив их в операторные скобки begin…end. 7. Рекомендуется вводить в программу комментарии. Это либо текст до конца строки после символов //, либо несколько строк, помещенных в фигурные скобки. В листинге программы комментарий по умолчанию отображается курсивом.
21
4. Структуры с ветвлениями Подготовка к работе 1. Изучить возможности языка программирования для реализации: условной и безусловной передачи управления; вычислительного процесса с разветвляющейся структурой. 2. Разработать алгоритм решения в соответствии с заданием. 3. Составить программы решения задач. Контрольные вопросы 1. Какие структуры вычислительных процессов Вы знаете? 2. Как организовать разветвление вычислений? 3. Условный оператор if...then...else. 4. Условный оператор if...then. 5. Вложенные условные операторы. 6. Оператор выбора case …of. 7. Зачем нужно при отладке программы тестировать все ветви алгоритма? Задания к работе 1. Вычислить значения функции по варианту задания из табл. 4.1. Вывести значения исходных данных и полученные результаты, сопровождая их именами переменных. Значения аргумента взять из указанного диапазона так, чтобы протестировать все ветви программы. Проект – консольное приложение. 2. Вывести сообщения для дней недели с использованием оператора выбора. Проект – консольное приложение. табл. 4.1. Варианты заданий № Функции и условия Данные Диапазон аргумента a = -0.5 t = [0 .. 3] 1 1⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ t 〈1 b = 2 шаг 0.25
2
y = at 2 ln t ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅1 ≤ t ≤ 2 e at cos bt ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ t 〉 2 πx 2 − 7 / x 2 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〈1.3 y = ax3 + 7 x ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅при ⋅ ⋅ ⋅ x = 1.3 tg x + 7 x ⋅ ⋅ ⋅ ⋅ ⋅ ⋅при ⋅ ⋅ ⋅ x〉1.3
(
3
4
5
6
a = 1.5
x = [0.8 .. 2.8] шаг 0.25
a = 2.8 b = -0.3 c=4
x = [1 .. 2] шаг 0.25
a = 1.65 b = 1.1
x = [0.5 .. 2] шаг 0.25
a = 2.3
x = [0.2 .. 3] шаг 0.4
a = 2.5
x =[1 .. 2.5] шаг 0.25
)
ax 2 + bx + c ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〈1.2 y = a / x + x 2 − 1 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x = 1.2 2 (a + bx ) / x + 1 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〉1.2 πx 2 − 7 / x 2 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〈1.4 y = ax 3 + 7 x 2 − 1 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x = 1.4 2 (a + bx ) / x + 1 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〉1.4 1.5 cos 2 x ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x ≤ 1 2 y = ( x − 2 ) + 6 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅1〈 x〈 2 3tgx ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〉 2 x x − a ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〉 a y = e − ax sin( ax) ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〈 a x ⋅ sin(ax) ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x = a
22
7
bx − lg bx ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ bx〈1 q = 1 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ bx = 1 bx + ln bx ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ bx〉1
8
sin(ln x) ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〉 3.5 q= 2 cos x ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x ≤ 3.5 ln( x + 1) ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〉1 f = 2 sin ( ax ) ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x ≤ 1
9
b = 1.5
x = [0.5 .. 3] шаг 0.25
x = [2 .. 5] шаг 0.25 a = 20.3
x = [0.5 .. 2] шаг 0.25
10
a ⋅ ln x + x ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〉1 y= 2a ⋅ cos x + 3 x 2 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x ≤ 1
a = 0.9
x = [0.5 .. 2] шаг 0.5
11
ln 2 ( x) + x 2 / x + 1 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〈0.5 z = x + t + 1 / x ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x = 0.5 2 cos x + t ⋅ sin x ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〉 0.5
t = 2.2
x = [0 .. 2] шаг 0.25
12
a+b e x + cos x ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〈 2.8 u = (a + b ) / ( x + 1) ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ 2.8 ≤ x ≤ 5 e x + sin x ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ x〉5 a 2 i + bi + c ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ i 〈 4 w = i ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ 4 ≤ i ≤ 6 ai + bi 2 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ i〉 6
a = 2.6 b = -0.39
x = [0 .. 6] шаг 1
a = 2.1 b = 1.8 c = -20.5
i = [0 .. 8] шаг 1
14
i2 + 1 i2 + 1 〉 0 a при ⋅ sin sin ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ n n y= i2 + 1 cos(i + 1 / n ) ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ sin 〈 0 n
a = 2.5 n = 10
i = [1 .. 2.5] шаг 0.25
15
at 2 + b ⋅ sin t + 1 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ t 〈 0.1 w = at + b ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ t = 0.1 2 at + b ⋅ cos t + 1 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ t 〉 0.1
a = 2.5 b = 0.4
t = [-1 .. 1] шаг 0.2
13
(
)
Пример выполнения Задание 1 Вычислить при y=1.3, x=[0.. 2.1] с шагом 0.3 значения функции a. Результат вывести в виде таблицы. Проект – консольное приложение.
yx + 1 ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ yx〈1 a = cos( yx) ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ yx = 1 e − yx cos( yx) ⋅ ⋅ ⋅ при ⋅ ⋅ ⋅ yx〉1 Блок-схема алгоритма представлена на рис. 4.1. Для организации цикла введены следующие переменные: xs - начальное значение, xk - конечное значение dx - шаг изменения аргумента x. Окно работающего приложения показано на Рис. 4.2.
23
Начало
Ввод y, xs, xk, dx
1
Заголовок
2
x=xs
3
Нет
4
6 y*x>1?
y*x Prg_12_1. 2.
3.
Заполнение формы При заполнении формы в палитре компонент выбирается нужный блок и переносится в форму. Там подбираются его положение и размеры. Затем в окне Инспектора объектов назначаются свойства компонента. Большая часть свойств устанавливается автоматически, их редактировать не следует. Нужные нам компоненты размещаются в палитре компонент на странице Standard. Для кнопок необходимо добавить функциональность, написав код обработчика события нажатия. При двойном щелчке по кнопке ИСР автоматически объявляет подпрограмму обработчика. В код модуля формы проекта заносятся: 1. В поля объекта заголовок обработчика. Заголовок обработчика формируется автоматически. Его имя содержит записанные без пробелов имя компонента и события с префиксом on, которое отрабатывается. 2. В раздел реализации шаблон обработчика. Он имеет заголовок, совпадающий с заголовком в поле объекта с добавлением имени формы в начале заголовка. В него между операторными скобками begin…end надо внести текст подпрограммы обработки события. Для некоторых обработчиков могут потребоваться и локальные переменные.
59
Листинг модуля формы: unit Prg_12_1_; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TPrg_12_1 = class(TForm) ListBox1: TListBox; ComboBox1: TComboBox; Button1: TButton; Edit1: TEdit; Button2: TButton; Label1: TLabel; Label2: TLabel; Label3: TLabel; Button3: TButton; Button4: TButton; procedure Button1Click(Sender: procedure Button2Click(Sender: procedure Button3Click(Sender: procedure Button4Click(Sender: private { Private declarations } public { Public declarations } end;
TObject); TObject); TObject); TObject);
var Prg_12__1: TPrg_12__1; implementation {$R *.dfm} procedure TPrg_12_1.Button1Click(Sender: TObject); begin Edit1.Text:=''; Edit1.SetFocus; end; procedure TPrg_12_1.Button2Click(Sender: TObject); begin ComboBox1.Items.Add(Edit1.Text); Edit1.Text:=''; Edit1.SetFocus; end; procedure TPrg_12_1.Button3Click(Sender: TObject); begin ComboBox1.Items.Insert(comboBox1.ItemIndex,Edit1.Text); Edit1.Text:=''; Edit1.SetFocus; end; procedure TPrg_12_1.Button4Click(Sender: TObject); begin ListBox1.Items.Add(ComboBox1.Items[ComboBox1.ItemIndex]); end;
60
end. После заполнения панелей компонентами форма примет вид рис. 12.1. Окно Дерево объектов приобретает вид, показанный на рис. 12.3. Проверьте по нему правильность введенных компонент, их имена и иерархию.
рис. 12.3 Дерево объектов после заполнения формы компонентами Сохраним проект в папке с именем 12_1. Для этого вызовем команду Файл => Сохранить Проект Как, которая приводит к появлению диалогового окна. В нем нужно попасть в нужную папку и сохранить проект. При сохранении проекта приложения необходимо сохранять проект (с именем Prg_12_1) и модуль формы (с именем Prg_12_1_). 5. Проверим программу в работе. Запускаем программу командой Выполнить. Возникает окно приложения. Инициализация. Кнопкой Инициализация очищаем Edit1 и передаем ему фокус ввода. Курсор появляется в поле ввода Edit1. Заполнение списка ComboBox. Для каждой строки в редакторе Edit1 заносим текст, кнопкой Принять в ComboBox переносим его в список. Повторяем операцию нужное число раз. Каждый раз проверяем список ComboBox, убеждаясь в появлении новой строки в конце. Редактирование. В редакторе Edit1 заносим строку текста для ввода в произвольно выбираемую позицию. В ComboBox выделяем позицию для ввода, ее текст перемещается в верхнюю строку редактирования. Копирование. В ComboBox выделяем позицию для копирования, ее текст перемещается в верхнюю строку редактирования. Кнопкой Копировать в ListBox переносим строку в ListBox. Каждый раз наблюдаем ListBox, чтобы убедится в появлении там новой строки в очередной позиции. Выводы 1. Списки используются для выбора элементов из большого набора. 2. В ИСР Delphi определены несколько компонент списков: ListBox - простой список строк текста для выбора без редактирования. ComboBox - комбинированный список строк текста с возможностью выбора и редактирования. ComboBoxEx - расширенный комбинированный список строк с отображением в строках текста и значков. 3. Все списки содержат массив строк текста, для которых применяются свойства: Items(Index) - массив строк текста с номером Index. Нумерация с 0. ItemIdent - номер выделенного элемента. Count - число элементов в списке. Capacity - максимальное число элементов в списке. 4. Для работы со списками доступны методы: Add - добавляет элемент в конец списка. Insert(Index,Item) - добавляет элемент Item в позицию с номером Index. Список переиндексируется. Delete (Index) - удаляет элемент с номером Index. Список переиндексируется. Clear - очищает список. Делает Count=0, Capacity=0. Exchange(Index1, Index2) - меняет местами элементы с номерами Index1 и Index2. Move(CurIndex, NewIndex) - перемещает элемент из текущей позиции CurIndex в новую позицию NewIndex. 5. Список ComboBox может отображаться в полной и краткой формах. В первом случае отображаются строка редактирования и список для выбора. Во втором случае список выбора выпадающий, отображается по требованию. 4.
61
13. Модули Подготовка к работе 1. По рекомендованной литературе изучить назначение и использование модулей и DLL (Dynamic Linked Library = динамически связываемая библиотека); 2. Разработать алгоритмы решения задач. 3. Составить программы решения задач. Контрольные вопросы 1. Что такое модуль? Его назначение и создание. 2. Структура модуля. 3. Назначение и содержание секций Interface, Implementation, Initialization, Finalization. 4. Связывание модуля с вызывающей программой. 5. Что такое DLL? Ее назначение и создание. 6. Структура DLL. 7. Экспортируемые и внутренние подпрограммы DLL. 8. Назначение и содержание списка Exports. 9. Связывание DLL с вызывающей программой. 10. Способы вызова подпрограмм из DLL. Задание к работе 1. Создать вызывающую программу, использующую модуль комплексной арифметики Complex, содержащий 4 функции: сложение, вычитание, умножение и деление. Вызывающая программа должна выполнить функцию 1 с комплексными операндами Comp1=a + i*b и Comp2=c + i*d b и функцию деления Comp1 на ноль. Варианты заданий в табл. 13.1. Проект – приложение. 2. Повторить задание 1, реализовав модуль в виде DLL Complex2. Проект – приложение. табл. 13.1. Варианты заданий № a b c d Функция 1 1 1 2 3 4 Сложение 2 5 6 7 8 Вычитание 3 9 10 11 12 Умножение 4 4 1 2 3 Сложение 5 8 5 6 7 Вычитание 6 12 9 10 11 Умножение 7 3 8 1 2 Сложение 8 7 14 5 6 Вычитание 9 11 12 9 10 Умножение 10 2 3 4 1 Сложение 11 6 7 8 5 Вычитание 12 10 11 12 9 Умножение 13 4 1 3 12 Сложение 14 8 5 7 10 Вычитание 15 12 9 11 68 Умножение Пример выполнения Задание 1 Создать вызывающую программу, использующую модуль комплексной арифметики Complex, содержащий 4 функции: сложение, вычитание, умножение и деление. Вызывающая программа должна выполнить функцию сложения с комплексными операндами Comp1=6 + i*8 и Comp2=7 + i*11 функцию деления Op1 на ноль. 1. Командой File=>New вызываем окно архива и выбираем в нем Unit (модуль без формы). Получаем в окне Редактора кода страницу шаблона модуля с именем Unit1. 2. В редакторе кода заносим код модуля. Секции Initialization и Finalization не используем. 3. Сохраним модуль с именем Complex.Pas. 4. Компилируем модуль. 5. Командой Файл => Создать => Приложение создаем проект вызывающей программы. Форма приложения приведена на рис. 13.1.
62
рис. 13.1. Форма вызывающей программы Форма содержит: Метки Label1…Label6 для отображения поясняющих надписей. Однострочные редакторы Edit1…Edit4 для ввода значений переменных a, b, c, d. Многострочный редактор Memo1 для вывода результатов. Кнопки BitBtn1…BitBtn4 с именами Ввод, Выполнить, Очистить, Закрыть. Кнопка Ввод принимает значения введенных переменных, Копка Выполнить осуществляет вычисления и выводит результаты. Кнопка Очистить удаляет содержимое поля результатов, Кнопка Закрыть завершает работу программы (дублирует стандартную кнопку закрытия окна Windows). 6. В коде модуля формы вызывающей программы добавляем: В строку uses ссылку на модуль Complex. В раздел var переменные a,b,c,d типа real и Comp1, Comp2, Comp3 типа TComplex. 7. Создаем обработчики нажатия кнопок. 8. Сохраняем проект под именем Prg_13_1. Листинг модуля Complex: unit Complex; interface type TComplex = Record Re, Im: Real end; function AddC(x,y: TComplex):TComplex; function SubC(x,y: TComplex):TComplex; function MultC(x,y: TComplex):TComplex; function DivC(x,y: TComplex):TComplex; implementation function AddC(x,y: TComplex):TComplex; begin Result.Re:=x.Re + y.Re; Result.Im:=x.Im + y.Im; end; //AddC function SubC(x,y: TComplex):TComplex; begin Result.Re:=x.Re - y.Re; Result.Im:=x.Im - y.Im; end; //SubC function MultC(x,y: TComplex):TComplex; begin Result.Re:=x.Re*y.Re - x.Im*y.Im; Result.Im:=x.Re*y.Im + x.Im*y.Re;
// Комплексная арифметика // Тип комплексного числа // // // //
Комплексное Комплексное Комплексное Комплексное
сложение вычитание умножение деление
63
end; {MultC} function DivC(x,y: TComplex):TComplex; var z: Real; begin z:=sqr(y.Re)+sqr(y.Im); try //Защита при делении на 0 Result.Re:=(x.Re*y.Re + x.Im*y.Im)/z; Result.Im:=(x.Re*y.Im - x.Im*y.Re)/z; except // Если делитель 0, то. Result.Re:=1.1e309; Result.Im:=1.1e309 end; end; {DivC} end. Листинг модуля формы вызывающей программы: unit Prg_13_1_; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ExtCtrls, Complex; type TForm1 = class(TForm) bbRun: TBitBtn; // Кнопка Выполнить bbClose: TBitBtn; // Кнопка Закрыть bbVvod: TBitBtn; // Кнопка Ввод bbClear: TBitBtn; // Кнопка Очистить Edit1: TEdit; // для a Edit2: TEdit; // для b Edit3: TEdit; // для c Edit4: TEdit; // для d Label1: TLabel; // Введите значения переменных Label2: TLabel; // a = Label3: TLabel; // b = Label4: TLabel; // c = Label5: TLabel; // d = Label6: TLabel; // Результаты Memo1: TMemo; procedure bbRunClick(Sender: TObject); procedure bbVvodClick(Sender: TObject); procedure bbClearClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; a,b,c,d: real; Comp1, Comp2, Comp3:TComplex; implementation {$R *.DFM} procedure TForm1.bbRunClick(Sender: TObject); begin Comp1.Re:=a; Comp1.Im:=b; Comp2.Re:=c; Comp2.Im:=d; Comp3:=AddC(Comp1,Comp2); memo1.Lines.Add('Исходные данные'); memo1.Lines.Add('Comp1='+FloatToStr(Comp1.Re)+’+i*'+FloatToStr(Comp1.Im)); memo1.Lines.Add('Comp2='+FloatToStr(Comp2.Re)+'+i*'+FloatToStr(Comp2.Im)); memo1.Lines.Add(''); memo1.Lines.Add('Результат комплексной операции’); memo1.Lines.Add('Comp3='+FloatToStr(Comp3.Re)+'+i*'+FloatToStr(Comp3.Im)); end;
64
procedure TForm1.bbVvodClick(Sender: TObject); begin a:=StrToFloat(Edit1.Text); b:=StrToFloat(Edit2.Text); c:=StrToFloat(Edit3.Text); d:=StrToFloat(Edit4.Text); end; procedure TForm1.bbClearClick(Sender: TObject); begin memo1.Clear; end; end. Задание 2 Повторить задание 1, реализовав модуль в виде DLL Complex2. Проект – приложение. 1. Командой Файл => Создать => Еще вызываем окно архива и выбираем в нем DLL. Получаем в окне Редактора кода страницу шаблона DLL с именем Project1. 2. В редакторе кода заносим в нее код DLL. Подпрограммы те же, что в модуле Complex задания 1. Секция begin…end – пустая. 3. Сохраним DLL с именем Complex2.Pas. 4. Компилируем DLL. Итог Complex2.dll. 5. Так как DLL не экспортирует типов, то создаем вспомогательный модуль Complex1, содержащий только интерфейсную часть с описанием типа TComplex и имен вызываемых подпрограмм DLL. Сохраняем его под именем Complex1. 6. Командой Файл => Создать => Приложение создаем проект вызывающей программы. Форму делаем аналогичной заданию 1. 7. В коде модуля формы вызывающей программы добавляем: В строку uses ссылку на модуль Complex1. В раздел var переменные a, b, c, d типа real, Comp1, Comp2, Comp3 типа TComplex. 8. Создаем обработчики нажатия кнопок. 9. Сохраняем проект под именем Prg_11_2. Листинг DLL Complex2 library Complex2; uses SysUtils, Classes; {$R *.RES} type TComplex = record Re, Im: real end; function CAdd(x,y:TComplex):TComplex; export; begin Result.Re:=x.Re + y.Re; Result.Im:=x.Im + y.Im; end; // CAdd function CSub(x,y:TComplex):TComplex; export; begin Result.Re:=x.Re - y.Re; Result.Im:=x.Im - y.Im; end; // CSub function CMult(x,y:TComplex):TComplex; Export; begin Result.Re:=x.Re*y.Re - x.Im*y.Im; Result.Im:=x.Re*y.Im + x.Im*y.Re; end; // CMult function CDiv(x,y:TComplex):TComplex; Export; var z: real; begin z:=sqr(y.Re)+sqr(y.Im); try Result.Re:=(x.Re*y.Re + x.Im*y.Im)/z;
// Комплексная арифметика
// Тип комплексного числа // Комплексное сложение
// Комплексное вычитание
// Комплексное умножение
// Комплексное деление
//Защита при делении на 0
65
Result.Im:=(x.Re*y.Im - x.Im*y.Re)/z; except Result.Re:=1.1e309; Result.Im:=1.1e309 end; end; // СDiv exports CAdd Index 1 Name 'AddC' Resident, CSub Index 2 Name 'SubC', CMult Index 3 Name 'MultC', CDiv Index 4 Name ‘DivC’; begin end.
// Результат, если делитель 0
// Список экспорта
Листинг модуля Complex1 unit Complex1; interface type TComplex=record // Тип комплексного числа Re, Im: real end; // Вызываемые функции function AddC(x,y:TComplex):TComplex; External 'Complex2' Index 1; function SubC(x,y:TComplex):TComplex; External 'Complex2' Index 2; function MultC(x,y:TComplex):TComplex; External 'Complex2' Index 3; function DivC(x,y:TComplex):TComplex; External 'Complex2' Index 4; implementation end. Листинг модуля формы вызывающей программы такой же, как в задании 1, только в строке uses добавлена ссылка на модуль Complex1. В этом модуле устанавливается связь с DLL. Выводы 1. Для работы с часто используемыми подпрограммами применяются модули и DLL 2. Модуль или DLL - это набор готовых подпрограмм, хранящихся в компилированном виде. 3. Модуль связывается с вызывающей программой при компоновке. 4. DLL связывается с вызывающей программой динамически: DLL загружается на время обращения к ее подпрограммам. 5. Одна и та же DLL может использоваться несколькими параллельно работающими программами.
66
14. Таблицы Подготовка к работе По указанной литературе изучить: 1. Cвойства компонентов Label, Button, Edit, StringGrid. 2. Cобытия onClick, onChange, onCreate. 3. Как создать код обработчика события. Контрольные вопросы 1. События onClick, onCreate. 2. Назначение и свойства компонента кнопка. 3. Назначение и свойства компонент метка. 4. Назначение и свойства компонента однострочный редактор. 5. Назначение и свойства компонента StringGrid. 6. Как инициализировать таблицу при старте приложения. 7. Как создать обработчик события onClick. 8. Как создать обработчик события onDblClick. 9. Как создать обработчик события onChange. 10. Как использовать строковые данные для вычислений. 11. Как увеличить число строк в таблице. 12. Как уменьшить число строк в таблице. 13. Как увеличить число столбцов в таблице. 14. Как увеличить число столбцов в таблице. 15. Подпрограммы. Основные понятия. Задание Создать проект “Таблица конвертации” для конвертации рублей России в разные валюты с учетом комиссии. В таблице предусмотреть возможность редактирования содержимого ячеек, добавления и удаления строк и столбцов. Варианты заданий приведены в табл. 14.1. табл. 14.1. Варианты заданий № 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Доллар США Фунт стерлингов Евро Японская йена Рубль Беларуси Гривна Украины Доллар США Фунт стерлингов Евро Японская йена Рубль Беларуси Гривна Украины Доллар США Фунт стерлингов Евро
Валюты Фунт стерлингов Евро Японская йена Рубль Беларуси Гривна Украины Фунт стерлингов Японская йена Японская йена Рубль Беларуси Гривна Украины Фунт стерлингов Евро Японская йена Рубль Беларуси Гривна Украины
Евро Рубль Беларуси Гривна Украины Японская йена Доллар США Доллар США Фунт стерлингов Евро Японская йена Рубль Беларуси Гривна Украины Японская йена Рубль Беларуси Гривна Украины Фунт стерлингов
Пример выполнения Задание Создать проект “Таблица конвертации” для конвертации с учетом комиссии рублей России в валюты США, Великобритании и Европейского союза. Выполнение 1. Запустить Delphi. 2. Создать в ней новое приложение. 3. Присвоить свойству Caption компонента Form1 значение Пересчет денежных сумм. 4. Сохранить модуль под именем Prg_14_1_, а проект под именем Prg_14_1. 5. Установить на форме компоненты: однострочные редакторы Edit1 и Edit2, метки Label1 - Label4, кнопки Button1- Button7 (со страницы Standard), таблицу строк StringGrid1 (со страницы Additional). Компоненты расположить, как показано на рис. 14.1. 6. Задать следующие свойства компонент: Компонент Caption (Надпись) Name (Имя) Описание функций
67 StringGrid1 Edit1 Edit2 Label1 Label2 Label3 Label4 Button1 Button2 Button3 Button4 Button5 Button6 Button7
Редактор ячеек Сумма для конвертации Таблица LbDate OK Принято Выход < > /\ \/
StringGrid1 EdCell EdSum Label1 Label2 Label3 Label4 SellAgree SumAgree Exit DecCol IncCol DecRow IncRow
Основная таблица Редактирование ячейки Редактирование суммы Поясняющая надпись Поясняющая надпись Заголовок Текущая дата Принятие изменений текущей ячейки Принятие суммы и расчет по курсу Выход из приложения Уменьшение числа столбцов на 1 Увеличение числа столбцов на 1 Уменьшение числа строк на 1 Увеличение числа строк на 1
StringGrid1
рис. 14.1. Заготовка интерфейса проекта "Таблица" После вышеперечисленных установок интерфейс проекта примет вид рис. 14.2.
рис. 14.2. Интерфейс проекта в режиме конструирования
68 7. Листинг модуля формы проекта: unit Prg_14_1_; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids; type TForm1 = class(TForm) StringGrid1: TStringGrid; EdCell: TEdit; EdSum: TEdit; SellAgree: TButton; SummAgree: TButton; Exit: TButton; DecCol: TButton; IncCol: TButton; DecRow: TButton; IncRow: TButton; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; procedure FormCreate(Sender: TObject); procedure DecColClick(Sender: TObject); procedure IncColClick(Sender: TObject); procedure DecRowClick(Sender: TObject); procedure IncRowClick(Sender: TObject); procedure ExitClick(Sender: TObject); procedure SellAgreeClick(Sender: TObject); procedure StringGrid1DblClick(Sender: TObject); procedure SummAgreeClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin StringGrid1.ColCount:=6; StringGrid1.RowCount:=4; StringGrid1.Cells[0,0]:='Валюта'; StringGrid1.Cells[1,0]:='Курс рубля; StringGrid1.DefaultColWidth:=78; StringGrid1.Cells[2,0]:='Сумма выдачи'; StringGrid1.Cells[3,0]:='Комиссия, %'; StringGrid1.Cells[4,0]:='Комиссионные'; StringGrid1.Cells[5,0]:='Взнос, руб.'; StringGrid1.Cells[0,1]:='USA'; StringGrid1.Cells[0,2]:='FST'; StringGrid1.Cells[0,3]:='EUR'; StringGrid1.cells[1,1]:='31,5'; StringGrid1.cells[1,2]:='45'; StringGrid1.cells[1,3]:='32,1'; StringGrid1.cells[3,1]:='2'; StringGrid1.cells[3,2]:='2'; StringGrid1.cells[3,3]:='2'; Label4.Caption:='По состоянию на '+DateToStr(Date); end;
69 procedure TForm1.DecColClick(Sender: TObject); begin if StringGrid1.ColCount>2 then StringGrid1.ColCount:=StringGrid1.ColCount-1; end; procedure TForm1.IncColClick(Sender: TObject); begin StringGrid1.ColCount:=StringGrid1.ColCount+1; end; procedure TForm1.DecRowClick(Sender: TObject); begin if StringGrid1.RowCount>2 then StringGrid1.RowCount:=StringGrid1.RowCount-1; end; procedure TForm1.IncRowClick(Sender: TObject); begin StringGrid1.RowCount:=StringGrid1.RowCount+1; end; procedure TForm1.ExitClick(Sender: TObject); begin Close; end; procedure TForm1.SellAgreeClick(Sender: TObject); begin StringGrid1.Cells[StringGrid1.Col,StringGrid1.Row]:=EdCell.Text; end; procedure TForm1.StringGrid1DblClick(Sender: TObject); begin if (StringGrid1.Col=1) and (StringGrid1.Row>0) then EdCell.Text:=StringGrid1.Cells[StringGrid1.Col,StringGrid1.Row]; end; procedure TForm1.SummAgreeClick(Sender: TObject); var ResVal, Komis:real; i:byte; S:string; begin with form1 do for i:=1 to StringGrid1.RowCount-1 do if (StrToFloat(StringGrid1.Cells[1,i])0) then begin Komis:=StrToFloat(EdSum.Text)/100* StrToFloat(StringGrid1.Cells[3,i]); ResVal:=(StrToFloat(EdSum.Text)-Komis)/ StrToFloat(StringGrid1.Cells[1,i]); str(Komis:0:2,s); StringGrid1.Cells[4,i]:=s; str(ResVal:0:2,s); StringGrid1.Cells[2,i]:=s; str(StrToFloat(EdSum.Text):0:2,s); StringGrid1.Cells[5,i]:=s; end; end; end. В программе применены следующие методы: 1. FormCreate. Он при создании формы заносит начальные данные в таблицу по координатам ячеек ACol (номер столбца) и ARow (номер строки). Одельным ячейкам компонента StringGrid1 через свойство StringGrid.Cell [ACol, ARow]
70 присваиваются текстовые значения, а свойству Caption метки Label4 значение текущего времени. CellAgreeClick. Он данные из текстового "Редактора ячеек" EdCell при нажатии на кнопку SellAgree (ОК) заносит в таблицу по текущим координатам выделенной ячейки таблицы. Учтите, что данные заносятся, как текстовая информация. 3. StringGrid1DblClick. Он позволяет двойным щелчком мыши по ячейкам таблицы переносить данные из таблицы в окно "Редактора ячеек" EdCell для их дальнейшего быстрого редактирования. Например, при изменении курса или процента комиссионных. Доступ к координатам текущей ячейки обеспечивается с помощью свойств Col и Row компонента StringGrid1. Редактировать надо только курсы валют. 4. SumAgreeClick. С его помощью данные из текстового редактора "Сумма для конвертации" EdSum при нажатии на кнопку SumAgree (Принято) заносятся в таблицу по текущим координатам. Учтите, что данные воспринимаются редактором, как текстовая информация, а вычисления необходимо производить с числами. 5. Для изменения размеров таблицы используются свойства ColCount и RowCount. Следующие 4 метода увеличивают или уменьшают числа столбцов и строк в процессе выполнения программы щелчками (вызывают событие onClick) по кнопкам размеров таблицы: Уменьшение числа столбцов TForm1.DecColClick. Увеличение числа столбцов TForm1.IncColClick. Уменьшение числа строк TForm1.DecRowClick. Увеличение числа строк TForm1.IncRowClick. 6. Для завершения работы с программой использован метод ExitClick, при осуществлении которого закрывается основная форма. Дублируется кнопка закрытия окна Windows. Запустить проект на выполнение и опробовать действие всех кнопок. Внести в EdSum сумму для конвертации и проконтролировать результат расчетов в соответствующих ячейках. Изменить курс валюты и проконтролировать, как это повлияет на результаты расчетов. Форма при исполнении имеет вид рис. 14.3. 2.
рис. 14.3. Интерфейс проекта в режиме выполнения Выводы 1. Для создания таблиц используется компонент StringGrid (таблица строк). 2. Для управления используются компоненты Button (кнопка) и их обработчики событий. 3. Для пояснений используются компоненты Label (метка). 4. Для ввода данных используются компоненты Edit (однострочный редактор). 5. Кнопка “Выход” дублирует стандартную кнопку завершения приложения Windows.
71
15. Графика, отображение графиков функций Подготовка к работе 1. По рекомендованной литературе изучить графические средства Delphi. 2. Разработать алгоритмы решения задач. 3. Составить программы решения задач. Контрольные вопросы 1. GDI (Graphics Device Interface) - интерфейс и драйверы графических устройств. Контекст отображения (дисплейный контекст) и его инструменты: шрифт, перо, кисть. 2. Класс TGraphicObject (графический объект). 3. Класс TFont - шрифт. Свойства Charset (набор символов), Name (имя), Size (размер в кеглях), Style (стиль), Color (цвет фона). 4. Класс TPen - перо. Свойства Color (цвет), Style (стиль), Width (ширина), Mode (режим). 5. Класс TBrush - кисть. Свойства Color (цвет), Style (стиль). 6. Класс TCanvas - холст (поверхность рисования). Свойства CopyMode (режим копирования), Pen (перо), Brush (кисть), Font (шрифт), Pixels (цвет пикселя). 7. Использование свойства TCanvas.Pixels или метода TCanvas.LineTo для рисования графиков функций. 8. Метод MoveTo (переместить перо к). 9. Компонент TChart. 10. Задание функции для отображения в компоненте TChart. 11. Использование легенды в компоненте TChart. Задание к работе Создать программу вывода текста и рисования в форме графиков функций. Проект – приложение. Варианты заданий приведены в табл. 15.1. табл. 15.1. Варианты задания 1 График функции y(x) № Функция x начальное x конечное 1 sin(x) 0 6π 2 cos(x) 0 6π 3 sin(x)+sin(2x) 0 6π 4 sin(x)-sin(2x) 0 6π 5 sin(x)+cos(2x) 0 6π 6 sin(x)-cos(2x) 0 6π 7 sin(x)*exp(x) 0 6π 8 cos(x)*exp(x) 0 6π 9 sin(x)*exp(-x) 0 6π 10 cos(x)*exp(-x) 0 6π 11 exp(x) 0 2 12 exp(-x) 0 2 13 ln(x) 1 10 14 lg(x) 1 100 15 ln(x)+lg(x) 1 10 Пример выполнения Создать программу рисования в форме графика функции с поясняющим текстом. Проект – приложение. Функция - синус. Программа предусматривает три варианта рисования графика: Точками с помощью свойства Pixels (график в левой верхней части окна). Линиями с использованием метода LineTo (график в нижней левой части окна). С использованием компонента TChart (в правой части окна). На рис. 15.1 представлено окно формы в начале конструирования. В форме размещены следующие компоненты: Кнопка BitBtn1 (Графика) из страницы Additional. Она вызывает построение графиков в окне. Кнопка BitBtn2 (Закрыть) из страницы Additional. Дублирует кнопку закрытия приложения Windows. TChart1. Компонент построения графиков из страницы Additional.
72
рис. 15.1. Окно формы на этапе конструирования Для подготовки TChart к работе используется встроенный редактор свойств этого компонента, вызываемый двойным щелчком по компоненту. На рис. 15.2 слева представлено окно этого редактора. В нем в закладке Series нужно нажатием кнопки Add добавить по крайней мере одну серию данных для построения графика. Остальные параметры компонента можно оставить без изменения. При этом возникает окно для выбора способа отображения графика, показанное на рис. 15.2 справа.
рис. 15.2. Выбор серии для TChart После выбора вида графика окно редактора приобретает вид рис. 15.3, а у компонента TChart в окне формы отображается примерный вид представления графика (см. рис. 15.4 слева). По умолчанию в правой части компонента отображается легенда - столбик из вычисляемых значений функции. При желании легенду можно удалить. Для этого следует вновь вызвать редактор свойств TChart, на вкладке Legend которого выключить флаг Visible. Окно формы примет вид, показанный на рис. 15.4 справа.
рис. 15.3. Окно редактора TChart после выбора серии
73
рис. 15.4. Окно формы после выбора серии Листинг модуля формы unit Prg_15_1_; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, Buttons, TeEngine, Series, TeeProcs, Chart; type TForm1 = class(TForm) BitBtn1: TBitBtn; BitBtn2: TBitBtn; Chart1: TChart; Series1: TLineSeries; procedure BitBtn1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.BitBtn1Click(Sender: TObject); var i,amp,x01,y01,x02,y02,imax,t:integer; func:real; begin imax:=100; //число точек в периоде t:=3; //число периодов amp:=70; //амплитуда x01:=20; //начала координат x02:=20; y01:=20+amp; y02:=y01+2*amp+40; //Рисуем график с Pixels Canvas.TextOut(0,0,'График функции с Pixels'); Canvas.MoveTo(x01,y01); //Рисуем ось X Canvas.LineTo(x01+imax*t,y01); Canvas.MoveTo(x01,y01+amp); //Рисуем ось Y Canvas.LineTo(x01,y01-amp); for i:=0 to imax*t do //Рисуем график begin func:=-amp*sin(2*pi/imax*i); Canvas.Pixels[x01+i,y01+round(func)]:=clBlack; end;
74
//Рисуем график с LineTo Canvas.TextOut(x02,y02-amp-20,'График функции c LineTo'); Canvas.MoveTo(x02,y02); //Рисуем ось X Canvas.LineTo(x02+imax*t,y02); Canvas.MoveTo(x02,y02+amp); //Рисуем ось Y Canvas.LineTo(x02,y02-amp); //func:=amp*sin(0); //Canvas.MoveTo(x01,y0+round(func)); for i:=0 to imax*t do //Рисуем график begin func:=-amp*sin(2*pi/imax*i); Canvas.LineTo(x02+i,y02+round(func)); end; //Рисуем график в компонентеTChart for i:=0 to imax*t do Chart1.SeriesList[0].AddXY(i,amp*sin(2*pi/imax*i),'',clRed); end; initialization end. На рис. 15.5 представлено окна работающего приложения проекта. Оно возникает при нажатии кнопки График. В окне видны графики одной и той же функции, построенные разными способами: С использованием свойства Pixels (вверху слева). С использованием метода LineTo (внизу слева). С помощью компонента TChart (справа).
рис. 15.5. Окна работающего приложения задачи Выводы 1. Для рисования используется класс Canvas (поверхность рисования, или холст). 2. Многие компоненты имеют свойство Canvas. Например, Form (форма), компонент Image (изображение). 3. Canvas имеет два инструмента: Pen (перо) для рисования линий, Brush (кисть) для заливки областей. 4. Pen имеет свойства: Color - цвет линии, значения с префиксом cl (например, clRed), Style - тип линии, значения с префиксом ps (например, psSolid, принято по умолчанию), Width - толщина линии, в пикселах (по умолчанию 1), Mode - режим взаимодействия с поверхностью холста, значения с префиксом pm (например, pmCopy - писать цветом пера, режим по умолчанию), 5. Brush имеет свойства: Color - цвет заливки, Style - стиль заливки, значения с префиксом bs (Например, bsCross). 6. Для рисования графиков функций используются свойство TCanvas.Pixel(x,y) и метод TCanvas.LineTo. Второй метод дает более качественный график.
75
7.
Для построения графиков есть компонент TChart, позволяющий автоматизировать значительную часть операций.
75
16. Графика, примитивы Подготовка к работе По указанной литературе изучить: Назначение, типы и методы работы с графическими примитивами. Свойства компонента TShape. Метафайлы. Контрольные вопросы 1. Назначение графических примитивов. 2. Графический примитив Линия и метод LineTo его отображения. 3. Графический примитив Кусочно-ломаная линия и метод PolyLine и его отображения. 4. Графический примитив Хорда (линия поперек эллипса) и метод Chord его отображения. 5. Графический примитив Прямоугольная рамка и метод FrameRect его отображения. 6. Графический примитив Заполненный прямоугольник и метод Rectangle его отображения. 7. Графический примитив Заполненный многоугольник и метод Polygon его отображения. 8. Графический примитив Заполненный прямоугольник со скругленными углами и метод RoundRect его отображения. 9. Графический примитив Дуга и метод Arc его отображения. 10. Графический примитив Заполненный эллипс и метод Ellipse его отображения. 11. Графический примитив Пирог (сектор эллипса) и метод Pie его отображения. 12. Метод заполнения замкнутых фигур FloodFill (заполнить область), 13. Методы вывода текста: TextOut (вставить строку текста). 14. Компонент TShape. 15. Метафайлы, назначение, структура, создание и использование. Задание к работе 1. Создать программу рисования в форме графического примитива с заливкой. Примитив рисуется при нажатии кнопки мыши (событие onDown) на форме. Цвет линий, стиль и цвет заливки зависит от того, какая кнопка мыши нажимается (левая или правая). Проект – приложение. Варианты заданий приведены в табл. 16.1. табл. 16.1. Варианты задания 1 Цвет линий Заливка Левая кнопка Правая кнопка Стиль Цвет 1 Ellipse clBlue clGreen bsSolid clRed 2 Rectangle clGreen clWhite bsHorizontal clBlue 3 Pie clWhite clRed bsVertical clGreen 4 RoundRec clRed clBlue bsDiagonal clWhite 5 Polygon (3) clBlue clGreen bsBDiagonal clRed 6 Ellipse clGreen clWhite bsCross clBlue 7 Rectangle clWhite clRed bsDiagCros clGreen 8 Pie clRed clBlue bsSolid clWhite 9 RoundRec clBlue clGreen bsHorizontal clRed 10 Polygon (7) clGreen clWhite bsVertical clBlue 11 Ellipse clWhite clRed bsDiagonal clGreen 12 Rectangle clRed clBlue bsBDiagonal clWhite 13 Pie clBlue clGreen bsCross clRed 14 RoundRec clGreen clWhite bsDiagCros clBlue 15 Polygon (6) clWhite clRed bsSolid clGreen 2. Создать проект, демонстрирующий использование графического компонента TShape для изменения пользовательского интерфейса при выполнении программы. В проекте на форме с изменяемым цветом отображается фигура с разными типом, размерами и цветом. Варианты заданий приведены в Табл. 16.2. Возможные типы фигуры: Тип Имя Круг StCircle Эллипс stEllipse Прямоугольник stRectangle Прямоугольник со скругленными углами stRoundRect Квадрат stsquare Квадрат со скругленными углами stRoundSquare(квадрат с округлыми углами) №
Примитив
Табл. 16.2. Варианты задания 2 1 2 3
stCircle stEllipse stRectangle
stEllipse stRectangle stRoundRect
stRectangle stRoundRect stsquare
76 4 stRoundRect stsquare stCircle 5 stsquare stRoundSquare stRectangle 6 stRoundSquare stCircle stRoundRect 7 stCircle stRectangle stsquare 8 stEllipse stRoundRect stRoundSquare 9 stRectangle stsquare stRectangle 10 stRoundRect stRoundSquare stRoundRect 11 stsquare stRoundRect stsquare 12 stRoundSquare stsquare stRoundSquare 13 stCircle stRoundSquare stRoundSquare 14 stEllipse stRoundRect stsquare 15 stRectangle stsquare stCircle 3. Создать проект работы с метафайлом. Метафайл содержит график с графическими примитивами,, создается программно, отображается на форме и сохраняется на диске ПК. Для проверки праильности метафайла он считывается в компонент Image формы. Проект – приложение. Графические примитвы студент выбирает самостоятельно. Пример выполнения Задание 1 Создать программу рисования в форме графического примитива с заливкой. Примитив - пятиугольная звезда, рисуется при нажатии кнопки мыши (событие onDown) на форме. Если нажата левая кнопка мыши, то цвет линий clBlack (черный), стиль заливки bsDiagCross (диагональный крест), цвет заливки - clRed (красный). Если нажата правая кнопка мыши, то цвет линий clRed (красный), стиль заливки bsCross ( крест), цвет заливки clBlue (синий). Проект – приложение. Листинг модуля формы unit Prg_16_1_; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) procedure FormMouseDown(Sender: TObject; Button:TMouseButton; Shift: TShiftState; x,y:integer); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure StarLine(x0,y0,r: integer; Canvas: TCanvas); // x0,y0 - координаты центра звезды // r - радиус звезды var p: array[1..11] of TPoint; // массив координат лучей и впадин a: integer; // угол между ОХ и радиусом к точке звезды i: integer; begin a := 18; // строим от правого горизонтального луча for i:=1 to 10 do begin if (i mod 2 = 0) then begin // впадина звезды p[i].x := x0+Round(r/2*cos(a*2*pi/360)); p[i].y:=y0-Round(r/2*sin(a*2*pi/360)); end else begin // луч звезды p[i].x:=x0+Round(r*cos(a*2*pi/360)); p[i].y:=y0-Round(r*sin(a*2*pi/360)); end;
77 a := a+36; end; p[11].X := p[1].X; p[11].Y := p[1].Y; Canvas.Polyline(p); end;
// чтобы замкнуть контур звезды // начертить звезду
// нажатие кнопки мыши procedure TForm1.FormMouseDown(Sender: TObject; Button:TMouseButton; Shift: TShiftState; x,y:integer); begin with Form1 do begin if Button = mbLeft // нажата левая кнопка? then begin Canvas.Pen.Color := clBlack; StarLine(x, y, 30,Canvas); Canvas.Brush.Style:=bsDiagCross; Canvas.Brush.Color:=clRed; Canvas.FloodFill(x,y,Canvas.Pen.Color,fsBorder); end else begin Canvas.Pen.Color := clRed; StarLine(x, y, 30,Canvas); Canvas.Brush.Style:=bsCross; Canvas.Brush.Color:=clBlue; Canvas.FloodFill(x,y,Canvas.Pen.Color,fsBorder); end; end; end; end. На рис. 16.1 представлен вид окна приложения задачи 1 при исполнении.
рис. 16.1. Окно работающего приложения задачи 1 Задание 2 Создать проект в котором в форме, цвет которой может изменяться, отображается компонент Shape1 (фигура), для которого можно менять тип, цвет и размеры. Формы фигур: stCircle, stEllipse, stsquare. Выполнение 1. Запустить Delphi. 2. Создать в ней новое приложение. 3. Присвоить свойству Caption компонента Form1 значение Prg_16_2. 4. Сохранить модуль под именем Prg_16_2_, а проект под именем Prg_16_2. 5. Установить на форме компоненты:
78 кнопки Button1 и Button2, комбинированный список ComboBox1, линейки прокрутки ScrollBar1 и ScrollBar2, панель Panel1 (со страницы Standard). фигура Shape1 (со страницы Additional). диалог цвета ColorDialog1 (со страницы Dialogs). 6. Задать свойству Shape компонента Shape1 значение stEllipse (Эллипс). Используя свойство Brush, установить произвольный цвет объекта Shape1. 7. Установить значения свойств компонентов линеек прокрутки ScrollBar1 и ScrollBar2: Name ScrollBar1 ScrollBar2 Kind ( Тип) sbHorizobntal (Горизонтальная) sbVertical (Вертикальная) Align (Размещение) alBottom (Снизу) alRight (Справа)
8. Компоненты Button1, Button2, ComboBox1 установить на передний план объекта Panel1 и выровнять их по вертикали. 9. Установить значения свойств компонентов Button1, Button2: Компонент Button1 Button2 Name (Имя) FormColor ShapeColor Caption (Надпись) Цвет формы Цвет фигуры 10. Установить следующие значения строк списка ComboBox1: Имя фигуры Тип фигуры stRectangle Прямоугольник stSguare Квадрат stRoundRect Прямоугольник со скругленными углами stRoundSguare Квадрат со скругленными углами stEllipse Эллипс stCircle Круг Внимание: имена фигур надо заносить в указанном порядке, так как они далее анализируются по номеру в списке. 11. Задать свойству BorderWidth компонента Panel1 значение 5. После вышеперечисленных установок интерфейс проекта примет вид, показанный на .
рис. 16.2. Форма проекта задачи 2 12. Для изменения цвета фигуры или формы во время выполнения приложения использовать стандартное диалоговое окно выбора цвета ColorDialog1. Этот компонент при исполнении программы невидим. 13. Двойным щелчком по кнопке Цвет формы создать заготовку обработчика отклика на событие OnClick (на щелчок) для кнопки Цвет формы. Написать код обработчика, который при нажатии кнопки Цвет формы вызывает стандартное диалоговое окно выбора цвета с помощью диалогового окна ColorDialog1. 14. Двойным щелчком по кнопке Цвет фигуры создать заготовку обработчика события OnClick (на щелчок) для кнопки Цвет фигуры. Написать код обработчика, который при нажатии кнопки установит значение свойства Brush.Color (цвет закраски) фигуры Shape1, выбираемое с помощью диалогового окна ColorDialog1. 15. Запустить проект командой Выполнить и проверить действие кнопок Цвет формы и Цвет фигуры. При нажатии кнопок выбора цвета в отдельном окне (см. рис. 16.3) отображается окно диалога выбора цвета, в котором следует выбирать желаемый цвет.
79
рис. 16.3. Окно диалога выбора цвета Вернуться в режим конструирования. 16. Запрограммировать изменение размера фигуры с помощью полос прокрутки. Для этого: • Двойным щелчком по компонентам создать заготовки методов для отклика на событие OnChange (на изменение) для каждой из полос прокрутки ScrollBar1 и ScrollBar2. • Написать для этих методов коды, которые установят свойство Width (ширина) или Height (высота) фигуры Shape1 в соответствии с положением "бегунка" на горизонтальной (ScrollBar1) или вертикальной (ScrollBar2) полосах прокрутки. • Подобрать соотношение между положением бегунков полосы прокрутки ScrollBar1.Position и ScrollBar2.Position (лежат в пределах 1...100) и размерами фигуры, при котором достигается лучшее представление изменения размеров фигуры. 17. Запустить проект и проверить действие каждой из полос прокрутки. Вернуться в режим конструирования. 18. Для выбора нового вида фигуры использовать выпадающий список (ComboBox). Чтобы создать список в режиме проектирования, необходимо ввести нужные элементы в список Items, щелкнув маленькую кнопку с тремя точками в правой части строки Инспектора объектов, отображающую данное свойство. Список показан на рис. 16.4.
рис. 16.4. Список опций свойства Shape 19. В диалоговое окно текстового редактора (см. рис. 16.4) ввести фигуры по заданию. 20. Двойным щелчком по компоненту ComboBox1 создать заготовку обработчика события OnClick (на щелчок) для списка ComboBox1. В нее вставить код, позволяющий выбрать из списка нужный элемент. 21. Для проверки кода запустить проект, а затем поочередно выбрать из списка разные виды фигур. 22. Сохранить и закрыть проект. Запустить исполняемый файл проекта Prg_16_2 из среды Windows и проверить его работоспособность. Листинг модуля формы unit Prg_16_2_; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type
80 TForm1 = class(TForm) FormColor: TButton; ShapeColor: TButton; ScrollBar1: TScrollBar; ComboBox1: TComboBox; Shape1: TShape; ColorDialog1: TColorDialog; ScrollBar2: TScrollBar; Panel1: TPanel; procedure FormColorClick(Sender: TObject); procedure ShapeColorClick(Sender: TObject); procedure ScrollBar1Change(Sender: TObject); procedure ScrollBar2Change(Sender: TObject); procedure ComboBox1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormColorClick(Sender: TObject); begin if ColorDialog1.Execute then Form1.Color:= ColorDialog1.Color; end; procedure TForm1.ShapeColorClick(Sender: TObject); begin if ColorDialog1.Execute then Shape1.Brush.Color:= ColorDialog1.Color; end; procedure TForm1.ScrollBar1Change(Sender: TObject); begin Shape1.Width:= ScrollBar1.Position*3; end; procedure TForm1.ScrollBar2Change(Sender: TObject); begin Shape1.Height:= ScrollBar2.Position*3; end; procedure TForm1.ComboBox1Click(Sender: TObject); var Index: integer; begin if ComboBox1.Text='stRectangle' then Index:=0; if ComboBox1.Text='stSquare' then Index:=1; if ComboBox1.Text='stRoundRect' then Index:=2; if ComboBox1.Text='stRoundSquare' then Index:=3; if ComboBox1.Text='stEllipse' then Index:=4; if ComboBox1.Text='stCircle' then Index:=5; Shape1.Shape:=TShapeType(Index); end; end. Задание 3 Создать проект работы с метафайлом. Метафайл содержит график с двумя фигурами (эллипс и квадрат), создается программно, отображается на форме и сохраняется на диске ПК. Для проверки праильности метафайла он считывается в компонент Image формы. Проект – приложение.
81 На рис. 16.5 показана форма проекта задачи 3. Она содержит компонент Image1 для просмотра метафайла и две кнопки: • Button1 - «Создать метафайл». При нажатии кнопки метафайл MyMetafile.wmf создается, прорисовывается на форме и сохраняется на диске. • Button2 - «Смотреть метафайл». Нажатие этой кнопки приводит к отображению метафайла в компоненте Image1 формы.
рис. 16.5. Форма проекта задачи 3 Листинг модуля формы unit Prg_16_3_; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Sozdath: TButton; Image1: TImage; Smotreth: TButton; procedure SozdathClick(Sender: TObject); procedure SmotrethClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; MyMetafile:TMetafile; implementation {$R *.dfm} procedure TForm1. SozdathClick(Sender: TObject); begin with TMetafileCanvas.Create(MyMetafile, 0) do try Brush.Color := clRed; Ellipse(0,0,150,100); // Рисуем эллипс Brush.Color:=clWhite;
82 Rectangle(150,150,200,200); // Рисуем квадрат finally Free end; MyMetafile.SaveToFile('MyMetafile.wmf'); // Сохранить метафайл Form1.Canvas.Draw(0,0,MyMetafile); // Рисовать метафайл на форме end; procedure TForm1. SmotrethClick(Sender: TObject); begin Image1.Picture.LoadFromFile('MyMetafile.wmf'); // Просмотр метафайла end; initialization MyMetafile := TMetafile.Create; end.
// Создать метафайл
Внимание Работа с метафайлом осуществляется в динамической памяти, поэтому перед использованием созданного метафайла необходимо освободить ДП процедурой Free. На рис. 16.6 показано окно работающего приложения задачи 3. Левая часть отображается при нажатии кнопки «Создать метафайл», правая – при нажатии кнопки «Смотреть метафайл».
рис. 16.6. Форма работающего приложения задачи 3 Выводы 1. Для построения графиков используются графические примитвы. 2. Определены графические примитивы: Линия и метод LineTo его отображения. Кусочно-ломаная линия и метод PolyLine и его отображения. Хорда (линия поперек эллипса) и метод Chord его отображения. Прямоугольная рамка и метод FrameRect его отображения. Заполненный прямоугольник и метод Rectangle его отображения. Заполненный многоугольник и метод Polygon его отображения. Заполненный прямоугольник со скругленными углами и метод RoundRect его отображения. Дуга и метод Arc его отображения. Заполненный эллипс и метод Ellipse его отображения. Пирог (сектор эллипса) и метод Pie его отображения. 3. Определен метод заполнения замкнутых фигур FloodFill (заполнить область), 4. Имеется метод вывода текста: TextOut (вставить строку текста). 5. Определен компонент TShape (фигура)., позволяющий быстро выбирать фигуру для построения. 6. Для изменения интерфейса используются кнопки, линейки прокрутки, списки, меню, диалоги. 7. Замкнутые фигуры с помощью инструмента Brush могут быть залиты узором. 8. График с использованием примитивов может быть сохранен в формате метафайла Windows.
83
17. Графика, растровые изображения и анимация Подготовка к работе 1. По рекомендованной литературе изучить графические средства Delphi. 2. Разработать алгоритмы решения задач. 3. Составить программы решения задач. Контрольные вопросы 1. Класс TImage - компонент изображения. 2. Класс TBitMap - растровое изображение. 3. Класс TJpegImage - сжатое по стандарту Jpeg изображение. 4. Сжатие изображений в стандарте Jpeg за счет изменения системы цветов.. 5. Сжатие изображений в стандарте Jpeg за счет дискретного косинусного преобразования. 6. Сжатие изображений в стандарте Jpeg за счет обнаружения повторяющихся кодов. 7. Сжатие изображений в стандарте Jpeg за счет использования алгоритма Хафмена. 8. Компонент TrackBar и его использование. 9. Использование класса TMemoryStream для определения размеров файлов. 10. Принцип создания анимации. 11. Использование в анимационной программе фоновой картинки. 12. Использование в анимационной программе картинки образа. 13. Использование в анимационной программе буфера. Задание к работе 1. Создать программу обработки битовых изображений. Проект – приложение. Нужно использовать два компонента TImage, в одном отображается растровая картинка, в другом - она же с использованием алгоритмов сжатия. Для сжатия использовать класс TJpegImage. 2. Создать программу анимации (движение самолета на фоне изображения фабрики) в компоненте TImage. Проект – приложение. Пример выполнения Задание 1 Создать программу работы с графическими файлами, Проект – приложение. В программе используется файл растровой картинки picture.bmp, который надо загрузить в ту же папку, где находится проект приложения. Этот файл находится в папке УМД к ЛР. На рис. 17.1 показана форма проекта задания 1.
рис. 17.1. Форма проекта задания 1 В форме размещены: Компоненты Image1 и Image2 для отображения битовых образов. Кнопки Button1 (BitMap) и Button2 (JpegImage), нажатие которых приводит к прорисовке изображений. Метки Label1 и Label2 для вывода размеров файлов исходного и сжатого изображений. Регулятор TrackBar1 для изменения качества сжимаемого изображения.
84
Метки Label3, Label4 и Label5 для отображения минимального, максимального и текущего значения коэффициента качества. Диапазон этого коэффициента определен в пределах 1...100. Метка Label6 предназначена для заголовка компонент регулятора. Программа содержит 3 процедуры. Две отрабатывают нажатие кнопок, третья изменение состояния регультора. В программе используется класс TJpegImage, описанный в ИСР в модуле Jpeg. Поэтому в строке uses нужно добавить ссылку на этот модуль. В программе определены: переменные MyBitmap и MyJpeg для взаимных преобразований картинок. переменная MyMemory для создания буфера в памяти, по нему определяются размеры файлов в байтах. вспомогательные переменные. файлы картинок должны размещаться в папке проекта. Листинг модуля формы unit Prg_17_1_; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ExtCtrls, jpeg, ComCtrls; type TForm1 = class(TForm) Image1: TImage; Image2: TImage; BitBtn1: TBitBtn; BitBtn2: TBitBtn; Label1: TLabel; Label2: TLabel; TrackBar1: TTrackBar; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; procedure BitBtn1Click(Sender: TObject); procedure BitBtn2Click(Sender: TObject); procedure TrackBar1Change(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; MyJpeg:TJpegImage; MyBitMap:TBitmap; MyMemory:TmemoryStream; s1,s2,s3,s:string; size:integer; implementation {$R *.dfm} procedure TForm1.BitBtn1Click(Sender: TObject); begin Image1.Picture.Assign(MyBitmap); MyMemory.Clear; Mymemory.LoadFromFile(s1); str(MyMemory.Size,s3); Label1.Caption:=s3; end; procedure TForm1.BitBtn2Click(Sender: TObject); begin MyJpeg.Assign(MyBitmap); MyJpeg.CompressionQuality:=100;
85
MyJpeg.Compress; MyJpeg.SaveToFile(s2); Image2.Picture.LoadFromFile(s2); MyMemory.Clear; Mymemory.LoadFromFile(s2); str(MyMemory.Size,s3); Label2.Caption:=s3; end; procedure TForm1.TrackBar1Change(Sender: TObject); begin str(TrackBar1.Min,s3); Label3.Caption:=s3; str(TrackBar1.Max,s3); Label4.Caption:=s3; str(TrackBar1.Position,s3); Label5.Caption:=s3; MyJpeg.CompressionQuality:=TrackBar1.Position; MyJpeg.Compress; MyJpeg.SaveToFile(s2); Image2.Picture.LoadFromFile(s2); MyMemory.Clear; Mymemory.LoadFromFile(s2); str(MyMemory.Size,s3); Label2.Caption:=s3; end; initialization s1:='E:\Eddy\Umd\Prg_YVU\LR\Delphi_examples_2\17_1\Picture.bmp'; s2:='E:\Eddy\Umd\Prg_YVU\LR\Delphi_examples_2\17_1\Picture.jpeg'; MyBitmap:=TBitMap.Create; MyBitmap.LoadFromFile(s1); MyMemory:=TmemoryStream.Create; MyJpeg:=TJpegImage.Create; end. При запуске проекта на выполнение появляется окно в котором картинок нет. При нажатии на кнопку BitMap отображается исходная картинка и размер ее файла (в примере 309862), При нажатии на кнопку JpegImage отображается сжатая картинка и размер ее файла (в примере 89598). Это показано на рис. 17.2. Картинки получены при качестве 100, когда никаких отличий не видно, хотя сжатый файл имеет размер примерно в 3 раза меньше.
86
рис. 17.2. Форма при запуске программы Если теперь перемещать движок регулятора, сжатая картинка и размер ее файла динамически изменяются. Например, при коэффициенте качества 1 картинки имеют вид, показанный на рис. 17.3. Размер сжатого файла 3119, т.е произошло сжатие примерно в 100 раз Граница заметности ухудшение качества для использованной картинки - коэффициент качества 10. При этом размер сжатого файла 5599, что примерно в 55 раз меньше, чем у исходного изображения.
рис. 17.3. Картинки при коэффициенте качества 1 Задание 2 Создать программу демонстрации анимации: движение самолета на фоне фабрики. Проект – приложение. В программе используются два файла растровых картинок, которые надо загрузить в ту же папку, где находится проект приложения: фон - фабрика, файл factory.bmp, движущийся объект - самолет, файл aplane.bmp. Эти файлы находятся в папке УМД к ЛР. Листинг модуля формы unit prg_17_2_; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, Buttons; type TForm1 = class(TForm) Timer1: TTimer; Image1: TImage; procedure FormActivate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end; var Form1: TForm1;
87
implementation {$R *.DFM} var Back, Bitmap, Buf : TBitMap; BackRct : TRect; BufRct: Trect; x,y:integer; W,H: integer;
// Фон, картинка, буфер // Область фона, восстановлена из буфера // Область буфера для фона // Текущее положение картинки // Размеры картинки
procedure TForm1.FormActivate(Sender: TObject); begin // создать три объекта - битовых образа Back := TBitmap.Create; // Фон Bitmap := TBitmap.Create; // Картинка Buf := TBitmap.Create; // Буфер // загрузить и вывести фон Back.LoadFromFile('factory.bmp'); Form1.Image1.canvas.Draw(0,0,Back); // загрузить картинку, которая будет двигаться Bitmap.LoadFromFile('aplane.bmp'); // определим "прозрачный" цвет Bitmap.Transparent := True; Bitmap.TransParentColor := Bitmap.canvas.pixels[1,1]; // создать буфер для сохранения копии области фона под картинку W:= Bitmap.Width; H:= Bitmap.Height; Buf.Width:= W; Buf.Height:=H; Buf.Palette:=Back.Palette; // Для соответствия палитр !! Buf.Canvas.CopyMode:=cmSrcCopy; // определим область буфера, используемую для восстановления фона BufRct:=Bounds(0,0,W,H); // начальное положение картинки x := -W; y := 20; // определим сохраняемую область фона и сохраним ее BackRct:=Bounds(x,y,W,H); Buf.Canvas.CopyRect(BufRct,Back.Canvas,BackRct); end; // обработка сигнала таймера procedure TForm1.Timer1Timer(Sender: TObject); begin Form1.image1.canvas.Draw(x,y,Buf); // Восстановлением фона удалим рисунок x:=x+2; if x>form1.Image1.Width then x:=-W; // определим сохраняемую область фона и сохраним ее копию BackRct:=Bounds(x,y,W,H); Buf.Canvas.CopyRect(BufRct,Back.Canvas,BackRct); // выведем рисунок Form1.image1.canvas.Draw(x,y,bitmap); end; // завершение работы программы procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin // освободим память, выделенную для хранения битовых образов Back.Free; Bitmap.Free; Buf.Free; end; end. На рис. 17.1 представлен вид кадра окна приложения при исполнении. Самолет движется слева направо.
88
рис. 17.1. Окно работающего приложения задачи 2 Выводы 1. Для работы с изображениями класса TBitmap предназначен компонент TImage. 2. ИСР содержит класс TJpegImage для работы со сжатыми по стандарту Jpeg изображениями. 3. Для фотореалистических изображений возможно сжатие в десятки раз без заметного ухудшения качества. 4. При создании анимации образ движущегося объекта рисуется на холсте со смещением во времени. Перед очередным рисованием область фона, на которую накладывается текущий образ движущегося объекта, запоминается в буфере для последующего восстановления.
89
18. Тестирование и отладка Подготовка к работе 1. Изучить по литературе и методическим указаниям: Способы получения данных состояния программы. Отладочная печать. Использование окна отладки «Наблюдатели» (Watches). Пошаговое выполнение программы в версиях «Пропуск блока» (Step over) и «Трассировка» (Trace into). Выполнение программы до позиции курсора. Использование окна «СтопТочки» (Breakpoints). Использование окна «Стек вызова» (Call stack). Использование окон «CPU» и «FPU». Использование опции «Вычислить/Изменить» (Evaluate/Modify). 2. Изучить алгоритм и программу учебной задачи в данной работе. 3. Получить для численного примера набор данных для отладочного контроля. Контрольные вопросы 1. Способы получения данных о состоянии программы. 2. Отладочная печать и ее использование при тестировании программ. 3. Структура и использование окна отладки «Наблюдатели» (Watches). 4. Пошаговое выполнение программы в версии «Пропуск блока» (Step over). 5. Пошаговое выполнение программы в версии «Трассировка» (Trace into). 6. Использование опции прогона программы до позиции курсора. 7. Структура и использование окна «СтопТочки» (Breakpoints).. 8. Структура и использование окна «Стек вызова» Call stack. 9. Назначение и использование окон «CPU» и «FPU». 10. Использование опции «Вычислить/Изменить» (Evaluate/Modify). Задание к работе В работе используется учебная программа, которая по паре вводимых чисел c,d в цикле для i=1...10 вычисляет значения пары других параметров a=(c+d)*i, b=(c-d)*i. Функция Ample вычисляет квадратный корень из суммы квадратов целых частей от a,b, и эти значения суммируются в s. По завершении цикла вычисляется среднее арифметическое sm от выходных параметров функции Ample. Функция Ample оформлена в виде подпрограммы. В программе определены метки, задающие точки останова. Варианты задания представлены в табл. 18.1. Листинг программы: program Prg_16_1; {$APPTYPE CONSOLE} uses SysUtils, RusTrans; // Ссылка на модули label m1,m2,m3,m4,m5,m6; var a,b,c,d,s,f,sm: real; i: integer; function Ample(x,y:real):real; var x1,y1,f: real; begin m5: x1:=Int(x); m6: y1:=Int(y); Result:=sqrt(x1*x1+y1*y1);
90
end; begin writeln(Rus('Введите c,d')); readln(c,d); writeln; s:=0; for i:=1 to 10 do begin m1: a:=(c+d)*i; m2: b:=(c-d)*i; m3: f:=Ample(a,b); m4: s:=s+f; writeln('s[',i,']=',s:8:3); end; sm:=s/10; writeln; writeln('Resultat=',sm:8:3); readln; end. табл. 18.1. Варианты заданий N 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Переменные для окна «Наблюдатели» a, b, f c, d, s a, c, s b, d, f a, d, c b, a, s c, d, f d, c, a f, d, b s, f, c a, s, f b, a, s c, d, f s, d, c a, c, f
Строки останова m1,m2,m3 m4,m5,m6 m2,m3,m4 m1,m5,m6 m3,m4,m5 m1,m2,m6 m4,m5,m6 m1,m2,m3 m5,m6,m1 m4,m2,m3 m6,m1,m2 m3,m4,m5 m1,m3,m5 m4,m5,m3 m2,m1,m6
Выражение для окна «Вычислить/Изменить» a+b a*b a-b a/b a+b a*b a–b a/b a+b a*b a–b a/b a*b a–b a/b
Пример выполнения Задание Протестировать учебную программу с условиями: С помощью отладочной печати контролировать массив s[i]. Переменные для окна «Наблюдатели» (Watches) - a,b,s,i. Точки останова - m1,m2,m4. Выражение для окна «Вычислить/Изменить» (Evaluate/ Modify) «a+b» Выполнение 1. Создаем консольное приложение. 2. Размещаем в нем код учебной программы. 3. Проверка значений s[i] с помощью отладочной печати. Отладочная печать - вывод значений переменных в окно приложения осуществляется при прогоне программы. Ниже показано окно приложения при прогоне.
91
4. Командой Инструменты=>Опции отладчика вызвать диалоговое окно, в котором установить флаг «Встроенная отладка». После этого доступны средства тестирования и отладки программ.
5. Командой Вид =>Окна отладки=>Наблюдатели создаем окно «Наблюдатели». В начале оно пустое. 6. Командой Запуск=>Добавить наблюдателя через окно «Свойства наблюдателя» последовательно заносим в него переменные a, b, s, i.
92
После занесения переменных окно «Список наблюдателей» приобретает вид
Так как переменные доступны только при выполнении программы, для них указано, что процесс не доступен. При тестировании в окне будут появляться конкретные значения. 7. Осуществляем проверку программы с помощью пошагового выполнения в версии «Пропуск блока» (Step over). При этом на каждом шаге в редакторе кода указывается строка кода для исполнения. Она выделяется цветом и помечается стрелкой зеленого цвета слева от строки кода.
При исполнении шага меняется содержание окна «Список наблюдений».
8. Осуществить проверку программы с помощью пошагового выполнения в версии «Трассировка» (Trace into). Все происходит аналогично, но с заходом в подпрограмму. 9. Командой Вид=>Окна отладки=>СтопТочки создаем окно «СтопТочки» (Breakpoints). В начале окно пустое.
93
10. Задаем в нем точки останова. Для этого командой Запуск=>Добавить СтопТочку=>СтопТочка исходника вызываем окно
11. В нем заносим данные о точке останова. То же самое можно выполнить быстрее, делая щелчки левой кнопкой мыши по точкам, помечающим строки кода в редакторе кода программы.
В редакторе кода точки и строки кода получают цветовое выделение, а в окне «Список СтопТочек» появляются сведения об этих точках.
12. Осуществить проверку программы с использованием точек останова. Для этого использовать команду Запуск. При каждом выполнении осуществляется прогон до следующей точки останова. 13. На любом шаге трассировки командой «Запуск=>Вычислить/Изменить» можно вызвать окно «Вычислить/Изменить» (Evaluate/Modify),
94
В нем ввести в поле «Выражение» формулу и командой Вычислить в поле «Результат» получить вычисленное значение. Если в поле «Выражение» введено имя переменной, то будет доступна команда Изменить, по которой значение, введенное в поле «Новое значение», будет присвоено этой переменной. Выводы по работе 1. Данные о состоянии программы можно получить, используя отладочную печать или отладочные средства ИСР. 2. Чтобы сделать отладочные средства доступными, нужно командой Инструменты=>Опции отладчика вызвать диалоговое окно, в котором установить флаг «Встроенная отладка». 3. Для контроля значений переменных можно использовать окно отладки «Наблюдатели». В нем при каждом останове программы можно наблюдать текущие значения переменных или выражений с их использованием. 4. Для трассировки программы предназначено пошаговое выполнение программы в версиях «Пропустить блок» и «Трассировка». В первом случае подпрограмма исполняется за один шаг, а во втором происходит построчное исполнение кодов подпрограммы. 5. Если есть уверенность в правильности программы до определенной строки, то для ускорения трассировки следует использовать команду Запуск=>Запуск до курсора. 6. Для задания произвольных точек останова используются команда Запуск=>Добавить СтопТочкува=>На строку исходника и окно «СтопТочки». 7. Для контроля вызова подпрограмм используется окно «Стек вызова». 8. Для контроля состояния регистров процессора используются окно «CPU» в котором отображаются 16-ричные коды содержимого регистров процессора и значения флагов, а также окно «FPU», в котором отображаются данные о регистрах сопроцессора, выполняющего команды с плавающей точкой. 9. При каждом останове программы можно, используя команду Запуск=>Вычислить/Изменить, вычислить выражение с текущими значениями переменных, либо присвоить выбранной переменной новое значение.
94
19. Квадратное уравнение Подготовка к работе По указанной литературе изучить: 1. Cвойства компонентов Label, Button, Edit, StringGrid. 2. Cобытия onClick, onChange, onCreate. 3. Как создать код обработчика события. Контрольные вопросы 1. События onClick, onCreate. 2. Назначение и свойства компонента кнопка. 3. Назначение и свойства компонент метка. 4. Назначение и свойства Компонента однострочный редактор. 5. Как создать обработчик события onClick. 6. Как создать обработчик события onDblClick. 7. Как создать обработчик события onChange. 8. Подпрограммы. Основные понятия. Задание Создать проект “Решение квадратного уравнения”. Пример выполнения 1. Запустить Delphi. 2. Создать в ней новое приложение. 3. Присвоить свойству Caption компонента Form1 значение Решение квадратного уравнения. 4. Сохранить модуль под именем Roots, а проект под именем SQR. 5. Установить на форме компоненты: однострочные редакторы Edit1 - Edit3, метки Label1 - Label5, кнопки Button1- Button3 (все со страницы Standard). Компоненты расположить, как это показано на рис. 19.1.
рис. 19.1. Заготовка интерфейса проекта "Решение квадратного уравнения" 6. В Инспекторе объектов задать следующие свойства компонент меток Label: Name Label1 Label2 Label3 Caption * Уравнение задается Коэффициент А коэффициентами AutoSize True True False Top 136 8 48 Left 24 40 24 Height 24 24 24 Width 40 270 95 Parent Fond True False True FontName Arial FontSize 11 * Компонент Label1 предназначен для вывода значений корней квадратного ошибках.
Label4 Коэффициент B
Label5 Коэффициент C
False 48 136 24 95 True
False 48 248 24 95 True
уравнения Ax2+Bx+C=0 или сообщений об
95 7. В Инспекторе объектов задать следующие свойства компонент кнопок Button: Name Button1 Button2 Caption Вычислить Новое Top 208 208 Left 24 136 Height 25 25 Width 81 81
Button3 Завершить 208 248 25 81
8. После вышеперечисленных установок интерфейс проекта примет вид рис. 19.2.
рис. 19.2. Интерфейс проекта в режиме конструирования 2.
3. 4. 5. 6. 7.
Создать обработчик события OnCliсk для кнопки "Вычислить", в котором необходимо описать: • все переменные, используемые при вычислении корней квадратного уравнения, • процедуру преобразования текста в число для трех коэффициентов уравнения, • код вычисления коэффициентов уравнения, при вводе в соответствующее текстовое поле коэффициентов и вывода полученных корней x1 и x2 в Label1, • сообщения о некорректности задания коэффициентов уравнения при А=0, • сообщения об отсутствия решения, если дискриминант меньше 0. • процедуру преобразования числа в строку при выводе корней уравнения, Создать обработчик событий OnClik для кнопки "Новое". Он должен очищать поля редактирования от первоначальных записей и устанавливать курсор в поле ввода коэффициента при второй степени неизвестного. Создать обработчик событий OnClik для кнопки "Завершить", который завершает работу приложения. Сохранить модуль проекта под именем Prg_19_1_, а проект под именем Prg_19_1. Запустить программу командой Run, а затем вести такие коэффициенты квадратного уравнения, чтобы проверить все виды сообщений и вывода корней уравнения. Закрыть проект SQR, а затем запустить его из среды Windows и проверить на его работоспособность.
Пример выполнения Код модуля проекта: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel;
96
var
end;
Label5: TLabel; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private { Private declarations } public { Public declarations }
Form1: TForm1; implementation {$R *.DFM} // обработчик события OnCliсk для кнопки "Вычислить" procedure TForm1.Button1Click(Sender: TObject); var a,b,c:real; // коэффициенты уравнения d:real; // дискриминант x1,x2:real; // корни уравнения code:integer; // для преобразования текста в число st1,st2:string[10]; begin // ввод исходных данных из полей редактирования val(Edit1.text,a,code); // преобразование текста в число val(Edit2.text,b,code); val(Edit3.text,c,code); if a=0 then Label1.caption:='Коэффициенты при второй степени'+chr(13)+'неизвестного равен нулю!'; else begin // решение уравнения d:=b*b-4*a*c; if d