245 78 2MB
Russian Pages [191]
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
ЮЖНО-УРАЛЬСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
681.3.06(07) Т41
С.А. Тимаева
Программирование в Delphi Учебное пособие
Челябинск 2010
Министерство образования и науки Российской Федерации Южно-Уральский государственный университет Кафедра международного менеджмента
681.3.06(07) Т41
С.А. Тимаева
Программирование в Delphi Учебное пособие
Челябинск Издательский центр ЮУрГУ 2010
УДК 681.3.06:519.6(075.8) Т41
Одобрено учебно-методической комиссией международного факультета Рецензенты: Л.В. Прохорова, М.И. Хаютин
Т41
Тимаева, С.А. Программирование в Delphi: учебное пособие / С.А. Тимаева. – Челябинск: Издательский центр ЮУрГУ, 2010. – 189 с. Учебное пособие предназначено для студентов очной формы обучения специальностей 08508 «Информационный менеджмент», 220601 «Управление инновациями», 230200 «Информационные системы». В первой части пособия рассматриваются теоретические основы объектно-ориентированного программирования, работа по созданию приложений в интегрированной среде разработки, синтаксис и семантика языка программирования Delphi. В каждом разделе рассматриваются примеры для практического использования. Вторая часть пособия посвящена разработке приложений для работы с базой данных. Содержит в краткой форме теоретический материал и описание практической работы по созданию приложения по технологии step-bystep. В последней главе рассматривается практическая работа с использованием языка SQL.
УДК 681.3.06:519.6(075.8) © Издательский центр ЮУрГУ, 2010
ОГЛАВЛЕНИЕ Часть I. Delphi и работа в Интегрированной Среде Разработки..........................................6 Глава 1. Объектно-ориентированное программирование .................................................... 6 1.1. Основные понятия и определения ............................................................................... 6 1.2. Визуальное программирование интерфейса ............................................................... 8 1.3. Общие вопросы построения программ ..................................................................... 10 Глава 2. Проекты Delphi 2.1.Файлы проекта .............................................................................................................. 11 2.2.Структура файла головной программы...................................................................... 12 2.3. Окно Интегрированной Среды Разработки Delphi .................................................. 13 2.4. Панель главного меню и всплывающие меню ......................................................... 16 2.5. Форма и компоненты .................................................................................................. 17 2.5.1.Окно формы ........................................................................................................... 17 2.5.2. Окно Редактора Кода ........................................................................................... 17 2.5.3. Инспектор Объектов ............................................................................................ 18 2.6. Структура модуля приложения .................................................................................. 21 Глава 3. Элементы языка Delphi ......................................................................................... 22 3.1.Типы данных ................................................................................................................. 22 3.1.1. Целый тип ............................................................................................................. 23 3.1.2.Вещественный тип ................................................................................................ 23 3.1.3. Символьный тип ................................................................................................... 23 3.1.4. Строковый тип ...................................................................................................... 24 3.1.5. Логический тип..................................................................................................... 24 3.2. Переменная .................................................................................................................. 24 3.3. Константы .................................................................................................................... 25 3.3.1.Числовые константы ............................................................................................. 25 3.3.2. Строковые и символьные константы ................................................................. 25 3.3.3. Логические и именованные константы .............................................................. 26 3.4. Инструкция присваивания.......................................................................................... 26 3.5. Стандартные функции ................................................................................................ 29 3.5.1.Математические функции .................................................................................... 29 Глава 4. Компоненты ............................................................................................................. 31 4.1. Форма и компоненты на форме ................................................................................. 32 4.2. Событие и процедура обработки событий................................................................ 36 Глава 5. Основы программирования 5.1. Сохранение проекта, его повторное открывание ..................................................... 38 5.2. Стиль программирования ........................................................................................... 39 5.3. Порядок разработки проекта ...................................................................................... 41 5.4. Управляющие структуры языка Delphi ..................................................................... 41 5.4.1. Инструкция if ..................................................................................................... 44 5.4.2. Инструкция case ................................................................................................. 50 3
5.5. Циклы ........................................................................................................................... 57 5.5.1. Инструкция for ................................................................................................... 57 5.5.2. Инструкция while .............................................................................................. 60 5.5.3. Инструкция repeat ............................................................................................ 62 5.5.4. Инструкция goto ................................................................................................. 64 5.6. Процедуры и функции ................................................................................................ 65 5.6.1. Структура функции .............................................................................................. 66 5.6.2. Структура процедуры .......................................................................................... 67 5.6.3. Ввод и вывод данных в диалоговых окнах ........................................................ 69 5.6.4. Запись инструкций программы ........................................................................... 72 5.6.5. Отладка программы ............................................................................................. 73 5.7. Операции со строками ................................................................................................ 75 5.7.1. Стандартные функции и процедуры работы со строками ............................... 75 5.7.2. Использование операций со строками ............................................................... 76 5.8. Массивы ....................................................................................................................... 77 5.8.1. Объявление массива ............................................................................................. 77 5.8.2. Операции с массивами ......................................................................................... 79 5.8.3. Стандартные функции обработки массивов ...................................................... 85 5.8.4. Многомерные массивы ........................................................................................ 87 5.8.5. Одномерные динамические массивы ................................................................. 90 5.9. Дополнительные модули ............................................................................................ 96 5.9.1. Создание модуля .................................................................................................. 96 5.9.2. Использование модуля......................................................................................... 98 5.9.3. Включение в проект новой формы ..................................................................... 99 5.10. Файлы ....................................................................................................................... 102 5.10.1. Объявление файла ............................................................................................ 102 5.10.2. Работа с файловыми переменными ................................................................ 102 5.10.3. Ошибки открытия файла ................................................................................. 104 Часть II. Создание приложения для работы с базой данных Глава 6. Простое приложение на основе компонента Table 6.1. Структура приложения ............................................................................................. 108 6.2.Создание проекта 6.2.1. Создание базы данных ....................................................................................... 109 6.2.2. Создание проекта и начало работы .................................................................. 110 6.2.3. Навигация по таблице ........................................................................................ 113 6.3.Упорядочивание записей, работа с полями ............................................................. 117 6.4. Создание вычисляемых полей ................................................................................. 122 6.5. Фильтрация данных .................................................................................................. 124 6.5.1. Создание фильтра ............................................................................................... 124 6.5.2. Фильтрация с использованием события FilterRecord............................. 131 Глава 7. Приёмы разработки сложных приложений......................................................... 132 4
7.1. Применение модуля данных .................................................................................... 133 7.2. Компоненты отображения и редактирования данных ........................................... 137 7.3. Приложение с несколькими связанными таблицами ............................................ 141 7.4. Поля просмотра ......................................................................................................... 144 7.5. Программирование работы с базой данных ........................................................... 148 7.5.1.Пересылка записи в базу данных ....................................................................... 149 7.5.2.Использование для редактирования компонентов категории Data Controls ........................................................................................................................................ 150 7.5.2. Использование для редактирования БД компонентов категории Standard .. 155 7.5.3.Поиск записей ...................................................................................................... 158 Глава 8. Основы языка SQL и его использование в приложениях .................................. 162 8.1. Оператор выбора SELECT........................................................................................ 162 8.3. Вложенные запросы .................................................................................................. 173 8.4.Объединения таблиц .................................................................................................. 178 8.5. Операции с записями ................................................................................................ 179 8.6. Операции с таблицами .............................................................................................. 182 8.7. Операции с индексами .............................................................................................. 187 Библиографический список................................................................................................. 189
5
ЧАСТЬ I. DELPHI И РАБОТА В ИНТЕГРИРОВАННОЙ СРЕДЕ РАЗРАБОТКИ Современные версии Delphi являются одними из самых мощных систем, позволяющих на самом современном уровне создавать как отдельные прикладные программы Windows, так и разветвленные комплексы, предназначенные для работы в корпоративных сетях и в Интернете.
Глава 1. Объектно-ориентированное программирование Объектно-ориентированное программирование (сокращенно ООП) – это естественный подход к построению сложных (и не очень сложных) программ и систем. Когда вы открываете любую программу Windows, вы видите окно с множеством кнопок, разделов меню, окон редактирования, списков и т.п. Все это объекты. Причем сами по себе они ничего не делают. Они ждут каких-то событий – нажатия пользователем клавиш или кнопок мыши, перемещения курсора и т.д. Когда происходит подобное событие, объект получает сообщение об этом и как-то на него реагирует: выполняет некоторые вычисления, разворачивает список, заносит символ в окно редактирования. Вот такая программа Windows и есть объектно-ориентированная программа (для краткости в дальнейшем называем прикладные программы приложениями). 1.1. Основные понятия и определения Приложение, построенное по принципам объектной ориентации – это не последовательность каких-то операторов, не некий жесткий алгоритм. Объектноориентрованная программа – это совокупность объектов и способов их взаимодействия. Отдельным (и главным) объектом при таком подходе во многих случаях можно считать пользователя программы. Он же служит и основным, но не единственным, источником событий, управляющих приложением. Основное понятие ООП – объект. Объект хранит в себе, как правило, какие-то данные. Данные можно рассматривать как поля записи. Это характеристики объекта. Пользователь и объекты программы должны, конечно, иметь возможность читать эти данные объекта, как-то их обрабатывать и записывать в объект новые значения. Здесь важнейшее значение имеют принципы инкапсуляции и скрытия данных. Принцип скрытия данных заключается в том, что внешним объектам и пользователю прямой доступ к данным, как правило, запрещен. Делается это по двум причинам: • для надежного функционирования объекта надо поддерживать целостность и непротиворечивость его данных. Если не позаботиться об этом, то внешний объект или пользователь могут занести в объект такие неверные данные, что он начнет функционировать с ошибками; • необходимо изолировать внешние объекты от особенностей внутренней реализации данных. Для внешних потребителей данных должен быть доступен только пользовательский интерфейс – описание того, какие имеются данные и функции и как их использовать. Внутренняя реализация – это дело разработчика объекта. При таком подходе разработчик может в любой момент модернизировать объект, изменить структуру хранения и форму представления данных, но, если при этом не затронут интерфейс, внешний потребитель этого даже не заметит. И значит, во внешней программе и в поведении пользователя ничего не придется менять.
6
Чтобы выдержать принцип скрытия данных, в объекте обычно определяются процедуры и функции, обеспечивающие все необходимые операции с данными: их чтение, преобразование, запись. Эти функции и процедуры называются методами, и через них происходит общение с данными объекта. Совокупность данных и методов их чтения и записи называется свойством. Свойства можно устанавливать в процессе проектирования, их можно изменять программно во время выполнения вашей прикладной программы. Причем внешне это все выглядит так, как будто объект имеет какие-то данные, например, целые числа, которые можно прочитать, использовать в каких-то вычислениях, заложить в объект новые значения данных. В процессе проектирования вашего приложения с помощью Delphi вы можете видеть значения некоторых из этих данных в окне Инспектора Объектов, можете изменять эти значения. В действительности все обстоит иначе. Все общение с данными происходит через методы их чтения и записи. Это происходит и в процессе проектирования, когда среда Delphi запускает в нужный момент эти методы, и в процессе выполнения приложения, поскольку компилятор Delphi незримо для разработчика вставляет в нужных местах программы вызовы этих методов [1]. Помимо методов, работающих с отдельными данными, в объекте имеются методы, работающие со всей их совокупностью, меняющие их структуру. Таким образом, объект является, прежде всего, совокупностью свойств и методов. Но это пока нельзя считать законченным определением объекта, поскольку надо еще рассмотреть взаимодействие объектов друг с другом. Средой взаимодействия объектов (как бы силовым полем, в котором существуют объекты) являются сообщения, генерируемые в результате различных событий. События наступают, прежде всего, вследствие действий пользователя – перемещения курсора мыши, нажатия кнопок мыши или клавиш клавиатуры. Но события могут наступать и в результате работы самих объектов. В каждом объекте определено множество событий, на которые он может реагировать. В конкретных экземплярах объекта могут быть определены обработчики каких-то из этих событий, которые и определяют реакцию данного экземпляра объекта. К написанию этих обработчиков, часто весьма простых, и сводится основное программирование при разработке графического интерфейса пользователя с помощью Delphi. Теперь можно окончательно определить объект как совокупность свойств и методов, а также событий, на которые он может реагировать (рис. 1.1). Внешнее управление объектом осуществляется через обработчики событий. Эти обработчики обращаются к методам и свойствам объекта. Начальные значения данных объекта могут задаваться также в процессе проектирования установкой различных свойств. В результате выполнения методов объекта могут генерироваться новые события, воспринимаемые другими объектами программы или пользователем. Представление о программе как о некоторой фиксированной совокупности объектов не является полным. Чаще всего сложная программа – это не просто какая-то предопределенная совокупность объектов. В процессе работы объекты могут создаваться и уничтожаться. Таким образом, структура программы является динамическим образованием, меняющимся в процессе выполнения. Основная цель создания и уничтожения объектов – экономия ресурсов компьютера и, прежде всего, памяти. Несмотря на бурное развитие вычислительной техники, память, наверное, всегда будет лимитировать возможности сложных приложений. Это связано с тем, что сложность программных проектов растет теми же, если не более быстрыми, темпами, что и техническое обеспечение. Поэтому от объектов, которые не нужны на данной стадии выполнения программы, лучше освобождаться [1]. 7
Установки при проектировании
Свойства События
Методы Обработчики событий
События Рис. 1.1. Схема организации объекта При этом освобождаются и выделенные им области памяти, которые могут использоваться вновь создаваемыми объектами. Простой пример этого – окно-заставка с логотипом, появляющееся при запуске многих приложений. После начала реального выполнения приложения эта заставка исчезает с экрана и никогда больше не появится в данном сеансе работы. Было бы варварством не уничтожить этот объект и не освободить занимаемую им память для более продуктивного использования. В любом сколько-нибудь сложном приложении имеется также немало диалоговых окон, которые вызываются пользователем очень редко, а многими пользователями вообще никогда не вызываются. Например, почти наверняка и вы даже не видали всех диалоговых окон, предусмотренных в программе Word. А часто ли вы вызываете окно «О программе» в том же Word? Естественно, что все эти диалоговые окна бессмысленно хранить постоянно в памяти. Они создаются в тот момент, когда пользователь их вызывает, и уничтожатся после того, как пользователь закончил работу с ними. С целью организации динамического распределения памяти во все объекты заложены методы их создания – конструкторы и уничтожения – деструкторы. Конструкторы тех объектов, которые изначально должны присутствовать в приложении (прикладной программе), срабатывают при запуске программы. Деструкторы всех объектов, имеющихся в данный момент в приложении, срабатывают при нормальном (неаварийном) завершении его работы. Но нередко и в процессе выполнения различные новые объекты (например, новые окна документов) динамически создаются и уничтожаются с помощью их конструкторов и деструкторов [1]. Включать объекты в свою программу можно двумя способами: вручную включать в нее соответствующие операторы (это приходится делать не очень часто) или путем визуального программирования, используя заготовки – компоненты. 1.2. Визуальное программирование интерфейса Сколько существует программирование, столько существуют в нем и тупики, в которые оно постоянно попадает и из которых, в конце концов, выходит. Один из таких тупиков или кризисов был в свое время связан с разработкой графического интерфейса пользователя. Программирование вручную всяких привычных для пользователя окон, кнопок, меню, обработка событий мыши и клавиатуры, включение в программы изображений и звука требовало все больше и больше времени программиста. В ряде слу8
чаев весь этот сервис начинал занимать до 80-90%. Выход из этой ситуации обозначился благодаря двум подходам. Первый из них – стандартизация многих функций интерфейса, благодаря чему появилась возможность использовать библиотеки, имеющиеся, например, в Windows. В частности, появился API Windows – интерфейс, в котором описано множество функций, причем от версии к версии набор функций расширяется, внутреннее описание функций совершенствуется, но формы вызова функций не изменяются. В итоге, при смене стиля графического интерфейса (например, при переходе от Windows 3.x к Windows 95, а затем к Windows 2000 и ХР) приложения смогли автоматически приспосабливаться к новой системе без какого-либо перепрограммирования. На этом пути создались прекрасные условия для решения одной из важнейших задач совершенствования техники программирования – повторного использования кодов. Однажды разработанные вами формы, компоненты, функции могли быть впоследствии неоднократно использованы вами или другими программистами для решения их задач. Каждый программист получил доступ к наработкам других программистов и к огромным библиотекам, созданным различными фирмами. Причем была обеспечена совместимость программного обеспечения, разработанного на разных алгоритмических языках [1]. Вторым революционным шагом, кардинально облегчившим жизнь программистов, явилось появление визуального программирования, возникшего в Visual Basic и нашедшего блестящее воплощение в Delphi и C++Builder фирмы Borland. Визуальное программирование позволило свести проектирование пользовательского интерфейса к простым и наглядным процедурам, которые дают возможность за минуты или часы сделать то, на что ранее уходили месяцы работы. В современном виде в Delphi это выглядит так. Вы работаете в Интегрированной Среде Разработки (ИСР или Integrated development environment – IDE) Delphi. Среда предоставляет вам формы (в приложении их может быть несколько), на которых размещаются компоненты. Обычно это оконная форма, хотя могут быть и невидимые формы. На форму с помощью мыши переносятся и размещаются пиктограммы компонентов, имеющихся в библиотеках Delphi. С помощью простых манипуляций вы можете изменять размеры и расположение этих компонентов. При этом вы все время в процессе проектирования видите результат – изображение формы и расположенных на ней компонентов. Вам не надо мучиться, многократно запуская приложение и выбирая наиболее удачные размеры окна и компонентов. Результаты проектирования вы видите, даже не компилируя программу, немедленно после выполнения какой-то операции с помощью мыши. Но достоинства визуального программирования не сводятся к этому. Самое главное заключается в том, что во время проектирования формы и размещения на ней компонентов Delphi автоматически формирует коды программы, включая в нее соответствующие фрагменты, описывающие данный компонент. А затем в соответствующих диалоговых окнах пользователь может изменить заданные по умолчанию значения каких-то свойств этих компонентов и, при необходимости, написать обработчики какихто событий. То есть проектирование сводится, фактически, к размещению компонентов на форме, заданию некоторых их свойств и написанию, при необходимости, обработчиков событий. Компоненты могут быть визуальные, видимые при работе приложения, и невизуальные, выполняющие те или иные служебные функции. Визуальные компоненты сразу видны на экране в процессе проектирования в таком же виде, в каком их увидит пользователь во время выполнения приложения. Это позволяет очень легко выбрать место их расположения и их дизайн – форму, размер, оформление, текст, цвет и т.д. 9
Невизуальные компоненты видны на форме в процессе проектирования в виде пиктограмм, но пользователю во время выполнения они не видны, хотя и выполняют для него за кадром весьма полезную работу. В библиотеки визуальных компонентов Delphi включено множество типов компонентов, и их номенклатура очень быстро расширяется от версии к версии. Компоненты библиотек Delphi и типы других объектов оформляются в виде классов. Классы – это типы, определяемые пользователем. В классах описываются свойства объекта, его методы и события, на которые он может реагировать. Язык Delphi предусматривает только инструментарий создания классов. А сами классы создаются разработчиками программного обеспечения. Создатели Delphi уже разработали множество очень полезных классов и включили их в библиотеки системы. Этими классами можно пользоваться при работе в Интегрированной Среде Разработки. Впрочем, это нисколько не мешает создавать пользователям свои новые классы. Если бы при создании нового класса пришлось все начинать с нуля, то эффективность этого занятия была бы под большим сомнением. Да и разработчики Delphi вряд ли создали бы в этом случае такое множество классов. Действительно, если представить себе, что при разработке нового компонента, например, какой-нибудь новой кнопки, вам пришлось бы создавать все с нуля: рисовать ее изображение, описывать все свойства, определяющие ее место расположения, размеры, надписи и картинки на ее поверхности, цвет, шрифты, описывать методы, реализующие ее поведение — изменение размеров, видимость, реакции на сообщения, поступающие от клавиатуры и мыши, то скорее всего, пользователи отказались бы от разработки новой кнопки. В действительности все обстоит гораздо проще, благодаря одному важному свойству классов – наследованию. Новый класс может наследовать свойства, методы, события своего родительского класса, т.е. того класса, на основе которого он создается. Например, при создании новой кнопки можно взять за основу один из уже разработанных классов кнопок и только добавить к нему какие-то новые свойства или отменить какие-то свойства и методы родительского класса. Благодаря визуальному объектно-ориентированному программированию была создана технология, получившая название быстрая разработка приложений, поанглийски RAD — Rapid Application Development. Эта технология характерна для современных систем программирования, к которым относится Delphi [1]. 1.3. Общие вопросы построения программ Программа, которую строит Интегрированная Среда Разработки (ИСР) Delphi в процессе проектирования приложения, основана на модульном принципе. Сама головная программа получается предельно простой и короткой. Она состоит из объявления списка используемых модулей и нескольких операторов, которые создают объекты тех форм, которые задумал разработчик, и запускают выполнение приложения. Принцип модульности очень важен для создания надежных и относительно легко модифицируемых и сопровождаемых приложений. Четкое соблюдение принципов модульности в сочетании с принципом скрытия информации позволяет внутри любого модуля проводить какие-то модификации, не затрагивая при этом остальные модули и головную программу. Все объекты компонентов размещаются в объектах – формах. Для каждой формы, которую вы проектируете в своем приложении, Delphi создает отдельный модуль. Именно в модулях и осуществляется программирование задачи. В обработчики событий объектов – форм и компонентов, вы помещаете все свои алгоритмы. В основном они сводятся к обработке информации, содержащейся в свойствах одних объектов, и 10
задании по результатам обработки свойств других объектов. При этом вы постоянно обращаетесь к методам различных объектов.
Глава 2. Проекты Delphi 2.1.Файлы проекта Проекты Delphi могут объединяться в группы. В одну группу имеет смысл включать проекты, связанные друг с другом или объединенные одной тематикой.
Рис. 2.1. Окно Менеджера проектов Корневая вершина ProjectGroupl (рис. 2.1) – это вершина группы проектов. Информация о ней хранится в файле с расширением .bdsgroup (.group-prog в Delphi 2007) и в файле с двойным расширением .bdsgroup.local (.groupprog.local). Оба файла – текстовые в формате XML. В группу может входить ряд проектов одного или разных типов. А в данном разделе остановимся только на наиболее часто встречающемся типе проектов, создающих исполняемый модуль .ехе и использующих графический интерфейс в виде форм. Информация о каждом проекте хранится в нескольких файлах, имеющих расширения .bdsproj (.dproj), .bdsproj.local (.dproj.local), .cfg, .res, .dpr. Все перечисленные файлы, кроме .res, – текстовые. Все они создаются в ИСР Delphi автоматически. Из них интерес для разработчика может представлять (и то не всегда) только файл .bdsproj (.dproj), содержащий код головной программы проекта. Когда вы хотите открыть в ИСР Delphi какой-то существующий проект, удобнее всего открывать файл .dpr. В проекте может быть несколько модулей (например модули: Unitl и Unit2). Модуль может содержать нескольких файлов. Это, прежде всего, файл с расширением .pas, в котором пишется задуманный код модуля. Модуль, связанный с формой, имеет, кроме того, файл с расширением .dfm, содержащий описание внешнего вида формы и описание размещенных на ней компонентов. Модуль может содержать также некоторые вспомогательные файлы.
11
Превращение проекта в исполняемый файл происходит в два этапа. Сначала проводится компиляция, которая проверяет правильность кода и создает для каждого модуля двоичный объектный файл, имеющий расширение .dcu. Затем осуществляется компоновка приложения, которая объединяет объектные файлы в единый исполняемый файл приложения .ехе. 2.2.Структура файла головной программы В процессе проектирования приложения Delphi автоматически создает код головной программы и отдельных модулей. В модули вы вводите свой код, создавая обработчики различных событий. Но головную программу, как правило, вы не трогаете и даже не видите ее текст. Только в исключительных случаях вам надо что-то изменять в тексте головной программы, сгенерированном Delphi. Тем не менее, хотя бы ради этих исключительных случаев, надо все-таки представлять вид головной программы и понимать, что означают ее операторы. Увидеть код головной программы вы можете или выполнив команду Project View Source, или открыв файл проекта с расширением .bdsproj. Типичная головная программа приложения имеет вид:
program Projectl; uses Forms, Unitl in 'Unitl.pas' {Forml}, Unit2 in 'Unit2.pas' {Form2}; {$R *.res} {Здесь вы можете поместить описания каких-то констант, переменных, функций, процедур. Все это будет доступно только в пределах данного файла} begin Application.Initialize; Application.MainFormOnTaskbar:=True;//Только в Delphi 2007 Application.CreateForm(TForml, Forml); Application.CreateForm(TForm2, Form2); Application.Run; end. Начинается программа с program, после которого пишется имя программы. Оно совпадает с именем файла, в котором вы сохранили свой проект. Это же имя присваивается выполняемому файлу приложения. По умолчанию это имя Projectl.
Всегда сохраняйте проект под каким-то осмысленным именем, изменяя тем самым
имя проекта, заданное Delphi по умолчанию. Иначе можно запутаться в бесконечных программах Projectl, лежащих в различных ваших каталогах. После заголовка в тексте программы располагается предложение uses. В этом предложении перечисляются модули, загружаемые программой. Первый модуль Forms – системный. А следующие – модули разработанных вами форм. Данный пример подразумевает, что вы создали в проекте две формы с именами Forml и Form2 в модулях с именами Unitl и Unit2. Помещенные в фигурные скобки названия форм – это комментарии.
12
Следующая строка текста – {$R *.RES} представляет собой директиву компилятора. Затем после ключевого слова begin и до последнего завершающего программу оператора end с точкой (end.) записано тело программы. Первый оператор в теле программы инициализирует приложение (в Delphi 2007 это два оператора), два следующих – создают объекты форм Forml и Form2, последний – начинает выполнение приложения. Если вам надо ввести какой-то свой текст в головную программу, вы можете сделать это, введя описания необходимых констант, переменных, функций и процедур в место программы, отмеченное соответствующим комментарием в приведенном выше тексте. Кроме того, вы можете добавить или изменить операторы в теле программы. Например, вам может потребоваться при запуске приложения на выполнение провести какие-то настройки (например, настроить формы на тот или иной язык – русский или английский). Или сделать какой-то запрос пользователю, и в зависимости от ответа создавать или не создавать те или иные формы. Пусть, например, вы хотите, чтобы вторая форма вашего приложения Form2 создавалась только в случае, если при запуске приложения через командную строку в него передана опция Y. В этом случае вы можете заменить приведенный выше оператор
Application.CreateForm(TForm2,
Form2);
оператором if (ParamStr(1)='Y') then Application.CreateForm(TForm2, Form2); Этот оператор анализирует функцией ParamStr первый параметр командной строки. Если приложение Projectl будет запускаться командой «Projectl Y», то форма Form2 будет создаваться. В остальных случаях этой формы не будет. Вы можете ввести в головной файл и другие операторы, функции, процедуры. Все это можно сделать, но это будет плохой стиль программирования, поскольку он противоречит принципу модульности. Выше уже говорилось о важности соблюдения этого принципа. Все необходимые вам в начале выполнения процедуры и функции настройки помещайте в отдельный модуль без формы [1]. 2.3. Окно Интегрированной Среды Разработки Delphi Если вы запускаете Delphi в первый раз, это окно будет иметь вид (рис. 2.2). В центре экрана находится страница приветствия Welcome Page. Раздел Recent Projects (Последние проекты) этой страницы позволяет открыть один из тех проектов, с которыми вы работали в последнее время. При первом запуске Delphi этот раздел будет пустым. Кнопка New Project (Новый проект) позволяет начать новый проект, кнопки Open Project (Открыть проект) и Open File (Открыть файл) открывают соответственно существующий проект или файл. Раздел Help открывает окно справки Delphi. В описываемом режиме, следует отметить окно Tool Palette (Палитра Инструментов), расположенное в нижнем правом углу экрана. Содержимое этого окна изменяется в зависимости от того, какую проектную операцию вы выполняете в данный момент. При просмотре страницы приветствия в Палитре Инструментов отображается список проектов, которые вы можете начать, щелкнув на соответствующем разделе.
13
Рис. 2.2. Окно ИСР при открытой странице приветствия По команде главного меню File New, и выбору из списка раздела VCL Forms Application – Delphi for Win32 окно изменяет вид (рис. 2.3).
Рис. 2.3. Окно ИСР при открытом проекте В верхней левой части окна ИСР располагается панель главного меню. Ее состав несколько зависит от варианта Delphi, с которым вы работаете. Ниже панели главного меню и справа от нее расположен ряд инструментальных панелей. Они включают в себя наборы быстрых кнопок, дублирующих некоторые наиболее часто используемые команды меню. Самая правая панель в верхнем ряду, расположенная на уровне полосы главного меню, содержит выпадающий список и две быстрые кнопки. Это панель сохранения и выбора различных конфигураций окна ИСР, которые вы сами можете создавать и запоминать. 14
В основном поле окна слева располагаются две панели. Верхняя из них – окно Structure (рис. 2.4), отображающее иерархическую связь визуальных и невизуальных компонентов и объектов создаваемого приложения.
Рис. 2.4. Окно структуры Ниже расположено окно Инспектора Объектов (Object Inspector). Это основной инструмент, с помощью которого можно задавать свойства компонентов и обработчики событий. Более подробно об этом будет сказано позже. В середине экрана – поверхность проектирования. В верхней части имеются закладки, позволяющие перемещаться между открытыми файлами проектов. Если на поверхности проектирования выделен файл проекта, то внизу видны три закладки: Code – переключение в Редактор Кода, Design – переключение в режим визуального проектирования формы, и History – страница управления версиями проекта. В правой части экрана (см. рис. 2.3) расположены друг под другом два окна. Верхнее окно – это многостраничная панель, содержащая страницы Project Manager, Model View и Data Explorer. Страница Project Manager (Менеджер Проектов) позволяет управлять проектами. Страница Model View (Просмотр модели) позволяет взглянуть на проект с точки зрения языка Unified Modeling Language (UML) – хорошего инструмента, создающего представление об организации кода вашего приложения. Страница Data Explorer содержит информацию о доступных приложению базах данных. Под этой панелью расположено окно Палитры Инструментов Tool Palette (рис.2.5). Ее состав меняется в зависимости от того, что именно просматривается в данный момент на поверхности проектирования [1].
Рис. 2.5. Окно палитры инструментов 15
2.4. Панель главного меню и всплывающие меню Разделы меню File (файл) позволяют создать новый проект, новую форму, фрейм, модуль данных, открыть ранее созданный проект или форму, сохранить проекты или формы в файлах с заданными именами. Разделы меню Edit (правка, редактирование) позволяют выполнять обычные для приложений Windows операции обмена с буфером Clipboard, а также дают возможность выравнивать группы размещенных на форме компонентов по размерам и местоположению. Разделы меню Search (поиск) позволяют осуществлять в коде вашего приложения поиск и контекстные замены, которые свойственны большинству известных текстовых редакторов. Разделы меню View (просмотр) позволяют вызывать на экран различные окна, необходимые для проектирования. Меню Refactor (рефакторинг) содержит разделы, облегчающие различные структурные преобразования кода: переименование идентификаторов, преобразование фрагмента кода в метод, объявления переменных и элементов класса и т.п. Разделы меню Project (проект) позволяют добавлять и убирать из проекта формы, задавать опции проекта, компилировать проект без его выполнения и делать много других полезных операций. Меню Run (выполнение) дает возможность выполнять проект в нормальном или отладочном режимах, продвигаясь по шагам, останавливаясь в указанных точках кода, просматривая значения переменных и т.д. Меню Component (компонент) позволяет создавать и устанавливать новые компоненты, конфигурировать палитру компонентов, работать с пакетами packages. Меню Tools (инструментарий) позволяет выполнять настройки ИСР и вызывать различные вспомогательные программы, например, вызывать Редактор Изображений (Image Editor), работать с программами, конфигурирующими базы данных и т.д. Кроме того, в это меню можно самим включить любые разделы, вызывающие те или иные приложения, и таким образом расширить возможности главного меню Delphi, приспособив его для своих задач. Меню StarTeam дает доступ к возможностям мощной системы контроля версий, облегчающей разработку крупных проектов. Меню Window (окно) позволяет ориентироваться среди массы окон, обычно одновременно открытых в процессе проектирования, и переключаться в нужное окно. Меню Help (справка) содержит разделы, помогающие работать со встроенной в Delphi справочной системой. Кроме этого в Delphi имеется система контекстных всплывающих меню, которые появляются, если пользователь поместил курсор мыши в том или ином окне или на том или ином компоненте и щелкнул правой кнопкой мыши. Большинство разделов этих контекстных меню дублируют основные разделы главного меню. Однако во всплывающих меню в ряде случаев имеются разделы, отсутствующие в главном меню. До многих инструментов, используемых для работы с некоторыми компонентами, можно добраться только через всплывающие меню [1].
Полезно в процессе работы почаще щелкать правой кнопкой мыши. Это ускорит выполнение многих проектных операций.
16
2.5. Форма и компоненты Чтобы перенести компонент на форму из открытой соответствующей категории палитры необходимо выделить курсором мыши необходимый компонент. Поместить выбранный компонент на форму очень просто – надо сделать щелчок мышью в нужном месте формы. Есть и другой способ поместить компонент на форму – достаточно сделать двойной щелчок на пиктограмме компонента, и он автоматически разместится в центре вашей формы. Наконец, третий вариант – перетащить компонент на форму с помощью мыши и отпустить кнопку мыши в том месте формы, в котором вы хотите его поместить. Если вы выбрали компонент, а затем изменили ваше намерение размещать его, вам достаточно нажать кнопку указателя. Это прервет процесс размещения компонента, и программа вернется в нормальный режим, в котором вы можете выбирать другой компонент или выполнять какую-то команду. 2.5.1.Окно формы Основой почти всех приложений Delphi является форма. Ее можно понимать как типичное окно Windows. Форма является основой, на которой размещаются другие компоненты. В качестве примера на рис. 2.6 показана форма с расположенными на ней компонентами для вычисления стоимости поездки на дачу.
Рис. 2.6. Форма приложения Форма имеет те же свойства, что присущи другим окнам Windows. Она имеет управляющее меню в верхнем левом углу, полосу заголовка, занимающую верхнюю часть, кнопки развертывания, свертывания и закрытия окна в верхнем правом углу. Можно изменить вид окна, убрав в нем какие-то кнопки или всю полосу заголовка, сделав его окном с неизменяемыми размерами и т.п. Во время проектирования форма покрыта сеткой из точек. В узлах этой сетки размещаются те компоненты, которые вы помещаете на форму. Во время выполнения приложения эта сетка, конечно, не видна. В некоторых случаях при разработке какого-то модуля форма может оказаться вообще ненужной. Но обычно вся работа в Delphi проводится именно на форме. 2.5.2. Окно Редактора Кода Одной из наиболее важных частей среды Delphi является окно Редактора Кода. Чтобы переключится в это окно, надо выбрать на поверхности проектирования закладку Code. Перед вами откроется окно Редактора Кода (рис.2.7). Редактор Кода является полноценным программным редактором. Его можно настраивать на различный стиль работы, который является более привычным. В редакторе применяется выделением цветом и шрифтом синтаксических элементов. Жирным шрифтом выделяются ключевые слова того языка программирования, с которым идёт работа. Зеленым курсивом выделяются комментарии (см. рис.2.7), например, это ком17
ментарий {Private declarations}. Синим цветом выделяются числа и строковые константы. В нижней части окна Редактора Кода расположена строка состояния. На второй панели находится индикатор строки и колонки. Это помогает понимать, в каком месте кода в данный момент находится курсор. Третья панель строки состояния – индикатор режима вставки. Это стандартный индикатор большинства редакторов, который показывает, будут ли вводимые символы вставляться в текст или писаться поверх текста. Переключение режима вставки производится клавишей Insert.
Рис. 2.7. Окно Редактора Кода Четвертая панель строки – индикатор модификации. Когда вы начинаете новый проект, то код, который Delphi автоматически написала для вас, еще не сохранен. Вы должны сделать это сами командой File Save. Если код изменялся вами или Delphi с того момента, когда вы в последний раз сохраняли его в файле, то в индикаторе модификации появляется слово «Modified». Это слово показывает, что код, который вы видите, не тот же самый, что на диске. В окно Редактора Кода, как и в другие окна Delphi, встроена контекстная справка. Чтобы получить справку по какому-то слову кода (ключевому слову, написанному имени функции и т.п.), достаточно установить курсор на это слово и нажать клавишу F1. Вам будет показана соответствующая тема справки. 2.5.3. Инспектор Объектов Инспектор Объектов (Object Inspector) – основной инструмент, с помощью которого можно задавать свойства компонентов и писать обработчики событий. Окно Инспек18
тора Объектов (рис. 2.8) имеет две страницы. В верхней части окна расположен выпадающий список всех компонентов, помещенных на форме. В нем вы можете выбрать тот компонент, свойства и события которого вас интересуют. Страница свойств (Properties) Инспектора Объектов показывает свойства того объекта, который в данный момент выделен вами. Щелкните на окне пустой формы, и на странице свойств Инспектора Объектов вы сможете увидеть свойства формы (см. рис. 2.8). По умолчанию эти свойства сгруппированы по категориям.
а б в Рис. 2.8. Инспектор Объектов (страница свойств, упорядоченная по категориям, по алфавиту и страница событий) Категории выделены в окне Инспектора Объектов жирным красным шрифтом. Например, в категорию Action собраны свойства, отображающие действия, связанные с компонентом, в категорию Layout – свойства, связанные с размещением компонента на форме и т.д. Около каждого названия категории имеется значок «+» или «-», позволяющий раскрыть или свернуть относящийся к категории список свойств. Некоторые свойства могут попасть одновременно в несколько категорий, например, свойство Caption (см. рис. 2.8) . Это не имеет значения, поскольку изменение значения свойства в любой категории приводит к синхронному изменению этого свойства во всех остальных категориях. Можно сделать какие-то категории невидимыми, чтобы сократить число отображаемых свойств и проще находить среди них нужные. Для этого щелкните в окне Инспектора Объектов правой кнопкой мыши. Во всплывшем меню вы можете выбрать раздел View. Вам будет показан ряд категорий. Около каждой категории имеется индикатор. Вы можете включить индикаторы только у некоторых категорий и тогда в Инспекторе Объектов вы увидите события и свойства только указанных категорий. Выбор раздела Toggle переключит видимость разделов: те, которые были видимы, станут не19
видимы и наоборот. Выбор раздела All сделает видимыми все свойства и события, а выбор раздела None сделает все события и свойства невидимыми. Внизу окна Инспектора Объектов указывается, сколько свойств или событий невидимо в данный момент или видимы все – All shown (см. рис. 2.8). В том же меню, всплывающем при щелчке правой кнопкой мыши в окне Инспектора Объектов, можно выбрать раздел Arrange и в нем установить одну из двух возможностей: by Name – упорядочить свойства и события в алфавитной последовательности их имен, или by Category – упорядочить их по категориям. При упорядочивании по алфавиту форма представления свойств и событий кардинально меняется – все располагается по алфавиту (см. рис. 2.8 б). Вы можете изменять свойства, отображаемые в окне Инспектора Объектов. Например, измените свойство Caption (надпись) вашей формы, написав в нем «Моя форма». Вы увидите, что эта надпись появится в полосе заголовка вашей формы. Если щелкнуть на некоторых свойствах, например, на свойстве Color (цвет), то справа от имени свойства откроется окно выпадающего списка. Нажав в нем на кнопочку со стрелкой вниз, вы можете увидеть список возможных значений свойства. Например, смените значение свойства Color с принятого по умолчанию clBtnFace – цвета поверхности кнопок на clWindow – цвет окна. Вы увидите, что поверхность формы изменит свой цвет. Рядом с некоторыми свойствами располагается знак плюс, например, свойство BorderIcons. Это означает, что данное свойство является объектом, который в свою очередь имеет ряд свойств. Так же свойство Font (шрифт) имеет знак плюс. Если щёлкнуть на этом плюсе или сделать двойной щелчок на свойстве Font, то откроется таблица таких свойств, как Color (цвет), Height (высота), Name (имя шрифта) и др. Среди них есть свойство Style (стиль), около которого тоже имеется знак плюс. Щелчок на этом плюсе или двойной щелчок на этом свойстве раскроет дополнительный список подсвойств, в котором можно, например, установить в true свойство fsBold (жирный). Кстати, для смены true на false и обратно в подобных булевых свойствах не обязательно выбирать значение из выпадающего списка. Достаточно сделать двойной щелчок на значении свойства, и оно изменится. После того как вы просмотрели или изменили подсвойства, вы можете опять сделать двойной щелчок на головном свойстве или щелчок на знаке минус около него, и список подсвойств свернется. Страница событий (Events) составляет вторую часть Инспектора Объектов (см. рис. 2.8 в). На ней указаны все события, на которые может реагировать выбранный объект. Например, если вам надо выполнить какие-то действия в момент создания формы (обычно это различные операции настройки), то вы должны выделить событие OnCreate. Рядом с именем этого события откроется окно с выпадающим списком. Если вы уже написали в своем приложении какие-то обработчики событий и хотите при событии OnCreate использовать один из них, вы можете выбрать необходимый обработчик из выпадающего списка. Если же вам надо написать новый обработчик, то сделайте двойной щелчок на пустом окне списка. Вы попадете в окно Редактора Кода, в котором увидите текст:
procedure TForml.FormCreate(Sender: TObject); begin end;
20
При этом курсор будет расположен в пустой строке между ключевыми словами begin и end. Увиденный код – это заготовка обработчика события, которую автоматически сделала Delphi. Вам остается только в промежутке между begin и end написать необходимые операторы. Если вы сделали эти операции, то вернитесь в Инспектор Объектов, выделите в нем, например, событие OnActivate, и нажмите в нем кнопку выпадающего списка. Вы увидите в нем введенный вами ранее обработчик события OnCreate. Если вам надо использовать тот же самый обработчик и в событии OnActivate, просто выберите его из списка. Таким образом вы можете избежать дублирования в программе одних и тех же фрагментов кода. Пользуясь Инспектором Объектов, вы можете получить контекстную справку по свойствам или событиям. Для этого выделите в окне Инспектора Объектов интересующее вас свойство или событие и нажмите клавишу F1 [1]. 2.6. Структура модуля приложения Тексты модулей в приложении имеют определённую структуру. Ниже приведен текст модуля с пустой формой. Подробные комментарии в этом тексте поясняют, куда и что в этот код можно добавлять. unit Unitl; interface // Открытый интерфейс модуля
/ / Список подключаемых модулей uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;
/ / Объявление класса формы type TForml = class(TForm) private // Закрытый раздел класса { Private declarations } {Сюда могут
помещаться объявления переменных, функций и процедур, включаемых в класс формы, но не доступных для других модулей} public // Открытый раздел класса { Public declarations } {Сюда могут помещаться объявления переменных, функций и процедур, включаемых в класс формы и доступных для других модулей} end; {Сюда могут помещаться объявления типов, констант, переменных, функций и процедур, к которым будет доступ из других модулей, но которые не включаются в класс формы} implementation // Реализация модуля {$R *.dfm} {Сюда могут помещаться предложения uses, объявления типов, констант, переменных, к которым не будет доступа из других модулей. Тут же должны быть реализации всех объявленных в разделе interface функций и процедур, а также могут быть реализации любых дополнительных, не объявленных ранее функций и процедур.} end.
21
Модуль начинается с ключевого слова unit, после которого пишется имя модуля. Оно совпадает с именем файла, в котором вы сохранили свой модуль. По умолчанию для первого модуля имя равно Unitl, для второго Unit2 — и т.д.
Если в приложении несколько модулей, следует сохранять их файлы под какими-
то осмысленными именами, изменяя тем самым имена модулей, заданные Delphi по умолчанию. Проще будет работать с осмысленными именами, а не с именами Unitl, Unit2, Unit3, которые ни о чем не говорят. Текст модуля состоит из двух основных разделов: interface – открытый интерфейс модуля, и implementation – реализация модуля. Все, что помещается непосредственно в раздел interface (типы, переменные, константы, функции, процедуры), может быть использовано другими модулями программы. Все, что помещается в раздел implementation – внутреннее дело модуля. Внешние модули не могут видеть типы, переменные, константы, функции и процедуры, размещенные в разделе реализации. В разделе interface после предложения uses, содержащего список подключаемых модулей, можно увидеть заготовку объявления класса вашей формы, подготовленную Delphi. Имя класса вашей формы – TForm1. Класс содержит два раздела: private – закрытый раздел класса, и public – открытый раздел класса. То, что вы или Delphi объявите в разделе public, будет доступно для других классов и модулей. То, что объявлено в разделе private, доступно только в пределах данного модуля. После завершения объявления класса формы находятся строки var Form1: TForm1; Это объявляется переменная Form1 класса TForm1, т.е. объявляется ваша форма как объекта класса TForm1. Затем следует пока пустой раздел реализации implementation, в котором содержится только директива компилятора. Вообще говоря, для работы этот смысл знать не обязательно. Необходимо следить только за тем, чтобы случайно не стереть эту директиву.
Глава 3. Элементы языка Delphi В среде программирования Delphi для записи программ используется язык программирования Delphi. Программа на Delphi – это последовательность инструкций, которые часто называют операторами. Одна инструкция от другой отделяется точкой с запятой. Каждая инструкция состоит из идентификаторов. Идентификатор может обозначать: • инструкцию языка (:=, if, while, for); • переменную; • константу (целое или дробное число); • арифметическую (+,-,*,/) или логическую (and,or,not) операцию; • подпрограмму (процедуру или функцию); • отмечать начало (procedure, function) или конец (end) подпрограммы или блока (begin,end). 3.1.Типы данных Программа может оперировать данными различных типов: целыми и дробными числами, символами, строками символов, логическими величинами. 22
3.1.1. Целый тип Язык Delphi поддерживает семь целых типов данных, описание которых приведено в табл. 3.1. Таблица 3.1 Целые типы
Тип
Диапазон
Требование к памяти в байтах
Shortint Smallint
-128 ÷127 -32 768 ÷ 32 767
1 2
Longint
-2 147 483 648 ÷ 2 147 483 647
4
Int64
-263 ÷ 2 63 - 1
8
Byte
0 ÷ 255
1, беззнаковый
Word Longword
0÷ 65 535 0 ÷ 4 294 967 295
2, беззнаковый 4, беззнаковый
Родовой тип (обеспечивающий максимальную производительность) – Integer, который эквивалентен в настоящее время Longint. 3.1.2.Вещественный тип Delphi поддерживает 6 вещественных типов. Типы различаются между собой диапазоном допустимых значений, количеством значащих цифр и количеством байтов, необходимых для хранения данных в памяти компьютера (табл. 3.2). Таблица 3.2 Вещественные (дробные) типы Тип Real48
-2.9 · 10-39 ÷ 1,7 · 1038
Значащих цифр 11 –12
Single
-3.5 · 1038 ÷ 3.4 · 1038
7–8
4
Double
-1.8 · 10308 ÷ 1.8 · 10308
15 – 16
8
-1.1 · 104951 ÷ 1.1 · 104932
19 – 20
10
-263 +1 ÷ 262-1
19 – 20
8
Extended Comp
Диапазон
Байтов 6
-922 337 203 685 477.5808 ÷ 19 – 20 13 -922 337 203 658 477.5807 Родовой тип – Real, который эквивалентен в настоящее время Double. Тип Currency используется для представления денежных величин. В памяти он хранится как масштабированное в 10000 раз 8-байтовое целое. Благодаря этому при операциях с величинами этого типа минимизируются ошибки округления, что очень важно для денежных расчётов. 3.1.3. Символьный тип Язык Delphi поддерживает два символьных типа: Ansichar и Widechar: Currency
23
• тип Ansichar – это символы в кодировке ANSI, которым соответствуют числа в диапазоне от 0 до 255; • тип Widechar – это символы в кодировке Unicode, им соответствуют числа от 0 до 65 535. Delphi поддерживает и наиболее универсальный символьный тип – Char, который эквивалентен AnsiChar. 3.1.4. Строковый тип Язык Delphi поддерживает три строковых типа: ShortString, LongString и WideString: • тип ShortString представляет собой статически размещаемые в памяти компьютера строки длиной от 0 до 255 символов; • тип AnsiString представляет собой длинную строку; • тип WideString представляет собой динамически размещаемые в памяти строки, длина которых ограничена только объемом свободной памяти. Каждый символ строки типа WideString является Unicode-символом. В Delphi для обозначения строкового типа допускается использование идентификатора string. Тип string имеет разный смысл в зависимости от директивы компилятора $H. По умолчанию string интерпретируется как AnsiString. 3.1.5. Логический тип Логическая величина может принимать одно из двух значений True (истина) или False (ложь). В языке Delphi логические величины относят к типу Boolean. 3.2. Переменная Переменная – это область памяти, в которой находятся данные, которыми оперирует программа. Когда программа манипулирует с данными, она, фактически, оперирует содержимым ячеек памяти, т. е. переменными. Чтобы программа могла обратиться к переменной (области памяти), например, для того, чтобы получить исходные данные для расчета по формуле или сохранить результат, переменная должна иметь имя. Имя переменной задаёт программист. В качестве имени переменной можно использовать последовательность из букв латинскою алфавита, цифр и некоторых специальных символов. Первым символом в имени переменной должна быть буква. Пробел в имени переменной использовать нельзя. Компилятор языка Delphi не различает прописные и строчные буквы в именах переменных, поэтому имена SUMMA, Summa и summa обозначают одну и ту же переменную. Желательно, чтобы имя переменной было логически связано с ее назначением. Например, переменным, предназначенным для хранения коэффициентов и корней квадратного уравнения, которое в общем виде традиционно записывают aх2 + bх + с = 0 вполне логично присвоить имена а, ь, с, x1 и х2. Другой пример. Если в программе есть переменные, предназначенные для хранения суммы покупки и величины скидки, то этим переменным можно присвоить имена TotalSumm и Discount или ObSumma и Skidka.
В Delphi каждая переменная перед использованием должна быть объявлена. С по-
мощью объявления устанавливается не только факт существования переменной, но и задается ее тип, чем указывается и диапазон допустимых значений. В общем виде инструкция объявления переменной выглядит так: 24
Имя : тип; где: • Имя– имя переменной; • тип – тип данных, для хранения которых предназначена переменная. Пример: а : Real; b : Real; i : Integer; В приведенных примерах объявлены две переменные типа real и одна переменная типа integer.
В тексте программы объявление каждой переменной, как правило, помещают на
отдельной строке. Если в программе имеется несколько переменных, относящихся к одному типу, то имена этих переменных можно перечислить в одной строке через запятую, а их тип указать после имени последней переменной через двоеточие. Например: a,b,c : Real; xl,x2 : Real; 3.3. Константы В языке Delphi существует два вида констант: обычные и именованные. Обычная константа – это целое или дробное число, строка символов или отдельный символ, логическое значение. 3.3.1.Числовые константы В тексте программы числовые константы записываются обычным образом, т.е. так же, как числа, например, при решении математических задач. При записи дробных чисел для разделения целой и дробных частей используется точка. Если константа отрицательная, то непосредственно перед первой цифрой ставится знак "минус". Например, числовые константы:
175 0.0 -624.01 0 Дробные константы могут изображаться в виде числа с плавающей точкой. Представление в виде числа с плавающей точкой основано на том, что любое число может быть записано в алгебраической форме как произведение числа, меньшего 10, называемое мантиссой, и степени десятки, именуемой порядком (табл.3.3) [3]. Таблица 3.3 Примеры записи дробных чисел Число Алгебраическая форма Форма с плавающей точкой 1000 000 1x106 1.0000000000Е+06 2 -123.452 -1,23452x10 -1.2345200000Е+02 -3 0,0056712 5,6712х10 5.6712000000Е-03 3.3.2. Строковые и символьные константы Строковые и символьные константы заключаются в кавычки. Например: 'Язык программирования Delphi', 'Delphi 2007' '2.8' 'K' 25
Константа '2.8'. Это символьная константа, т. е. строка символов, которая изображает число "две целых, восемь десятых", а не число 2,8. 3.3.3. Логические и именованные константы Логическое высказывание (выражение) может быть либо истинно, либо ложно. Истине соответствует константа True, значению "ложь" – константа False. Именованная константа – это имя (идентификатор), которое в программе используется вместо самой константы. Именованная константа, как и переменная, перед использованием должна быть объявлена. В общем виде инструкция объявления именованной константы выглядит следующим образом: константа = значение; где: • константа – имя константы; • значение – значение константы. Именованные константы объявляются в программе в разделе объявления констант, который начинается словом const. Например, объявления именованных констант (целой, строковой и дробной).
const Bound = 10; Title = 'Скорость бега'; pi = 3.1415926; После объявления именованной константы в программе вместо самой константы можно использовать ее имя. В отличие от переменной, при объявлении константы тип явно не указывают. Тип константы определяется ее видом, например: • 125 – константа целого типа; • 0.0 – константа вещественного типа; • ' выполнить' – строковая константа; • ' \' – символьная константа [3]. 3.4. Инструкция присваивания
Инструкция присваивания является основной вычислительной инструкцией. Если в программе надо выполнить вычисление, то нужно использовать инструкцию присваивания. В результате выполнения инструкции присваивания значение переменной меняется, ей присваивается значение. В общем виде инструкция присваивания выглядит так: Имя := Выражение; где: • имя – переменная, значение которой изменяется в результате выполнения инструкции присваивания; • : = – символ инструкции присваивания. • выражение – выражение, значение которого присваивается переменной, имя которой указано слева от символа инструкции присваивания. Пример:
Summa := Сеnа * Kol; Skidka := 10; Found := False; 26
Выражение состоит из операндов и операторов. Операторы находятся между операндами и обозначают действия, которые выполняются над операндами (табл.3.4). В качестве операндов выражения можно использовать: переменную, константу, функцию или другое выражение. Таблица 3.4 Алгебраические операторы Оператор +
Действие Сложение
-
Вычитание
*
Умножение
/
Деление
DIV
Деление нацело
MOD
Вычисление остатка от деления
При записи выражений между операндом и оператором, за исключением операторов DIV и
MOD, пробел
можно не ставить.
Результат применения операторов +, -, * и / очевиден. Оператор DIV позволяет получить целую часть результата деления одного числа на другое. Например, значение выражения 15 DIV 7 равно 2. Оператор MOD, деление по модулю, позволяет получить остаток от деления одного числа на другое. Например, значение выражения 15 MOD 7 равно 1. В простейшем случае выражение может представлять собой константу или переменную. Примеры выражений:
123 0.001 i+1 А + В/С Summa*0.75 (В1+В3+В3)/3 Cena MOD 100
При вычислении значений выражений следует учитывать, что операторы имеют
разный приоритет. Так у операторов *, /, DIV, MOD более высокий приоритет, чем у операторов + и -. Приоритет операторов влияет на порядок их выполнения. При вычислении значения выражения в первую очередь выполняются операторы с более высоким приоритетом. Если приоритет операторов в выражении одинаковый, то порядок вычисления слева – направо. Для задания нужного порядка выполнения операций в выражении можно использовать скобки, например:
(r1+r2+rЗ)/(r1*r2*rЗ) Выражение, заключенное в скобки, трактуется как один операнд. Это означает, что операции над операндами в скобках будут выполняться в обычном порядке, но раньше, чем операции над операндами, находящимися за скобками. При записи выражений, содержащих скобки, должна соблюдаться парность скобок (число открывающих скобок должно быть равно числу закрывающих скобок). Нарушение парности скобок – наиболее распространенная ошибка при записи выражений.
27
Тип выражения определяется типом операндов, входящих в выражение, и зависит от операций, выполняемых над ними. Например, если оба операнда, над которыми выполняется операция сложения, целые, то очевидно, что результат тоже является целым. А если хотя бы один из операндов дробный, то тип результата дробный, даже в том случае, если дробная часть значения выражения равна нулю. Важно уметь определять тип выражения. При определении типа выражения следует иметь в виду, что тип константы определяется ее видом, а тип переменной задается в инструкции объявления. Например, константы 0,1 и -512 – целого типа (integer), а константы 1.0,0.0 и 3.2Е-05 – вещественного типа (real). В табл. 3.5 приведены правила определения типа выражения в зависимости от типа операндов и вида оператора.
Таблица 3.5 Правила определения типа выражения Оператор
Тип операндов
*, +, -
Хотя бы один из операндов real
Тип выражения real
*, +, -
Оба операнда integer
integer
/
real или integer
Всегда real
DIV, MOD
Всегда integer
Всегда integer
Инструкция присваивания выполняется следующим образом: 1. Сначала вычисляется значение выражения, которое находится справа от символа инструкции присваивания. 2. Затем вычисленное значение записывается в переменную, имя которой стоит слева от символа инструкции присваивания. Например, в результате выполнения инструкций: • i:=o, – значение переменной i становится равным нулю; • а:=b+с; – значением переменной а будет число, равное сумме значений переменных b и с; • j:=j+i; – значение переменной j увеличивается на единицу. Инструкция присваивания считается верной, если тип выражения соответствует или может быть приведен к типу переменной, получающей значение. Например, переменной типа real можно присвоить значение выражения, тип которого real или integer, а переменной типа integer можно присвоить значение выражения только типа integer. Например, если переменные i и n имеют тип integer, а переменная d – тип real, to инструкции
i:=n/10; i:=1.0; неправильные, а инструкция
d:=i+l; правильная . Примеры. Пример1. Запись значения в целочисленную переменную имеет вид:
var i: Integer; 28
begin i: = 10; i: =$a; end; Здесь сначала переменной i присваивается число 10, а потом $a – шестнадцатеричное а, что тоже равно 10. Таким образом первая и вторая строка делают одно и то же, а значит и результат будет одинаковый. Пример2. Объявление строковой переменной.
var Str: AnsiString; begin Str:=‘Hello Word’;//Присвоение Str значение ‘Hello Word’ end; Пример 3. Работа с логическими переменными.
var b:Boolean;// Объявление логической переменной b Str: AnsiString; ;// Объявление строковой переменной Str begin b:=true; if b=true then Str: = ‘истина’ Else Str:=’Ложь’;//Присвоение Str значение ‘Hello Word’ end; Во время компиляции выполняется проверка соответствия типа выражения типу переменной. Если тип выражения не соответствует типу переменной, то компилятор выводит сообщение об ошибке:
Incompatible types ... and ... где вместо многоточий указывается тип выражения и переменной. Например, если переменная n целого типа, то инструкция n: = m/2 неверная, поэтому во время компиляции будет выведено сообщение :
Incompatible types 'Integer' and 'Extended'. 3.5. Стандартные функции Для выполнения часто встречающихся вычислений и преобразований язык Delphi предоставляет программисту ряд стандартных функций. Значение функции связано с ее именем. Поэтому функцию можно использовать в качестве операнда выражения, например в инструкции присваивания. Так, чтобы вычислить квадратный корень, достаточно записать k:=sqrt(n), где Sqrt – функция вычисления квадратного корня, n – переменная, которая содержит число, квадратный корень которого надо вычислить.
Функция характеризуется типом значения и типом параметров. Тип переменной,
которой присваивается значение функции, должен соответствовать типу функции. Точно так же тип фактического параметра функции, т. е. параметра, который указывается при обращении к функции, должен соответствовать типу формального параметра. В противном случае компилятор выводит сообщение об ошибке. 3.5.1.Математические функции Математические функции (табл. 3.6) позволяют выполнять различные вычисления. 29
Таблица 3.6 Математические функции
Функция Abs(X)
Описание
Аргумент
Абсолютное значение
Целое или действительное выражение
Arctan(X) Cos (X) Exp(X) Frac(X) Int(X) IntPower(X, E) Ln(X) Log10(X) Max(A, B)
Арктангенс X Косинус X экспонента Дробная часть аргумента X-Int(x) Целая часть аргумента Возведение X в целую степень E
Min(A,B)
Минимум двух чисел
Pi Random (Range)
Число: 3.1415926535897932385 Генерирует последовательность целых или действительных случайных чисел
Натуральный логарифм от X Десятичный логарифм от X Максимум двух чисел
Power(X, E) Возведение X в произвольную степень E Ближайшее целое аргумента Определяет знак аргумента
Аргумент X – угол в радианах Действительное выражение Действительное выражение Действительное выражение Выражения Extended и Integer Действительное выражение Extended Выражения Integer,Int64, Single, Double, Extended Выражения Integer,Int64, Single, Double, Extended Параметр Range не является обязательным. Если параметр не задан, то функция возвращает случайные действительные числа X, равномерно распределённые в интервале 0 < = X < 1. Если задан, например, Random (101) то можно получить последовательность чисел от 0 до 100 Выражения Extended
Действительное выражение Действительные и целые выражения Квадрат аргумента: X*X Sqr (X) Выражение Extended Квадратный корень Sqrt (X) Выражение Extended Синус X Аргумент X – угол в радианах Sin (X) Величина угла тригонометрических функций должна быть выражена в радианах. Для преобразования величины угла из градусов в радианы используется формула (а* 3.1415256) /180, где: а – величина угла в градусах. Вместо дробной константы 3.1415926 можно использовать стандартную именованную константу PI. В этом случае выражение пересчета угла из градусов в радианы будет выглядеть так: a*pi/180. 3.5.2. Функции преобразования Функции преобразования (табл. 3.7) наиболее часто используются в инструкциях, обеспечивающих ввод и вывод информации. Например, для того чтобы вывести в поле вывода (компонент Label) диалогового окна значение переменной типа real, необ-
Round (X) Sign (X)
30
ходимо преобразовать число в строку символов, изображающую данное число. Это можно сделать при помощи функции FloatToStr, которая возвращает строковое представление значения выражения, указанного в качестве параметра функции. Например, инструкция Label1.Caption := FloatToStr (x) выводит значение переменной х в поле Label 1. Таблица 3.7 Функции преобразования Функция
Значение функции
Chr(n)
Символ, код которого равен n
IntToStr(k)
Строка, являющаяся изображением целого k
FloatToStr (n)
Строка, являющаяся изображением вещественного n
FloatToStrF(n,f,k,m) Строка, являющаяся изображением вещественного n.
StrToInt(s) StrToFloat(s)
При вызове функции указывают: f — формат (способ изображения); к - точность (нужное общее количество цифр); m — количество цифр после десятичной точки Целое, изображением которого является строка s Вещественное, изображением, которого является строка s
Обычно функции используют в качестве операндов выражений. Параметром функции может быть константа, переменная или выражение соответствующего типа. Ниже приведены примеры использования стандартных функций и функций преобразования.
n := Round((x2-xl)/dx); xl:= (-b + Sqrt(d)) / (2*а); m := Random(10); cena := StrToInt(Editl.Text); Edit2.Text := IntToStr(100); mes := 'xl=' + FloatToStr(xl);
Глава 4. Компоненты Поля редактирования, поля отображения текста, списки, переключатели, командные кнопки и другие элементы, обеспечивающие взаимодействие с пользователем, называют компонентами. Компоненты, которые программист может использовать в процессе разработки программы, находятся на вкладках палитры компонентов (Tool Palette). На вкладках Standard, Additional, System и Win32 находятся наиболее часто используемые компоненты. Компонент – это элемент пользовательского интерфейса. С другой стороны, компонент – это код, который обеспечивает создание компонента, его отображение и функционирование. Стандартные компоненты Delphi объединены в библиотеку, которая называется VCL – Visual Component Library (библиотека визуальных компонентов). Именно поэтому приложение, которое для взаимодействия с пользователем использует компоненты VCL, называется VCL-приложением. 31
4.1. Форма и компоненты на форме Работа над новым приложением начинается с создания стартовой формы – главного окна программы. Сначала нужно настроить форму, затем – добавить к форме необходимые компоненты (поля отображения текстовой информации, поля ввода, командные кнопки). Настройка формы (и компонентов) осуществляется путем изменения значений их свойств. Свойства объекта (формы, компонента) определяют вид и поведение объекта. Например, свойство caption определяет заголовок формы, а свойство Position – положение окна в момент первого его появления на экране. Основные свойства формы приведены в табл. 4.1. Таблица 4.1 Свойства формы (объекта TForm) Свойство
Описание
Name
Имя (идентификатор) формы. Используется для доступа к форме, ее свойствам и методам, а также для доступа к компонентам формы
Caption Width Height Position
Текст заголовка Ширина формы
Top Left BorderStyle
Borderlcons
Высота формы Положение окна в момент первого его появления на экране (poCenterScreen – в центре экрана; poOwnerFormCenter – в центре родительского окна; poDesigned– положение окна определяют значения свойств Тор и Left) Расстояние от верхней границы формы до верхней границы экрана Расстояние от левой границы формы до левой границы экрана Вид границы. Граница может быть обычной (bsSizeable), тонкой (bsSingle) или отсутствовать (bsNone). Если у окна обычная граница, то во время работы программы пользователь может с помощью мыши изменить размер окна. Изменить размер окна с тонкой границей нельзя. Если граница отсутствует, то на экран во время работы программы будет выведено окно без заголовка. Положение и размер такого окна во время работы программы изменить нельзя Кнопки управления окном. Значение свойства определяет, какие кнопки управления окном будут доступны пользователю во время работы программы. Значение свойства задается путем присвоения значений уточняющим свойствам biSystemMenu, biMinimaze, biMaximaze и biHelp. Свойство biSystemMenu определяет доступность кнопки системного меню (пиктограммы в заголовке окна), biMinimaze – кнопки Свернуть, biMaximaze – кнопки Развернуть, biHelp – кнопки вывода справочной информации
32
Окончание табл.4.1 Цвет фона. Цвет можно задать, указав название цвета или привязку Color к текущей цветовой схеме операционной системы. Во втором случае цвет определяется текущей цветовой схемой, выбранным компонентом привязки и меняется при изменении цветовой схемы операционной системы Шрифт. Шрифт, используемый "по умолчанию" компонентами, Font находящимися на поверхности формы. Изменение свойства Font формы приводит к автоматическому изменению свойства Font компонента, располагающегося на поверхности формы. То есть компоненты наследуют свойство Font от формы (имеется возможность запретить наследование) Чтобы в заголовке формы вместо Form1 появилось название программы – текст (например Покупка), следует изменить значение свойства caption. Для этого надо в окне Object Inspector щелкнуть левой кнопкой мыши на имени свойства (в результате будет выделено текущее значение свойства и появится курсор), ввести текст и нажать клавишу . Аналогично можно установить значения свойств Height и Width, которые определяют высоту и ширину формы. Размер формы, а также размер других компонентов задают в пикселах (точках). Форма – это обычное окно. Поэтому размер формы можно изменить точно так же, как любого окна Windows, т. е. путем перемещения границы. По окончании перемещения границы значения свойств Height и Width будут соответствовать установленному размеру формы. Положение окна на экране в момент его первого появления соответствует положению формы, заданному во время разработки. Положение формы можно задать, установив значение свойств Tор (отступ от верхней границы экрана) и Left (отступ от левой границы экрана) или задав значение свойства Position. При выборе некоторых свойств, например Borderstyle, справа от текущего значения свойства появляется значок раскрывающегося списка. Из чего следует, что значение таких свойств можно задать путем выбора из списка. Некоторые свойства являются сложными, т. е. их значение определяется совокупностью значений других (уточняющих) свойств. Например, свойство Bordericons определяет кнопки управления окном, которые будут доступны во время работы программы. Значения этого свойства определяются совокупностью значений свойств biSystemMenu, biMinimize, biMaximize и biHelp, каждое из которых, в свою очередь, определяет наличие соответствующей командной кнопки в заголовке окна во время работы программы. Перед именами сложных свойств стоит значок "+", в результате щелчка которого раскрывается список уточняющих свойств. Значение уточняющего свойства можно задать обычным образом (ввести значение в поле редактирования или выбрать в списке). В результате выбора некоторых свойств, например Font, в поле значения свойства отображается кнопка, на которой изображены три точки. В результате щелчка на этой кнопке появляется дополнительное диалоговое окне для задания уточняющих свойств. Например, значение свойства Font можно задать путем ввода значений уточняющих свойств (Name, Size, Style и др.), а можно воспользоваться стандартным диалоговым окном Шрифт, которое появится в результате щелчка на кнопке с тремя точками. В качестве примера можно показать значения свойств компонентов, используемых в программе Покупка. Окно приложения показано на рис. 4.1. 33
Рис. 4.1. Окно приложения Покупка В табл. 4.2 приведены значения свойств стартовой формы программы Покупка. Значения других свойств формы оставлены без изменения и в таблице не представлены. В приведенной таблице в именах некоторых свойств есть точка. Это значит, что надо задать значение уточняющего свойства. После того как будут установлены значения свойств формы, на форму надо добавить компоненты. Таблица 4.2 Значения свойств стартовой формы Свойство
Значение
Height
Стоимость покупки 190
Width
376
BorderStyle
bsSizeable
Caption
обычная
True Borderlcons. [biSystemMenu,biMinimize,bi Maximize] MS Sans Serif Font.Name
Font.Size
Комментарий
В заголовке окна все кнопки, кроме Help
8
Программа Покупка должна получить от пользователя исходные данные: цену и количество. Ввод данных с клавиатуры обеспечивает компонент Edit. Поэтому в форму разрабатываемого приложения нужно добавить три компонента Edit. Для того чтобы в форму добавить компонент Edit, надо: 1. В палитре компонентов (окно Tool Palette) раскрыть вкладку Standard. 2. Сделать щелчок на значке компонента. Здесь следует обратить внимание, что в палитре компонентов рядом со значком компонента указывается тип, а не название компонента. 3. Установить указатель мыши в ту точку формы, в которой должен быть левый верхний угол компонента. 4. Щелкнуть кнопкой мыши. В результате на форме появляется компонент Edit – поле редактирования. Другие компоненты добавляются в форму аналогичным образом. Каждому добавленному компоненту среда разработки присваивает имя, которое состоит из названия компонента и 34
его порядкового номера. Например, первый компонент Edit получает имя Edit1, второй – Edit2 и т.д. Программист, путем изменения значения свойства Name, может изменить имя компонента. Однако в простых программах имена компонентов, как правило, не изменяют. Свойства выбранного компонента отображаются в окне Object Inspector. Чтобы увидеть и, если надо, изменить свойства другого компонента, нужно этот компонент выбрать – щелкнуть левой кнопкой мыши на изображении компонента или выбрать имя компонента в раскрывающемся списке, который находится в верхней части окна Object Inspector. Компонент, свойства которого надо изменить, можно выбрать и в окне Structure. Основные свойства компонента Edit приведены в табл. 4.3. Таблица 4.3 Свойства компонента Edit Свойство
Name Text Left Top Height Width Font
Описание Имя компонента. Используется в программе для доступа к компоненту и его свойствам, в том числе к тексту, который находится в поле редактирования Текст, который находится в поле редактирования Расстояние от левой границы компонента до левой границы формы Расстояние от верхней границы компонента до верхней границы формы Высота компонента Ширина компонента Шрифт, используемый для отображения текста в поле компонента
ParentFont Признак наследования шрифта от формы. Если значения свойства равно True, то для отображения текста в поле компонента используется шрифт формы MaxLength Количество символов, которое можно ввести в поле редактирования. Если значение свойства равно нулю, ограничения на количество символов нет Отображение текста на поверхности формы обеспечивает компонент Label. Основные свойства компонента Label перечислены в табл. 4.4. Таблица 4.4 Свойства компонента Label Свойство
Описание
Name Caption Height Width AutoSize
Имя компонента. Используется в программе для доступа к компоненту Отображаемый текст
WordWrap
Признак того, что слова, которые не помещаются в текущей строке, автоматически переносятся на следующую строку (значение свойства AutoSize должно быть False)
Высота поля вывода Ширина поля вывода Признак того, что размер поля определяется его содержимым
35
Смысл свойств Left, Top и Font аналогичны компоненту Edit. Командная кнопка, компонент Button, добавляется в форму точно так же, как и другие компоненты. Основные свойства компонента приведены в табл. 4.5. Таблица 4.5 Свойства компонента Button Свойство
Описание
Name
Имя компонента. Используется в программе для доступа к компоненту
Caption Enabled Left
Текст на кнопке Признак доступности кнопки. Кнопка доступна, если значение свойства равно True, и не доступна, если значение свойства равно False Расстояние от левой границы кнопки до левой границы формы
Top
Расстояние от верхней границы кнопки до верхней границы формы
Height Width
Высота кнопки Ширина кнопки
4.2. Событие и процедура обработки событий Вид созданной формы подсказывает, как работает программа. Очевидно, что пользователь должен ввести в поля редактирования исходные данные и сделать щелчок на кнопке Стоимость. Щелчок на изображении командной кнопки – это пример того, что называется событием. Событие (Event) – это то, что происходит во время работы программы. У каждого события есть имя. Например, щелчок кнопкой мыши – это событие Click, двойной щелчок мышью – событие DblClick. Следует понимать, что одни и те же, но выполненные над разными объектами, действия пользователя, вызывают разные события. Например, щелчок (событие click) на кнопке Расчёт и щелчок на кнопке Завершить – это два разных события. Реакцией на событие должно быть какое-либо действие. В Delphi реакция на событие реализуется как процедура обработки события. Таким образом, для того чтобы программа выполняла некоторую работу в ответ на действия пользователя, программист должен написать процедуру обработки соответствующего события. Методику создания процедуры обработки события рассмотрим на примерее обработки события click, которое возникает в результате щелчка на кнопке Стоимость. Для создания процедуры обработки события надо выполнить подготовительные действия: • выбрать компонент, для которого создается процедура обработки события. Компонент можно выбрать щелчком на его изображении на форме или в раскрывающемся списке окна Object Inspector; • затем в окне Object Inspector нужно открыть вкладку Events (События). В левой колонке вкладки Events перечислены события, которые может воспринимать выбранный компонент. Строго говоря, на вкладке Events указаны не события, а свойства, значением которых являются имена процедур обработки событий. Так, например, значением свойства onclick является имя процедуры обработки события click. Дальнейшие действия можно выполнить разными способами, приводящими к одному
36
результату – переход в Редактор кода, в котором будет создан каркас будущей процедуры обработки события. Первый способ. Для создания процедуры обработки события, нужно на вкладке Events выбрать событие (сделать щелчок мышью на имени события), ввести в ставшее доступным поле редактирования имя процедуры обработки события и нажать клавишу . В результате этих действий в тексте программы (в модуле формы) будет объявлена процедура обработки события и станет доступным окно Редактора кода, в котором можно набирать инструкции процедуры обработки события. Второй способ. Сначала нужно раскрыть вкладку Events и выбрать событие, процедуру обработки которого надо создать. Затем сделать двойной щелчок левой кнопкой мыши в поле редактирования, которое находится справа от имени события. В результате имя процедуры обработки события сформирует Delphi. Стандартное имя процедуры обработки события образуется путем объединения имени компонента, для которого создается процедура обработки события, и имени события, например,Button1Click.
Полное имя процедуры обработки события состоит из двух частей. Первая часть
идентифицирует форму, вторая – компонент (объект) и событие. В примере вычисления стоимости покупки объявление процедуры (формирует Delphi) имеет вид:
procedure Button1Click(Sender: TObject); В разделе реализации модуля описание процедуры:
// щелчок на кнопке Стоимость procedure TForm1.Button1Click(Sender: TObject); begin Summa(Edit3); // вычислить сумму покупки end; В табл. 4.6 приведены некоторые события, возникающие в результате действий пользователя [3]. Таблица 4.6 События Событие
Click DblClick MouseDown MouseUp MouseMove KeyPress KeyDown
KeyUp Create
Происходит При щелчке кнопкой мыши При двойном щелчке кнопкой мыши При нажатии кнопки мыши При отпускании кнопки мыши При перемещении мыши При нажатии клавиши клавиатуры При нажатии клавиши клавиатуры. События KeyDown и KeyPress — это чередующиеся, повторяющиеся события, которые происходят до тех пор, пока не будет отпущена удерживаемая клавиша (в этот момент происходит событие KeyUp) При отпускании нажатой клавиши клавиатуры При создании объекта (формы, элемента управления). Процедура обработки этого события обычно используется для инициализации переменных, выполнения подготовительных действий 37
Окончание табл. 4.6
Enter Exit
При получении элементом управления фокуса При потере элементом управления фокуса
Глава 5. Основы программирования 5.1. Сохранение проекта, его повторное открывание Перед созданием проекта предварительно создайте пустую папку (каталог), где будут размещены файлы проекта. После того как вы создали приложение с пустой формой, следует сразу сохранить его в подготовленном каталоге. И в течение работы над проектом рекомендуется периодически выполнять сохранение. Начало работы с сохранения проекта и регулярного повтора сохранения поможет обезопасить проект от неожиданностей типа сбоя компьютера или Delphi, вызванных техническими причинами или недопустимыми действиями собственного, еще не отлаженного приложения при его запуске. Сохранение проекта и модулей в самом начале разработки многооконного приложения позволяет сразу задать модулям имена, которые будут использоваться в программе для взаимных ссылок модулей друг на друга. Если не выполнить сразу сохранение формы, то придётся сначала ссылаться на ее имя по умолчанию, а в дальнейшем изменять эти ссылки. Сохранить проект можно командой File Save All. Удобно также использовать соответствующую быструю кнопку. При сохранении следует выбрать заранее подготовленную папку для разрабатываемого проекта При первом сохранении Delphi спросит имя файла сохраняемого модуля, а затем – имя файла проекта. Тут надо иметь в виду, что Delphi не допускает одинаковых имен модулей и проектов. Поэтому задаваемые имена файлов должны быть разными. Можно выполнять сохранение проекта в два этапа: 1) сохранение модуля командой FileSave As. Предлагаемый тип файла Delphi unit (*.pas); 2) сохранение проекта командой FileSave Project As. Предлагаемый тип файла Delphi projects (*.dproj).
Не следует задавать одинаковые имена различным файлам. Имена проектов и мо-
дулей должны быть осмысленными. Имя файла проекта будет в дальнейшем именем выполняемого модуля. Если в проекте будет несколько модулей, то предлагаемые по умолчанию имена Unitl, Unit2 ... Projectl, Project2...будут представлять большое неудобство как для последующей разработки проекта, так и для сопровождения другими лицами. Имя, которое задается вами при сохранении проекта, присвоится исполняемому файлу и файлам .dpr, .bdsproj (.dproj), .cfg, .dsk и ряду других. Имя, которое вы даете модулю, присвоится файлам .pas, .dfm, .dcu. Таким образом, рекомендации по созданию нового проекта: • Создать новый каталог для нового проекта. • Создать новый проект одной из рассмотренных команд. • Сразу сохранить проект и файл модуля командой File Save All. В последующих сеансах работы можно открыть сохраненный проект командой File Open Project. При этом в стандартном диалоге открытия файла вы можете открыть файл .dpr или файл .bdsproj проекта. Если открыть файл .dpr, в окно Редактора Кода загрузятся все файлы модулей проекта. Если же открыть файл .bdsproj, то в окно Редактора Кода, помимо файлов модулей, загрузится и откроется головной файл проек38
та. Поскольку в большинстве случаев он не нужен, удобнее открывать проект с помощью файла .dpr. А если впоследствии потребуется просмотреть головной файл проекта, его всегда можно открыть его командой Project View Source. 5.2. Стиль программирования Работая над программой, программист, особенно начинающий, должен хорошо представлять, что программа, которую он разрабатывает, предназначена, с одной стороны для пользователя, с другой – для самого программиста. Текст программы нужен, прежде всего, самому программисту, а также другим людям, с которыми он совместно работает над проектом. Поэтому для того, чтобы работа была эффективной, программа должна быть легко читаемой, ее структура должна соответствовать структуре и алгоритму решаемой задачи. Этому способствует хороший стиль программирования. Стиль программирования – это набор правил, которым следует программист в процессе своей работы. Очевидно, что хороший программист должен следовать правилам хорошего стиля. Хороший стиль программирования предполагает: • использование комментариев; • использование несущих смысловую нагрузку имен переменных, процедур и функций; • использование отступов; • использование пустых строк. Следование правилам хорошего стиля программирования значительно уменьшает вероятность появления ошибок на этапе набора текста, делает программу легко читаемой, что, в свою очередь, облегчает процессы отладки и внесения изменений. Четкого критерия оценки степени соответствия программы хорошему стилю программирования не существует. Вместе с тем достаточно одного взгляда чтобы понять, соответствует программа хорошему стилю или нет. Сводить понятие стиля программирования только к правилам записи текста программы было бы неверно. Стиль, которого придерживается программист, проявляется во время работы программы. Хорошая программа должна быть, прежде всего, надежной и дружественной по отношению к пользователю. Надежность подразумевает, что программа, не полагаясь на «разумное» поведение пользователя, контролирует исходные данные, проверяет результат выполнения операций, которые по какой-либо причине могут быть не выполнены, например, операций с файлами. Дружественность предполагает хорошо спроектированные диалоговые окна, наличие справочной системы, разумное и предсказуемое, с точки зрения пользователя, поведение программы [3]. Совершенно очевидно, что программный код должен быть написан без синтаксических ошибок. В этом поможет инструмент Code Insight – Знаток Кода. Этот инструмент встроен в окно Редактора Кода и может оказать большую помощь при написании кода и его отладке. Он во многих случаях подскажет имена свойств, методов, событий, типы аргументов, типовые синтаксические конструкции и многое другое. Code Insight может работать в двух режимах: автоматическом и не автоматическом. Вызвать настройку Редактора Кода можно щелчком правой кнопки мыши в его окне и выбором команды Properties из всплывшего меню. Можно также выполнить для этого команду Tools Options и в открывшемся окне перейти на страницу Editor Options (рис. 5.1). Для файлов языка Pascal (Delphi) можно задавать следующие опции (табл.5.1.). 39
Таблица 5.1 Основные опции Code Insight Опция
Содержание
Завершение кода – подсказка в виде списка свойств, методов, событий, относящихся к данному компоненту. Code parameters Подсказка параметров функций, процедур, методов. Tooltip expres- Оценка выражений во время останова или пошагового выполsion evaluation нения приложения в процессе его отладки. Tooltip Symbol Подсказка во всплывающем окне определений идентиInsight фикаторов, над которыми перемещается курсор мыши. Tooltip Help Подсказка во всплывающем окне по идентификаторам, над коInsight торыми перемещается курсор мыши, содержащая ссылки на источники дополнительной информации. Error Insight Подчеркивание волнистой красной линией ошибок. Подсказка во всплывающем окне возможной причины ошибки при перемещении курсора мыши над ошибочными идентификаторами. Block Completion Автоматическое завершение начатого блока. Code Completion Автоматическое простановка скобок в вызове функций, если parenthesis функции взяты из подсказки, заданной опцией Code completion. Code completion
Code Template Completion
Автоматическая вставка в код шаблона, если написан его первый идентификатор и нажата клавиша табуляции.
Рис. 5.1. Окно настройки Code Insight – Знатока кода
40
По умолчанию автоматическое выполнение всех опций в окне включено. Автоматически возникающие подсказки очень полезны для начинающих, но иногда при работе на не очень мощных компьютерах могут раздражать более опытных пользователей. Поэтому имеется возможность отключить автоматический режим и вызывать Code Insight по мере надобности, нажимая клавиши Ctrl-Shift- или Ctrl- в зависимости от того, к каким возможностям Code Insight вы хотите обратиться. Code Insight может выполнять, например, следующие функции. 1.Завершение кода. Если вы написали в своем приложении имя компонента, поставили после него точку и немного задержались с вводом последующего текста, то появится окно, содержащее список всех свойств, методов и событий класса, к которому принадлежит данный компонент. Можно выбрать из него требуемое или начать писать первые символы свойства или метода, а затем нажать , и в код вставится соответствующее имя. Так будет при автоматической работе Code Insight. Если автоматический режим отключен, то вы можете вызвать ту же подсказку, если, поставив точку после имени компонента, нажмете Ctrl-. 2.Параметры функций, процедур, методов. Если Code Insight работает в автоматическом режиме, то после того, как вы напишете имя функции, процедуры или метода и поставите открывающуюся скобку, вы увидите список параметров и их типов. Причем по мере того, как вы будете вводить значения аргументов, вам будет высвечиваться тип следующего параметра. Это, может быть, наиболее мощная возможность Code Insight, поскольку вряд ли кто-нибудь способен помнить параметры всех функций и методов Delphi [1]. 5.3. Порядок разработки проекта Начиная работу по созданию проекта, рекомендуется в общем случае выполнить этапы: 1. Уяснить задачу, которую собираетесь решать на компьютере. 2. Нарисовать на бумаге все то, что предполагаете увидеть на экране в процессе решения. Это может быть один или несколько рисунков. Если задача сложная, ее следует разбить на этапы и для каждого этапа сделать отдельный рисунок; 3. Написать сценарий работы будущей программы. Местом развертывания действия является экран, а зритель не просто смотрит, но и участвует в «спектакле». В сценарии должно быть учтено все: что выводится на экран вначале, что делается потом, как программа завершается, и т.д. Декорациями «спектакля» служат сделанные рисунки. 4. Составить алгоритм вычисления. 5.4. Управляющие структуры языка Delphi На практике редко встречаются задачи, алгоритм решения которых является линейным. Часто оказывается, что алгоритм решения даже элементарной задачи не является линейным. Например, пусть надо вычислить по формуле значение тока в электрической цепи. Если предположить, что пользователь всегда будет вводить верные данные, то алгоритм решения этой задачи действительно является линейным. Однако полагаться на то, что пользователь будет вести себя так, как надо программе, не следует. Формула расчета предполагает, что величина сопротивления не равна нулю. А что будет, если пользователь введет 0? Ответ простой: возникнет ошибка «Деление на ноль», и программа аварийно завершит работу. Можно, конечно, возложить ответственность за это
41
на пользователя, но лучше внести изменения в алгоритм решения, чтобы расчет выполнялся только в том случае, если введены верные данные. Точки алгоритма, в которых выполняется выбор дальнейшего хода программы, называются точками выбора. Выбор очередного шага решения задачи осуществляется в зависимости от выполнения некоторого условия. В повседневной жизни условие обычно формулируется в виде вопроса, на который можно ответить Да или Нет. Например: • Величина сопротивления равна нулю? • Ответ правильный? • Сумма покупки больше 300 рублей? В программе условие – это выражение логического типа (Boolean), которое может принимать одно из двух значений: True (истина) или False (ложь). Простое условие состоит из двух операндов и оператора сравнения. В общем виде условие записывается следующим образом: Оп1 Оператор Оп2 где: • Onl и Оп2 – операнды условия, в качестве которых может выступать переменная, константа, функция или выражение; • оператор – оператор сравнения. В Delphi есть шесть операторов сравнения, которые приведены в табл. 5.2. Таблица 5.2 Операторы сравнения Оператор
Описание
>
Больше
=
42
В третьем примере в качестве второго операнда используется функция. Значение этого условия будет True, если в переменной sim находится символьный код клавиши , равный 13.
При записи условий следует обратить особое внимание на то, что операнды усло-
вия должны быть одного типа или, если тип операндов разный, то тип одного из операндов может быть приведен к типу другого операнда. Например, если переменная Key объявлена как integer, то условие кеу = chr(13) синтаксически неверное, т. к. значение возвращаемое функцией chr имеет тип char (символьный). Во время трансляции программы при обнаружении неверного условия компилятор выводит сообщение: incompatible types (несовместимые типы). Из простых условий при помощи логических операторов: and – «логическое И», or – «логическое ИЛИ» и not – «отрицание» можно строить cложные условия. В общем виде сложное условие записывается следующим образом: условие1 оператор условие2 где: • условие1 и условие2 – простые условия (выражения логического типа); • оператор – оператор and или or. Например,
(ch >= '0') and (ch
100)
and 43
(Day = 7)
Если условие предоставления скидки дополнить тем, что скидка предоставляется в любой день, если сумма покупки превышает 500 руб., то условие записывается:
((Summa
>
100)
and
(Day =7))
or
(Summa
>
500)
Выбор в точке разветвления алгоритма очередного шага программы может быть реализован при помощи инструкций if и case. Инструкция if позволяет выбрать один из двух возможных вариантов, инструкция case – один из нескольких [3]. 5.4.1. Инструкция if Инструкция if позволяет выбрать один из двух возможных вариантов развития программы. Выбор осуществляется в зависимости от выполнения условия. В общем виде инструкция if записывается так:
if
условие then begin // здесь инструкции, которые надо выполнить, // если условие истинно.
end else begin // здесь инструкции, которые надо выполнить, // если условие ложно.
end; Обратите внимание, что перед else (после end) точка с запятой не ставится. Выполняется инструкция if следующим образом: 1. Вычисляется значение условия (условие – выражение логического типа, значение которого может быть равно True или False). 2. Если условие истинно (значение выражения условие равно True), то выполняются инструкции, следующие за словом then (между begin и end). На этом выполнение операции if заканчивается и инструкции, следующие за else, не будут выполнены. 3. Если условие ложно (значение выражения условие равно False), то выполняются инструкции, следующие за словом else (между begin и end). На рис. 5.2 представлен алгоритм, соответствующий инструкции if-then-else. Например, если переменная t обозначает тип соединения сопротивлений в электрической цепи (t=1 это последовательное соединение, t=2 – параллельное), a rl и r2 – величины сопротивлений, то инструкция if осуществляет выбор формулы, по которой будет выполнен расчет, имеет вид:
if t=l then begin z:=rl+r2; end else begin z:= (r1*r2)/(r1+r2); end; 44
Рис. 5.2. Алгоритм, реализуемый инструкцией if-then-else Если в инструкции if между begin и end находится только одна инструкция, то слова begin и end можно не писать. Например, инструкцию
if otv=3 then begin prav:=prav+l; end else begin ShowMessage('Ошибка!'); end;
можно переписать так: if otv=3 then prav:=prav+l else ShowMessage('Ошибка!'); Если какое-либо действие должно быть выполнено только при выполнении определенного условия и пропущено, если это условие не выполняется, инструкция if может быть записана так:
if условие then begin { инструкции, которые надо выполнить, если условие выполняется, истинно }
end На рис. 5.3 представлен алгоритм, соответствующий инструкции if-then. 45
Условие выполняется?
Да (True)
Нет (False)
Инструкции
Рис. 5.3. Алгоритм, реализуемый инструкцией if-then Например, инструкция
if n = m then
c: =c+l;
увеличивает значение переменной c только в том случае, если значения переменных n и m равны. При вложенных конструкциях if могут возникнуть неоднозначности в понимании того, к какой из вложенных конструкций if относится элемент else. Компилятор всегда считает, что else относится к последней из конструкций if, в которой не было раздела else. Например, в конструкции
if then if then else ; else будет отнесено компилятором ко второй конструкции if, т.е. будет выполняться в случае, если первое условие истинно, а второе ложно. Иначе говоря, вся конструкция будет прочитана как
if then begin if then else end; Если же вы хотите отнести else к первому if, это надо записать в явном виде с помощью операторных скобок begin...end:
if then begin if then end else ; В качестве примера использования инструкции if рассмотрим программу вычисления стоимости междугородного телефонного разговора.
46
Как известно, стоимость междугородного разговора по телефону в выходные дни ниже, чем в обычные. Программа должна запрашивать длительность разговора и день недели, а затем вычислять стоимость разговора. Если день недели – суббота или воскресенье, то стоимость уменьшается на величину скидки. Цена минуты разговора и величина скидки задаются в тексте программы как константы [3]. Для ввода исходных данных (длительность разговора, номер дня недели) используются поля редактирования, для вывода результата и пояснительного текста – поля меток. В табл. 5.4 перечислены компоненты и указано их назначение. Таблица 5.4 Компоненты формы приложения Стоимость разговора Компонент Edit1 Edit2 Label1, Label2
Назначение Окно ввода – для ввода длительности разговора в минутах Окно ввода – для ввода номера дня недели Метки – для вывода пояснительного текста о назначении полей ввода
Метка – для вывода результата вычисления — стоимости разговора Button1 Кнопка – для активизации процедуры вычисления стоимости разговора Диалоговое окно программы показано на рис. 5.4. Label3
Рис. 5.4. Вид диалогового окна программы. В табл. 5.5 приведены значения свойств компонентов. Таблица 5.5 Значения свойств компонентов Свойство Forml.Caption (заголовок формы) Editl.Text Edit2.Text
Значение Стоимость разговора
Labell.Caption
Длительность (мин.)
Label2.Caption
Номер дня недели
Label3.Caption Buttonl.Caption
Вычислить
47
Программа производит вычисления в результате щелчка на командной кнопке Вычислить. При этом возникает событие Onclick, которое обрабатывается Процедурой Tforml.Button1Click. Текст программы показан в листинге. Листинг. Вычисление стоимости телефонного разговора
unit Phone_u; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; // поле ввода длительности разговора Edit2: TEdit; // поле ввода номера дня недели Button1: TButton; // кнопка Вычислить Label1: TLabel; Label2: TLabel; Label3: TLabel; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); const PAY = 0.15; // цена одной минуты разговора0.15 рубля DISCOUNT = 0.2; // скидка 20 процентов var Time:Real;// длительность разговора Day:integer;// день недели Summa:real;// стоимость разговора begin //получить исходные данные Time:=StrToFloat(Edit1.Text); 48
Day:=StrToInt(Edit2.Text); // Вычислить стоимость разговора Summa:= PAY*Time; // Если день суббота или воскресенье, то уменьшить // стоимость на величину скидки if (Day = 6) OR (Day = 7) then Summa:=Summa*(1 -DISCOUNT); // вывод результата вычисления label3.caption:='К оплате '+FloatToStr(Summa)+'руб.'; end; end. Часто в программе необходимо реализовать выбор более чем из двух вариантов. Например, известно, что для каждого человека существует оптимальное значение веса, которое может быть вычислено по формуле: Рост (см)- 100. Реальный вес может отличаться от оптимального: вес может быть меньше оптимального, равняться ему или превышать оптимальное значение. Следующая программа, диалоговое окно которой приведено на рис. 5.5, запрашивает вес и рост, вычисляет оптимальное значение, сравнивает его с реальным весом и выводит соответствующее сообщение.
Рис.5.5. Форма с компонентами для приложения Контроль веса Как и в предыдущей программе, вычисления выполняются при щелчке на кнопке Вычислить. Текст процедуры обработки события имеет вид:
procedure TForm1.Button1Click(Sender: TObject); var w:real; { вес } h:real; { рост } opt:real; { оптимальный вес } d:real; { отклонение от оптимального веса } begin w:=StrToFloat(Edit1.text); h:=StrToInt(Edit2.Text); opt:=h-100; if w=opt
49
then Label3.caption:='Ваш вес оптимален !' else if w 100 then r:=n mod 100; if ( r >= 11) and ( r кон_знач
Да
Нет
Инструкции
счётчик: = счётчик+1
Рис. 5.11. Алгоритм инструкции for
Если начальное значение счетчика больше конечного значения, то последователь-
ность операторов между begin и end не будет выполнена ни разу. После каждого выполнения инструкций тела цикла счетчик циклов увеличивается автоматически. Переменную-счетчик можно использовать внутри цикла (но ни в коем случае не изменять). Например, в результате выполнения следующих инструкций:
tabl: =' ' ; for i:=l to 5 do begin tabl:=tabl+IntToStr(i)+' end;
'+IntToStr(i*i)+chr(13);
переменная tabl будет содержать изображения таблицы квадратов чисел. Рассмотрим программу, которая вычисляет сумму первых 10 элементов ряда: 1 + 1/2 + 1/3 + ... (значение i-го элемента ряда связано с его номером формулой 1/i). Диалоговое окно программы должно содержать, по крайней мере, два компонента: поле метки (Label1) и командную кнопку (Button1). Вычисление суммы ряда и вывод результата выполняет процедура обработки события Onclick, текст которой имеет вид:
procedure TForm1.Button1Click(Sender: TObject); var i:integer; // номер элемента ряда 59
elem:real; // значение элемента ряда summ:real; // сумма элементов ряда begin summ:=0; label1.caption:=''; // очистка содержимого строки вывода // по метке for i:=1 to 10 do begin elem:=1/i; label1.caption:=label1.caption+ IntToStr(i)+' '+FloatToStr(elem)+#13; summ:=summ+elem; end; label1.caption:=label1.caption+'Сумма ряда:' + FloatToStr(summ); end;
Если в инструкции for вместо слова to записать downto, то после очередного выполнения инструкций тела цикла значение счетчика будет не увеличиваться, а уменьшаться. 5.5.2. Инструкция while
Инструкция while используется в том случае, если некоторую последовательность действий (инструкций программы) надо выполнить несколько раз, причем необходимое число повторений во время разработки программы неизвестно и может быть определено, только во время работы программы. Типичными примерами использования цикла while являются вычисления с заданной точностью, поиск в массиве или в файле. В общем виде инструкция while записывается следующим образом:
while условие do begin // здесь инструкции, end
которые надо выполнить несколько раз
где условие — выражение логического типа, определяющее условие выполнения инструкций цикла. Инструкция while выполняется следующим образом: 1. Сначала вычисляется значение выражения условие. 2. Если значение выражения условие равно False (условие не выполняется), то на этом выполнение инструкции while завершается. 3. Если значение выражения условие равно True (условие выполняется), то выполняются расположенные между begin и end инструкции тела цикла. После этого снова проверяется выполнение условия. Если условие выполняется, то инструкции цикла выполняются еще раз. И так до тех пор, пока условие не станет ложным (False). Алгоритм, соответствующий инструкции while, представлен на рис. 5.12.
60
Для того чтобы инструкции цикла while, которые находятся между begin и
end, были выполнены хотя бы один раз, необходимо, чтобы перед выполнением инструкции while значение выражения условие было истинно.
Нет
Условие = True Да
Инструкции цикла
Рис. 5.12. Алгоритм инструкции while Для того чтобы цикл завершился, нужно, чтобы последовательность инструкций между begin и end влияла на значение выражения условие (изменяла значения переменных, входящих в выражение условие). Рассмотрим программу, которая вычисляет значение числа π с точностью, задаваемой пользователем во время работы программы. В основе алгоритма вычисления лежит тот факт, что сумма ряда 1 - 1/3 + 1/5 -1/7 + 1/9 + ... приближается к значению π/4 при достаточно большом количестве членов ряда. Каждый член ряда с номером n вычисляется по формуле: 1/(2 * n - 1) и умножается на минус один, если n чётное (определить, является ли n четным, можно проверкой остатка от деления n на 2). Вычисление заканчивается тогда, когда значение очередного члена ряда становится меньше, чем заданная точность вычисления. Вид диалогового окна программы во время ее работы приведен на рис. 5.13. Пользователь вводит требуемую точность вычисления в поле ввода (Edit1). После щелчка на командной кнопке Вычислить (Button1) программа вычисляет значение числа π и выводит результат в поле метки (Label1).
Рис.5.13. Диалоговое окно программы Вычисление π
61
Как и в предыдущих примерах, основную работу выполняет процедура обработки события onclick:
procedure TForm1.Button1Click(Sender: TObject); var pi:real;// вычисляемое значение ПИ t:real;// точность вычисления n:integer;// номер члена ряда elem:real;// значение члена ряда begin pi:=0; n:=1; t:=StrToFloat(edit1.text); elem:=1; // чтобы начать цикл while elem >= t do begin elem:=1/(2*n-1); if n MOD 2 = 0 then pi:=pi-elem else pi:=pi+elem; n:=n+1; end; pi:=pi*4; label1.caption:= 'ПИ равно '+ FloatToStr(pi) + #13 + 'Просуммировано '+IntTostr(n)+' членов ряда.'; end; 5.5.3. Инструкция repeat
Инструкция repeat, как и инструкция while, используется в программе в том случае, если необходимо выполнить повторные вычисления (организовать цикл), но число повторений во время разработки программы неизвестно и может быть определено только во время работы программы, т. е. определяется ходом вычислений. В общем виде инструкция repeat записывается:
repeat // инструкции until условие где условие – выражение логического типа, определяющее условие завершения цикла. Инструкция repeat выполняется следующим образом: 1. Сначала выполняются находящиеся между repeat и until инструкции тела цикла. 2. Затем вычисляется значение выражения условие. Если условие ложно (значение выражения условие равно False), то инструкции тела цикла выполняются еще раз. 3. Если условие истинно (значение выражения условие равно True), то выполнение цикла прекращается. Алгоритм, соответствующий инструкции repeat, представлен на рис. 5.14.
62
Рис. 5.14. Алгоритм инструкции repeat Таким образом, инструкции цикла, находящиеся между repeat и until, выполняются до тех пор, пока условие ложно, т.е. значение выражения условие равно False (см. рис.5.14).
Для завершения цикла, необходимо, чтобы инструкции цикла, располагающиеся
между repeat и until, изменяли значения переменных, входящих в выражение условие. Инструкции цикла, находящиеся между repeat и until, выполняются как минимум один раз. Следующий пример проверяет, является ли введенное пользователем число простым, Проверить, является ли число n простым, можно делением числа n на два, на три и т. д. до n и проверкой остатка после каждого деления. Если после очередного деления остаток равен нулю, то это означает, что найдено число, на которое n делится без остатка. Сравнив n и число, на которое n разделилось без остатка, можно определить, является ли n простым числом [3]. Форма приложения Простое число изображена на рис. 5.15.
Рис.5.15. Форма приложения Простое число Обработчик событий:
procedure TForm1.Button1Click(Sender: TObject); var n: integer; // проверяемое число d: integer; // делитель r: integer; // остаток от деления n на d begin 63
n:=StrToInt(Edit1.text); d := 2;// сначала будем делить на два repeat r := n mod d; if r 0 // n не разделилось нацело на then d := d + 1; until r = 0; // повторять пока не найдено //на n делящееся без остатка label2.caption:=Edit1.text; if d = n then label2.caption:=label2.caption + ' число.' else label2.caption:=label2.caption + ' число.'; end;
d число
- простое обычное
5.5.4. Инструкция goto
Инструкции if и case используются для перехода к последовательности инструкций программы в зависимости от некоторого условия. Поэтому их иногда называют инструкциями условного перехода. Помимо этих инструкций управления ходом выполнения программы существует еще одна – инструкция безусловного перехода goto.
В общем виде инструкция goto записывается следующим образом: goto Метка где метка – это идентификатор, находящийся перед инструкцией, которая должна быть выполнена после инструкции goto. Метка, используемая в инструкции goto, должна быть объявлена в разделе меток, который начинается словом label и располагается перед разделом объявления переменных. В программе метка ставится перед инструкцией, к которой должен быть выполнен переход в результате выполнения инструкции goto. Сразу после метки ставится двоеточие. Например, в процедуре проверки положительности вводимого числа инструкция goto используется для завершения процедуры в том случае, если пользователь введет неверные данные. Текст процедуры:
procedure TForm1.Button1Click(Sender: TObject); label //раздел объявления меток bye; var n: integer; // проверяемое число d: integer; // делитель r: integer; // остаток от деления n на d begin n:=StrToInt(Edit1.text); if n 500 then begin s := s * 0.9; mes := 'Предоставляется скидка 10%' + #13; end; mes := mes+ 'Стоимость покупки: ' + FloatToStrF(s,ffFixed,4,2) +' руб.'; Forml.Label3.Caption := mes; end; Обращение к этой процедуре в программе выглядит так:
procedure TForm1.Button1Click(Sender: TObject); begin summa; // обращение к процедуре summa end; Другой вариант вычисления стоимости покупки с использованием функции:
Function Summa(k:TEdit):String;//в скобках формальный //параметр var cena: real; // цена kol: integer; // количество s: real; // сумма mes: string[255]; // изменять число begin mes:= ' '; cena := StrToFloat(Form1.Edit1.Text); kol := StrToInt(Form1.Edit2.Text); s := cena * kol; if s > 500 then begin s := s * 0.9; mes := 'Предоставляется скидка 10%'{+ #13}; end; 68
mes := mes+ 'Стоимость покупки: ' + FloatToStrF(s,ffFixed,4,2) +' руб.'; k.text:= mes; end; // щелчок на кнопке Стоимость procedure TForm1.Button1Click(Sender: TObject); begin // обращение к функции (вызов функции) Summa(Edit3); // вычислить сумму покупки end; 5.6.3. Ввод и вывод данных в диалоговых окнах Наиболее просто программа может получить исходные данные из окна ввода или из поля редактирования (компонент Edit). Рассмотрим пример использования диалоговых окон для решения задачи пересчёта веса. Один из самых простых вариантов решения этой задачи может быть реализован с помощью следующих процедур:
procedure TForm1.FormCreate(Sender: TObject); label bye; var funt:real; { вес в фунтах } kg:real; { вес в килограммах } k:real; { коэффициент пересчета } s:string; begin bye: //вывод окна сообщения S:=InputBox('Ввод в окно редактирования', 'Введите вес в фунтах'+' Для отделения целой части'+ ' от дробной ставьте зпт','0'); k:=0.4059; funt:=StrToFloat(s); kg:=funt*k; ShowMessage('вес ' + FloatToStrF(kg,ffFixed,6,1)+ ' кг'); case MessageDlg('Продолжить вычисления?', mtCustom,mbYesNo,0) of mrYes: goto bye; mrNo:Form1.Show; end; end; procedure TForm1.Button1Click(Sender: TObject); begin Form1.Close; end; При запуске приложения открывается окно редактирования для ввода данных (рис. 5.17 a). После ввода данных (рис. 5.17 b). 69
a) b) Рис. 5.17. Диалоговое окно редактирования После нажатия ОК появляется результат в окне сообщения, последующее нажатие ОК выводит окно сообщения с предложением выбора продолжения вычисления Yes или No (рис. 5.18).
Рис. 5.18. Окна сообщений Отказ от продолжения вычисления выводит окно завершения работы с программой (рис. 5.19).
Рис. 5.19. Окно завершения программы Окно ввода – это стандартное диалоговое окно, которое появляется на экране в результате вызова функции inputBox. Значение функции inputBox – строка, которую ввел пользователь. Функция inputBox объявлена в модуле Dialogs следующим образом:
InputBox(const ACaption, APrompt, ADefault:string):string; Функция предлагает пользователю диалоговое окно с заголовком ACaption,с предложением APrompt пользователю что-то написать и с окошком редактирования, в котором предварительно загружено начальное значение текста ADefault. Если пользователь нажмёт в окне ОК, то функция вернёт введённую им строку текста. Если в диалоге нажать Cancel, или Esc, или закрыть окно системной кнопкой, то функция вернёт строку ADefault, перед этим пользователь что-то написал в окне редактирования. Окна сообщений используются для привлечения внимания пользователя. При помощи окна сообщения программа может, к примеру, проинформировать об ошибке в исходных данных или запросить подтверждение выполнения необратимой операции, например, удаления файла. Вывести на экран окно с сообщением можно при помощи процедуры ShowMessage или функции MessageDlg.
70
Процедура ShowMessage выводит на экран окно с текстом и командной кнопкой ОК. Процедура имеет вид:
Procedure ShowMessage (const Msg:string); Текст сообщения задаётся параметром Msg. Заголовок окна совпадает с именем выполняемого файла приложения. Например:
ShowMessage('Введите вес в фунтах.'); Функция MessageDlg объявляется следующим образом:
function MessageDlg(const Msg: string; AType:TMsgDlgType; AButtons: TMsgDlgButtons; HelpCtx: Longint): Word; Вызов MessageDlg отображает диалоговое окно и ожидает ответа пользователя. Сообщение в окне задаётся параметром функции Msg.. Параметр HelpCtx определяет тему контекстной справки, соответствующую данному диалоговому окну. Эта тема будет появляться при нажатии пользователем клавиши F1. Если вы справку не планируете, надо задать нулевое значение параметра HelpCtx. Вид отображаемого окна задаётся параметром Atype (табл. 5.10) Таблица 5.10 Значения параметра AType Значение mtWarning mtError mtInformation mtConfirmation
Описание Окно замечаний, содержащее желтый восклицательный знак Окно ошибок, содержащее красный стоп-сигнал Информационное окно, содержащее голубой символ «I» Окно подтверждения, содержащее зеленый вопросительный знак mtCustom Заказное окно без рисунка. Заголовок соответствует имени выполняемого файла приложения Параметр AButtons определяет, какие кнопки будут присутствовать в окне. Тип TMsgDlgBtns параметра AButtons является множеством, которое включает различные кнопки. Возможные значения видов кнопок показано в табл.5.11. Таблица 5.11 Значения видов кнопок Значение
mbYes mbNo mbOK mbCancel mbHelp mbAbort mbRetry mbIgnore mbAll
Надпись кнопки
Yes No OK Cancel Help Abort Retry Ignore All
Список необходимых кнопок заключается в квадратные скобки [ ], поскольку параметр AButtons является множеством. Если внутри скобок список отсутствует, в окне не будет ни одной кнопки и пользователю придется закрывать окно системными кнопками Windows [1]. 71
Кроме множества значений, соответствующих отдельным кнопкам, в Delphi определены три константы, соответствующие часто используемым сочетаниям кнопок (табл. 5.12). Таблица 5.12 Сочетание кнопок
mbYesNoCancel
Значение
Описание Включает в окно кнопки Yes, No и Cancel
mbOkCancel
Включает в окно кнопки OK и Cancel
mbAbortRetryIgnore Включает в окно кнопки Abort, Retry и Ignore Эти константы являются предопределенными множествами. Поэтому при их использовании их не надо заключать в квадратные скобки [ ]. Функции возвращают значение, соответствующее выбранной пользователем кнопке. Возможные возвращаемые значения:
mrNone mrOk mrCancel
mrAbort mrRetry mrIgnore
mrYes mrNo mrAll
5.6.4. Запись инструкций программы Одну инструкцию от другой отделяют точкой с запятой или, другими словами, в конце каждой инструкции ставят точку с запятой. Хотя в одной строке программы можно записать несколько инструкций, как правило, каждую инструкцию программы записывают в отдельной строке. Некоторые инструкции (if, case, repeat, while и др.) принято записывать в несколько строк, используя для выделения структуры инструкции отступы. Ниже приведен пример инструкции, которая записана в несколько строк и с использованием отступов:
if d >= О then begin xl:=(-b+Sqrt(d))/(2*a); x2:=(-b-Sqrt(d))/(2*a); ShowMessage('xl='+FloatToStr(xl) + 'x2='+FloatToStr(x2)); end else ShowMessage('Уравнение не имеет корней.'); Следует обратить внимание на то, что слова then и else записаны одно под другим (с одинаковым отступом) и с отступом относительно слова if. Слово end располагается под словом begin, а инструкции между begin и end размещаются одна под другой, но с отступом относительно begin. Приведенную выше инструкцию можно записать и так:
if d >= 0 then begin xl:=(-b+Sqrt(d))/(2*a); x2: = (-b-Sqrt(d))/(2*a); 72
ShowMessage('xl='+FloatToStr(xl)+'x2='+FloatToStr(x2)); end else ShowMessage('Уравнение не имеет корней.'); Однако первый вариант лучше, т. к. он отражает структуру алгоритма, peализуемого инструкцией. С первого взгляда видна группа инструкций, которая будет выполнена, если условие d >= 0 выполняется (в этом случае будут вычислены значения переменных x1 и х2), и инструкция, которая будет выполнена, если условие d >=0 не выполняется. Длинные выражения тоже могут быть записаны в несколько строк. Разорвать выражение и перенести оставшуюся часть на следующую строку можно практически в любом месте.
Нельзя разрывать имена переменных, числовые и строковые константы, а
также составные операторы, например, оператор присваивания. Пример записи выражения в несколько строк:
st:= 'Корни уравнения'+ #13 +'xl=' + FloatToStr(xl)+ #13 +'х2=' + FloatToStr(x2);
Компилятор игнорирует «лишние» пробелы и пустые строки. Так, он игнорирует
все пробелы в начале строки. Это и позволяет записывать инструкции с отступами. Не требуются пробелы при записи арифметических и логических выражений (условий), списков параметров. Однако при их использовании программа легче воспринимается.
Если сравнить два варианта записи инструкции присваивания, то видно, что второй вариант воспринимается лучше: xl:=(-b+Sqrt(d))/(2*a); и xl := (-b + Sqrt(d)) / (2 * а);
Для облегчения понимания логики работы программы в текст программы нужно
включать поясняющий текст – комментарии. В общем случае комментарии заключают в фигурные скобки. Открывающая скобка помечает начало комментария, закрывающая – конец. Если комментарий однострочный или находится после инструкции, то перед комментарием ставят две наклонные черты. Пример раздела объявления переменных, в котором использованы оба способа записи комментариев:
var { коэффициенты уравнения } a:real; // при второй степени неизвестного b:real; // при первой степени неизвестного с:real; // при нулевой степени неизвестного { корни уравнения } xl,x2:real;[3] 5.6.5. Отладка программы ИСР предоставляет разработчику средство поиска и устранения ошибок в программе – отладчик. Отладчик позволяет выполнять трассировку программы, наблюдать значения переменных, контролировать выводимые программой данные.
73
Для того, чтобы найти причину ошибки, надо выполнить какой-то фрагмент программы, наблюдая изменения переменных при выполнении каждой команды. Трассировка – это процесс выполнения программы по шагам (step-by-step), инструкция за инструкцией. Для прохода фрагмента программы по шагам можно использовать команды, представленные в табл.5.13. Наиболее распространённый инструмент – введение в приложение точек прерывания (breakpoint). Для ввода простой (безусловной) точки прерывания достаточно в окне Редактора Кода щелкнуть мышью на полоске левее кода требуемой строки. Строка выделится цветом и на ней появится красная точка (рис. 5.20).
Рис. 5.20. Окно Редактора Кода с введённой точкой прерывания Таблица 5.13 Команды трассировки Команда Step Over (По шагам без захода в ...)
Горячие клавиши F8
F7 Trace Into (Трассировка с заходом в ...)
Trace to Next Source Shift+F7 Line (Трассировка до следующей строки) F4 Run to Cursor (Выполнить до курсора)
Пояснения Пошаговое выполнение строк программы, считая вызов функции или процедуры за одну строку, т.е. вход в функции и процедуры не производится. Пошаговое выполнение программы с заходом в вызываемые функции и процедуры. Переход к следующей исполняемой строке
Команда выполняет программу до того выполняемого оператора, на котором расположен курсор в окне редактора кода. Если запустить приложение на выполнение и начать с ним работать, то как только управление перейдёт к строке с установленной точкой прерывания, то произойдёт прерывание выполнения. Далее, при нажатии F7 или F8, будут выполняться операторы по шагам и в окне наблюдений Local Variables (рис. 5.21) можно видеть изменения значений переменных. Следует помнить, что если операторы содержат вызовы какихто других процедур или функций, определённых в данном модуле, то при нажатии F7 программа будет заходить внутрь вызываемых процедур и функций. При нажатии F8 подобного захода не будет [1].
74
Рис. 5.21. Окно Local Variables Для удаления точки прерывания достаточно щёлкнуть мышью на красной точке левее кода соответствующей строки.
Точки прерывания можно устанавливать только на выполняемых операторах. Ес-
ли установить точку прерывания, например, на строке объявления переменной, то в момент запуска приложения в красной точке выделения строки прерывания появится крестик, предупреждающий, что прерывания не будет. Для выхода из режима отладки выполнить команду RunProgram Reset или нажать Ctrl-F2. 5.7. Операции со строками В языке Delphi есть несколько полезных при работе со строками функций и процедур. Некоторые из них уже описывались ранее в обработчике событий KeyPress. 5.7.1. Стандартные функции и процедуры работы со строками
Функция length Функция length возвращает длину строки. У этой функции один параметр – выражение строкового типа. Значением функции length (целое число) является количество символов, из которых состоит строка. Например, в результате выполнения инструкций
n:=length('Иванов'); m:=length (' Невский проспект '); значение переменных n и m будет равно 6 и 20.
Процедура delete Процедура delete позволяет удалить часть строки. В общем виде обращение к этой процедуре выглядит так:
delete(Строка, р, п) где: Строка – переменная или константа строкового типа; p – номер символа, с которого начинается удаляемая подстрока; п – длина удаляемой подстроки. Например, в результате выполнения инструкций
s: ='Город Санкт-Петербург'; delete(s,7,6) ; значением переменной s будет строка 'Город Петербург'.
Функция pos
Функция pos позволяет определить положение подстроки в строке. В общем виде обращение к функции выглядит так: 75
pos (Подстрока, Строка) ; где подстрока – строковая константа или переменная, которую надо найти в строковой константе или переменной Строка. Например, в результате выполнения инструкции
p:= pos('Пе','Санкт-Петербург'); значение переменной р будет равно 7. Если в строке нет искомой подстроки, то значение функции pos будет равно нулю. Ниже приведена инструкция while, в результате выполнения которой удаляются начальные пробелы из строки st.
while(pos(' ',st) = 1) and(length(st) > 0) do delete (st,1,1); Пробелы удаляет инструкция delete (st,l,l), которая выполняется в цикле до тех пор, пока первым символом строки является пробел. В этом случае значение pos(' ',st) равно единице. Необходимость проверки условия length (st) > 0 объясняется возможностью того, что введенная строка состоит только из пробелов.
Функция сору Функция сору позволяет выделить фрагмент строки. В общем виде обращение к функции сору выглядит так:
сору(Строка ,р,n) где: Строка – выражение строкового типа, содержащее строку, фрагмент которой надо получить; P– номер первого символа, с которого начинается выделяемая подстрока; n – длина выделяемой подстроки. Например, в результате выполнения инструкций
st:= 'Инженер Иванов'; fam:=copy(st, 9,6); значением переменной fam будет строка 'Иванов'. 5.7.2. Использование операций со строками В качестве примеров использования операций со строками можно привести примеры функций проверки допустимости ввода символов. Функция isint проверяет, является ли символ, соответствующий клавише нажатой во время ввода целого числа в поле редактирования, допустимым. Предполагается, что допустимыми являются цифры, клавиши и .
// проверяет, является ли символ допустимым // во время ввода целого числа function IsInt(ch : char) : Boolean; begin if (ch >= '0') and (ch ='0') and (ch='0')and (st[Length(st)]=0) and (Length(StringGrid1.Cells[StringGrid1.Col,1])= '0') and (ch ='0') and (ch= '+ E1.Text+') '+'and (Stag = '+ E1.Text+') '+ 'and (Stag