МИНИСТЕРСТВО ОБРАЗОВАНИЯ РОССИИ Томский политехнический университет _______________________________________________________
УТВЕРЖДАЮ Декан АВТФ ________________ Мельников Ю.С. “__” ______2002 г.
ПРОГРАММЫ И МОДУЛИ DELPHI Методические указания к лабораторной работе № 129 по курсу “Программирование и основы алгоритмизации” для студентов направления 550200 “Автоматизация и управление”
Томск — 2002
УДК 681.3 Программы и модули Delphi. Методические указания к лабораторной работе № 129 по курсу “Программирование и основы алгоритмизации ” для студентов направления 550200 “Автоматизация и управление”.
Составитель Н.М. Семёнов Рецензент к.т.н., доцент Е.И. Громаков
Методические указания рассмотрены и рекомендованы методическим семинаром кафедры интегрированных компьютерных систем управления “___” ___________ 2002 г. Зав. кафедрой
А.М. Малышенко
ОГЛАВЛЕНИЕ 1 Программа BUTTON .............................................................. 1.1 Создание программы .................................................... 1.2 Сохранение файлов проекта ........................................ 1.3 Выполнение программы BUTTON ..............................
4 4 6 7
2 Исследование кода ................................................................. 2.1 Программный код ......................................................... 2.2 Модули, поддерживающие формы .............................. 2.3 Программы и модули ................................................... 2.4 Программы и проекты Delphi ......................................
7 7 8 9 10
3 Раздел интерфейса .................................................................. 3.1 Оператор uses ................................................................ 3.2 Оператор const .............................................................. 3.3 Оператор type ................................................................ 3.3.1 Класс Паскаля .................................................. 3.3.2 Поля класса ...................................................... 3.3.3 Методы класса ................................................ 3.3.4 Классы и наследование ................................... 3.3.5 Класс и объекты ...............................................
10 11 11 11 11 12 13 13 14
Раздел реализации .................................................................. Контрольные вопросы ............................................................ Дополнительные задания ....................................................... Литература ..............................................................................
15 15 16 16
4 5 6 7
Программы и модули Delphi Настоящая лабораторная работа призвана познакомить студентов с построением простой программы Delphi, а также тонкой настройкой свойств визуальных управляющих элементов. Тут же студенты узнают, как задать реакцию визуальных управляющих элементов на нажатие мыши. Лабораторная работа предусматривает следующие этапы: 1) Создание простой демонстрационной программы BUTTON. 2) Исследование программного кода, который обычно генерируется Delphi. 3) Изучение раздела интерфейса модуля библиотеки. 4) Изучение раздела реализации модуля библиотеки. 5) Выполнение дополнительного задания.
1 Программа BUTTON Delphi предлагает для создания программы мощные визуальные инструментальные средства программирования. Приступим к созданию формы с одиночной графической кнопкой, т.е. кнопкой, которая может быть связана с изображением в стандарте bitmap. Когда Вы нажимаете на кнопку, программа отображает диалоговое окно сообщения. Когда Вы нажимаете на кнопку ОК этого диалогового окна, программа закрывает форму и заканчивает выполнение. Графическая кнопка - это кнопка, которая имеет связанное с ней изображение в стандарте bitmap (записанное в файле .bmp). 1.1 Создание программы Чтобы создать и запустить программу BUTTON, выполните следующее: 1. Загрузите Delphi, если она ещё не загружена. 2. Выполните команду Файл/ Создать/ Приложение, чтобы создать новый проект. 3. Нажмите на закладку страницы Additional в Палитре компонентов. 4. Нажмите на графическую кнопку, которая является крайней левой кнопкой в палитре. 5. Переместите указатель мыши на середину окна формы. 6. Держите левую кнопку мыши нажатой и переместите мышь к нижнему левому углу формы. Когда Вы перемещаете мышь, Delphi показывает контур графической кнопки, которую Вы рисуете. Отпустите кнопку мыши по Вашему усмотрению. Тем самым завершится установка кнопки. 7. Delphi отображает разрядную кнопку с заголовком по умолчанию BitBtn1, как показано на рис. 1. 8. Нажмите на закладку страницы Свойства (Properties) в окне Инспектора объектов. 9. Нажмите на свойство Caption, которое имеет текст BitBtn1. Удалите этот текст и напечатайте Close. Когда Вы закончили, нажмите Enter. Delphi отобразит новый заголовок на разрядной кнопке. 10. Нажмите на свойство Glyph, имеющее текущее значение “Нет”. Delphi отображает маленькую кнопку с тремя точками (после текущего значения Glyph). 11. Нажмите на кнопку Glyph с тремя точками. Delphi отображает диалоговое окно “Редактор картинки”, как показано на рис. 2.
12. Нажмите на кнопку “Открыть”, чтобы загрузить изображение .BMP. Система Delphi отображает диалоговое окно “Загрузить картинку”, которое очень похоже на стандартное диалоговое окно Windows Open File.
Рис.1. Графическая кнопка с заголовком по умолчанию.
Рис.2. Диалоговое окно “Редактор картинки”.
13. Выберите файл Geometrix из каталога WNT или WINDOWS. Вы можете выбирать любой другой файл .bmp в любой другой директории. Конечно, различные файлы .bmp отобразят на кнопке различные изображения. 14. Нажмите кнопку ОК в диалоговом окне “Редактор картинки”. 15. Нажмите свойство Name в Инспекторе объекта. Имя управляющего элемента по умолчанию - BitBtn1. Удалите это имя и напечатайте CloseBtn. 16. Нажмите табличку страницы “События” в Инспекторе объектов. Система Delphi показывает список событий, которые могли бы быть связаны с разрядной кнопкой. 17. Нажмите два раза на событии OnClick. (Нажимать надо на правом чистом белом поле). Система Delphi отображает окно UNIT1 (рис. 3) и помещает курсор для вставки текста внутри процедуры TForm1.CloseBtnClick.
Рис.3. Окно UNIT1. 18. Напечатайте два следующих оператора: MessageDlg(‘Close form’, mtInformation, [mbOK],0); Close; 1.2 Сохранение файлов проекта Сначала сохраняется модуль по опции “Файл/ Сохранить как”. Система Delphi отображает диалоговое окно с заголовком “Сохранить Unit1 как”. Выберите личную поддиректорию и затем введите имя UBUTTON.PAS в окошко редактирования File Name. Чтобы сохранить проект, выберите опцию “Файл/ Сохранить проект как” . Система Delphi отображает диалоговое окно с заголовком “Сохранить Project1 как”. Выберите личную поддиректорию и затем введите имя BUTTON.DPR в окошке редактирования File Name.
1.3 Выполнение программы BUTTON
Чтобы оттранслировать и запустить программу BUTTON, нажмите функциональную клавишу F9 или выберите опцию Выполнить/ Выполнить. Система Delphi транслирует, компонует и выполняет программу. Если обнаружена ошибка, Delphi подсвечивает неправильный оператор и отображает сообщение об ошибке. Когда программа выполняется, она отображает форму с графической кнопкой Close. Нажмите на эту кнопку, чтобы отобразить диалоговое окно сообщения (см. рис. 4). Когда Вы нажимаете кнопку ОК диалогового окна сообщения, программа закрывает форму и заканчивает выполнение.
Рис. 4. Типовой сеанс с программой BUTTON.
2 Исследование кода Достоинство программирования Delphi в том, что она генерирует систематически необходимый код. Вы должны концентрироваться только на настраиваемой части кода. Исследуем код, сгенерированный Delphi, и посмотрим, как использовались два оператора, которые Вы ввели. 2.1 Программный код Каждая программа имеет основную часть, которая начинает выполняться первой. Эта основная часть обычно вызывает другие, вторичные, части, чтобы выполнить различные требуемые задачи. Программа BUTTON не исключение. Она имеет основную часть и вторичную часть. Листинг 1 показывает основную часть, которая хранится в файле BUTTON.DPR. Программа коротка, потому что использует модули, которые выполняют большую часть работы. Система Delphi сама сгенерировала все операторы в листинге 1. ______________________________________________________________
1: program Button; 2: 3: uses 4: Forms, 5: Ubutton in 'UBUTTON.PAS' {Form1}; 6: 7: {$R *.RES} 8: 9: begin 10: Application.Initialize; 11: Application.CreateForm(TForm1, Form1); 12: Application.Run; 13: end. ______________________________________________________________ Листинг 1. Исходный текст для программы BUTTON.DPR. Строка 1 содержит ключевое слово program, которое сообщает компилятору, что это основная часть программы. Если создаётся библиотека DLL, вместо него используется слово library, если новый пакет – слово package. Строки 4 и 5 определяют имена двух использованных библиотечных модулей. Строка 4 определяет модуль Forms, который поддерживает формы. Строка 5 определяет модуль Ubutton и указывает, что этот модуль хранится в файле UBUTTON.PAS. Строка 7 содержит директиву. Директивы - специальные команды компилятору, которые включены в комментарии, но начинающиеся со знака $, за которым следует имя директивы. Строки между ключевыми словами begin и end содержат операторы основной программы: строка 10 содержит обращение к методу Initialize, который предусмотрен “на всякий случай” и по умолчанию ничего не делает [3]; строка 11 содержит оператор, который создаёт форму, а строка 12 содержит оператор, который запускает программу. 2.2 Модули, поддерживающие формы Для того, чтобы поддерживать форму, Delphi использует модули Паскаля. Рассмотрим листинг 2 , который показывает исходный текст для модуля UBUTTON.PAS. ______________________________________________________________ 1: unit Ubutton; 2: 3: interface 4: 5: uses 6: Windows, SysUtils, , Messages, Variants, Classes, Graphics, Controls, 7: Forms, Dialogs, StdCtrls, Buttons; 8: 9: type 10: TForm1 = class(TForm) 11: CloseBtn: TBitBtn; 12: procedure CloseBtnClick(Sender: TObject); 13: private
14: { Private declarations } 15: public 16: { Public declarations } 17: end; 18: 19: var 20: Form1: TForm1; 21: 22: implementation 23: 24: {$R *.DFM} 25: 26: procedure TForm1.CloseBtnClick(Sender: TObject); 27: begin 28: MessageDlg('Close form',mtInformation,[mbOK],0); 29: Close; 30: end; 31: 32: end. ______________________________________________________________ Листинг 2. Исходный текст для модуля UBUTTON.PAS. Строки с 5 по 7 перечисляют имена модулей, используемых модулем Ubutton. Строки с 9 по 17 определяют класс TForm1, который поддерживает форму. Строка 19 определяет экспортируемую переменную Form1, имеющую тип TForm1. Часть реализации начинается на строке 22. Эта часть определяет процедуру TForm1.CloseBtnClick, которая отвечает за реакцию на нажатие мыши на графической кнопке. Строки 28 и 29 - Вами написанные строки. Оператор в строке 28 выводит на дисплей диалоговое окно сообщения. Оператор Close в строке 29 закрывает форму. Delphi сама сгенерировала все операторы в листинге 2, кроме тех, что находятся в строках 28 и 29. Как Delphi “придумала” имя процедуры в строке 26 ? Ответ находится в объявлении класса TForm1 в строках с 10 по17. Строка 12 объявляет процедуру CloseBtnClick. Это имя составлено из имени кнопки CloseBtn и имени события Click. Определение процедуры в строке 26 использует имя класса TForm1, к которому относится процедура, затем следует точка и имя процедуры. Этот синтаксис сообщает компилятору, что процедура CloseBtnClick принадлежит классу TForm1. 2.3 Программы и модули Каждое приложение Паскаля имеет одну и только одну основную часть программы. Основная программа может использовать экспортируемые части одного или большего количества модулей. В свою очередь эти модули могут использовать экспортируемые части других модулей. Таким образом, приложение может быть сделано из иерархической последовательности независимых модулей низкого, среднего, высокого уровня и основной части программы. 2.4 Программы и проекты Delphi
Система Delphi объединяет язык программирования Паскаль с визуальными возможностями программирования. Чтобы выполнить такое совмещение, приложения Delphi используют файлы проекта, которые поддерживают приложения. Во время разработки генерируются следующие типы файлов: Файл проекта .DPR содержит исходный паскалевский текст основной программы проекта. Файл .DPR перечисляет все файлы форм и модулей проекта и содержит код, который инициализирует приложение. Delphi создаёт файл проекта, когда Вы сохраняете его в первый раз. Модуль .PAS содержит исходный (Object Pascal) код. Delphi создаёт один файл .PAS для каждой формы, которую содержит проект, когда сохраняется в первый раз. Файл .PAS содержит все объявления и процедуры формы (вместе с процедурами, обрабатывающими события). Файлы формы (.DFM), каждый из которых содержит проектные свойства одной формы, содержащейся в проекте. Delphi генерирует один файл .DFM, так же как и соответствующий файл .PAS для каждой формы проекта, когда проект сохраняется в первый раз. Файл.DDP – сохраняет сведения обо всех созданных для окон диаграммах. .RES - откомпилированный файл ресурсов, который является двоичным файлом и содержит пиктограмму программы и отдельные внешние ресурсы, используемые проектом. ~DP - файл резервной копии проекта, который генерируется при втором сохранении проекта и модифицируется при последующих сохранениях. Файл ~DP содержит копию файла .DPR, каким он был перед самым последним сохранением. .~PA - файл резервной копии модуля, который содержит копию файла .PAS в том виде, в котором он существовал перед самым последним сохранением. Delphi создаёт этот параллельный файл при втором сохранении проекта и обновляет его при последующих модификациях и сохранениях файла PAS. .~DF - графическая резервная копия формы. Delphi создаёт этот файл, когда Вы открываете файл .DFM как текст в редакторе кода, делаете изменения и затем сохраняете .DFM - файл. Файл ~DF содержит копию файла .DFM в двоичном формате, каким он был перед последним сохранением. .DSK -файл установок рабочей среды, который содержит информацию относительно установок, которые Вы сделали для проекта в опциях Сервис/ Опции среды. .CFG – файл с параметрами настройки компилятора; .DOF – файл с параметрами настройки проекта
3 Раздел интерфейса Здесь более подробно рассматривается раздел интерфейса библиотечного модуля. Раздел интерфейса модуля определяет, какие элементы модуля являются доступными для других модулей и программ. Вы можете думать об этих элементах как об экспортируемых. В следующих подразделах кратко рассматриваются различные части модуля Паскаля. Важно отметить, что большая часть последующего обсуждения применима к основной части программы - приложения Паскаля. 3.1 Оператор uses
Оператор uses сообщает компилятору, что модуль использует экспортируемые части других модулей. Оператор uses перечисляет модули поддержки, отделённые друг от друга запятыми. В листинге 2 в строках с 6 по 7 перечисляется 11 модулей, которые используются модулем Ubutton. 3.2 Оператор const Оператор const перечисляет имена идентификаторов, которые имеют фиксированные значения. Эти значения могут быть целыми, с плавающей запятой, строками, а также другими зарезервированными или определяемыми пользователем типами данных. 3.3 Оператор type Оператор type позволяет объявлять Ваши собственные типы данных. Эти новые типы данных могут быть записями или классами. Запись - это набор полей, которые представляют её элементы. Синтаксис. Общий синтаксис для объявления записи (Record). Type recordName = Record field1 : typeField1; field2 : typeField2;
end; Объявление определяемой пользователем записи начинается с определения имени типа записи. Поля, которые составляют определение записи, должны иметь зарезервированные типы данных и/или предварительно объявленные типы записи. Хотя имена типов записи должны быть уникальны в программе, типы записи могут иметь поля с одинаковыми именами. Примеры : type TDate = record Day, Month, Year : Integer; end; TDuration = record Start, Finish : TDate end; 3.3.1 Класс Паскаля Delphi позволяет объявлять классы, которые играют важную роль в создании и управлении формами и их управляющими элементами. О классе можно думать как о супер-записи, которая объединяет поля и методы. Поля описывают состояние объекта, в то время как метод определяет, как объект управляется. Синтаксис. Общий синтаксис класса. Type TClassName = Class public
protected <protected fields> <protected methods> private <private fields> <private methods> end; Объявление класса имеет три возможных раздела, которые определяют доступность полей и методов. Раздел public объявляет поля и методы, не имеющие никаких ограничений доступа - экземпляры класса и классы - потомки могут иметь доступ к этим полям и методам. Раздел protected объявляет поля и методы, имеющие некоторые ограничения доступа - классы - потомки могут иметь доступ к этим полям и методам. Раздел private объявляет поля и методы, имеющие серьёзные ограничения доступа - экземпляры класса или классы - потомки к ним обращаться не могут. Пример: Type TTimeClas = class public constructor Initialize; procedure SetHour (dHour : Integer); procedure SetMinute (dMinute : Integer); procedure SetSecond (dSecond : Integer); function GetHour : Integer; function GetMinute : Integer; function GetSecond : Integer; protected Hour : Integer; Minute : Integer; Second : Integer; end; Класс TTimeClass объявляет три защищённых поля : Hour, Minute и Second. Класс объявляет методы для инициализации, установки и опроса защищённых полей. Цель объявления класса - возвратить количество секунд, прошедших с полуночи. 3.3.2 Поля класса Поля класса содержат данные (или состояния, если Вам больше нравится), которые определяют атрибуты экземпляров класса. Общее практическое правило надо избегать объявление поля как public до тех пор, пока объявление public не становится более практичным. Например, класс TTimeClass, объявленный в предыдущем разделе, имеет методы, предназначенные для опроса защищённых полей. Поскольку эти методы созданы для того, чтобы дать полный доступ к защищённым полям, Вы можете определить более короткую версию класса TTimeClass следующим образом: Type TTimeClass =class
public Hour : Integer; Minute : Integer; Second : Integer; Initialize; function GetSeconds : Integer; end; Таким образом, новая версия имеет меньшее количество кода, потому что поля объявлены как public. 3.3.3 Методы класса Методы класса - процедуры и функции, которые манипулируют полями и возвращают результаты, основанные на текущих значениях полей. Важно подчеркнуть, что методы класса автоматически имеют доступ ко всем полям этого класса. Поля не надо передавать в качестве параметров процедур или функций. Пример того, как мог бы выглядеть код функции GetSeconds : function TTimeClass.GetSeconds( ) : Integer; begin GetSeconds :=Second +60*(Minute + 60*Hour); end; Обратите внимание, что функция GetSeconds имеет доступ к полям Second, Minute и Hour. Эта реализация допустима для любой версии класса TTimeClass. 3.3.4 Классы и наследование Эффективность использования классов заключается в возможности создавать новые классы как потомки существующих. Каждый класс - потомок наследует поля и методы родителя и классов - предков. Можно также объявлять методы в новых классах, которые отменяют унаследованные. Эта возможность позволяет не замыкаться на использовании унаследованных методов, которые не соответствуют потребностям нового класса. Фактически классы - потомки совершенствуют поведение своих предков, вводя новое, более специализированное, поведение. Синтаксис. Общий синтаксис класса - потомка. Type TClassName = Class(TParentClassName) public protected <protected fields> <protected methods> ptivate <private fields> <private methods>
end; Синтаксис, приведённый выше, похож на синтаксис для класса-не-потомка (также называемого базовым классом). Обратите внимание, что ключевое слово Class сопровождается именем родительского класса, заключённого в круглые скобки. Пример класса - потомка: Type TTimeClass = class public Hour : Integer; Minute : Integer; Second : Integer; Initialize; function GetSeconds : Integer; end; TDateTime = class(TTimeClass) public Year : Integer; Month : Integer; Day : Integer; Initialize; function GetDayNumber : Integer; end; Класс TDateTime - потомок класса TTimeClass и наследует поля Hour, Minute и Second. Класс потомка также наследует метод GetSeconds. Класс TDateTime отменяет унаследованный метод Initialize и объявляет метод GetDayNumber. 3.3.5 Класс и объекты Объекты - это экземпляры классов. Вы объявляете объект в операторе var точно так же, как и другие переменные. Каждый объект имеет собственный набор полей класса и может обращаться только к его публичным ( public ) полям. Аналогично, только публичные методы класса могут применяться к объекту. Объектно - ориентированное программирование (Object - oriented programming OOP) подразумевает управление объектами путём посылки им сообщений. Сообщение указывает объекту выполнить задачу. Объект ищет метод, чьё имя соответствует такому сообщению, и применяет этот метод. Таким образом, OOP - сообщение определяет, что делать объекту, в то время как метод определяет, как управлять объектом. Паскаль использует операцию точки, чтобы обратиться к публичным полям объекта и также посылать сообщение объекту. Пример посылки OOP - сообщения к экземпляру класса : var DT : TDateTime; N : Integer;
begin DT.Initialize; N := DT.GetDayNumber end; В этом примере объекту DT, который является экземпляром класса TDateTime, посылаются сообщения Initialize и GetDayNumber.
4 Раздел реализации Раздел реализации содержит детализированную реализацию экспортируемых функций и процедур. Кроме того, раздел содержит объявления локальных констант, типов данных и переменных, также как и реализацию локальных функций и процедур. Следовательно, раздел реализации имеет доступ и к экспортируемым, и к локальным константам, типам данных и переменным. Директива $R Директива $R - это директива файла ресурсов. Общий синтаксис для этой директивы: { $R FileName } Директива $R определяет имя файла ресурсов, который будет включен в приложение или библиотеку. Расширение по умолчанию для параметра FileName .RES. FileName должен быть файлом ресурсов Windows. Если имя файла не содержит директорию, компилятор ищет его сначала в текущей директории, а затем просматривает директории, включенные в команду path. Когда Вы помещаете в модуль директиву $R, имя файла ресурса просто записывается в результирующий файл модуля. Компилятор во время компиляции не выполняет никаких проверок, чтобы гарантировать существование файла. Когда Вы помещаете директиву $R в приложение, или когда компонуется библиотека, файлы ресурсов, определённые во всех модулях и в программе или в самой библиотеке, обрабатываются, и каждый ресурс из каждого файла ресурсов копируется в генерируемые файлы .EXE или .DLL.
5 Контрольные вопросы 1. Что такое процедура, обрабатывающая событие ? (см. листинг 2) 2. К каким полям класса (public, protected, private) имеют автоматический доступ методы класса ? 3. Чем поле класса отличается от метода класса ? 4. Что такое “базовый класс” ? 5. Что такое “объект” ? 6. Что обозначает директива $R ? 7. Может ли модуль вызывать программу ?
6 Дополнительные задания 1. Измените программу BUTTON так, чтобы она отображала сообщение “I am Pascal Programmer”. 2. Создайте программу BTN2, которая использует стандартную кнопку управления вместо графической кнопки. Измените заголовок по умолчанию кнопки Button1 на Close. Также измените имя по умолчанию кнопки Button1 на CloseBtn. Заставьте кнопку отвечать на событие Click и вставьте те же операторы, что и в программе BUTTON. 3. Удалите в директориях, связанных с проектами BUTTON и BTN2, все “лишние” файлы. Оставьте только те, которые позволяют быстро “реанимировать” проекты.
7 Литература 1.Возневич Э. Delphi. Освой самостоятельно. - М.: Восточная Книжная Компания, 1996. - 736 с. 2. Рубенкинг Н. Программирование в Delphi для “чайников”. -К.: Диалектика, 1996. - 304 с. 3. Фаронов В. Delphi 6: учебный курс. – СПб.: Питер, 2002. – 512 с.