Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ракитин Р.Ю. ООП в Turbo Delphi

.PDF
Скачиваний:
56
Добавлен:
18.03.2015
Размер:
3.59 Mб
Скачать

101

finalization //необязательный

{Операторы, выполняемые при любом завершении работы модуля}

end.

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

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

Раздел initialization включает в себя операторы, которые

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

Раздел finalization включает в себя операторы, которые выполняются только один раз при любом завершении работы программы: нормальном или аварийном. Этот раздел не является обязательным. В нем могут помещаться какие-то операторы, производящие зачистку «мусора» – удаление временных файлов, освобождение ресурсов памяти и т.п. Введение раздела finalization не разрешается, если в модуле нет раздела initialization.

Предложение uses подключение модулей

Предложение, определяющее подключаемые к проекту или используемые в данном модуле другие модули, начинается с ключевого слова uses, после которого следует список имен модулей, разделяемый запятыми. Например:

uses Windows, Messages, SysUtils, Classes, Unit2, MyUnit;

Предложение uses в головном файле (DPR) программы может также содержать после имени модуля ключевое слово in, после которого указывается имя файла, содержащего модуль. Например:

uses Unitl in ‘Unitl.pas’,

Unit2 in ‘с:\examples\Unit2.pas’;

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

102

+ В предложениях uses, включаемых в модули, использование in не

допускается.

При взаимных ссылках модулей друг на друга не разрешаются циклические ссылки с помощью предложений uses, размещенных в разделах interface. Такие циклы надо разрывать, перенося одно или все предложения uses из разделов interface в разделы implementation модулей. Например,

недопустимыми циклическими ссылками являются следующие предложения uses в модулях Unitl и Unit2:

unit Unitl

unit Unit2

...

...

interface

interface

uses ... Unit2;

uses ... Unitl;

...

...

implementation

implementation

...

...

В этом случае компилятор выдаст сообщение об ошибке:

[Fatal Error] Unitl.pas(3): Circular unit reference to 'Unitl1

и приложение не будет скомпилировано. Выходом из положения является вариант, когда в одном модуле ссылка uses помещена в раздел interface, а в другом в implementation, или в обоих модулях соответствующие ссылки помещены в разделах implementation:

unit Unitl;

unit Unit2;

...

...

interface

interface

...

...

implementation

implementation

uses ... Unit2;

uses ... Unitl;

...

...

Как правило, при решении задач будем работать с двумя типами модулей:

1. Модуль, связанный с определенной формой окном. Например, можно выбрать File New Form (Файл → Новая → Форма). При создании данного модуля автоматически создается новый объект класса TForm.

2. Модуль не связанный с визуальным объектом File New Unit

(Файл → Новый → Модуль). При этом создается пустой модуль.

Многооконные приложения

Как отмечалось выше, каждой программе в Windows сопоставляется окно

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

103

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

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

Windows.

Создание дочерних окон

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

Как было показано в Главе 3, можно менять список форм, которые будут созданы автоматически, а также определять, какая форма будет основной.

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

Создадим и сохраним новый проект. Для просмотра исходного кода проекта (головного файла) выберем в меню Project View Source (Проект → Просмотр кода).

program Project1; uses

Forms,

Unit1 in 'Unit1.pas' {Form1}; {$R *.res}

begin

Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run;

end.

Это код хранится в файле Project1.dpr. В первой строке стоит имя программы program Project1. Затем идёт раздел uses, в котором можно подключать необходимые модули. В нашем случае подключен модуль Forms (позволяет работать с формами) и Unit1 (модуль главного окна).

Между begin и end выполняется три строчки:

104

Application.Initialize запускает инициализацию приложения. Убирать не рекомендуется.

Application.CreateForm (TForm1, Form1) метод CreateForm создает объект Form1 класса TForm1. Переменная Form1 автоматически описывается в модуле объекта TForm1 (в нашем случае это модуль

Unit1.pas) в разделе var.

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

Создадим еще одну форму. В исходном коде проекта автоматически появится еще две строки, одна в разделе uses Unit2 in 'Unit2.pas' {Form2}; другая в разделе выполнения означающая создание новой формы:

Application.CreateForm (TForm2, Form2);

+ Головной файл создается автоматически и требует внесения

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

Существует еще один способ создания формы, это вызов конструктора Create соответствующего класса, однако такой подход обычно не имеет смысла, так как в методе CreateForm класса ТApplication выполняются точно такие же действия:

unit Unitl; //Заголовок модуля главной формы implementation //Начало описательной секции модуля uses Unit2; //Подключение модуля вспомогательной формы

...

//Обработчик нажатия на кнопку Buttonl главной формы procedure TForml.ButtonlClick (Sender: TObject); var

//Списание ссылки на экземпляр вспомогательной формы

AForm: TForm2; begin

//Форма создается прямым вызовом конструктора, и в //качестве владельца формы указывается глобальная

//переменная Application

AForm := TForm2.Create(Application); end;

...

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

105

unit Unitl; //Заголовок модуля главной формы implementation //Начало описательной секции модуля uses Unit2; //Подключение модуля вспомогательной формы

...

//Обработчик нажатия на кнопку Buttonl главной формы procedure TForml.ButtonlClick(Sender: TObject);

var

//Описание ссылки на экземпляр вспомогательной формы

AForm: TForm2; begin

{Форма создается прямым вызовом конструктора, в качестве владельца указывается форма, которой принадлежит метод ButtonlClick. Указание происходит с помощью ключевого слова Self}

AForm:= TForm2.Create(Self); end;

...

Окна приложений могут отображаться на экране в модальном режиме

когда пользователь не имеет возможности переключаться между окнами одной программы, или немодальном, когда переключение между окнами допустимо. Для вывода формы на экран используются методы объекта TForm: Show и ShowModal без параметров. Рассмотрим окна вызываемые данными методами подробнее.

Не модальные окна

Метод Show позволяет показать форму в немодальном режиме. В этом случае главная форма создаст дочернее окно, показав его на экране, и продолжит выполняться дальше. Это позволит работать с обеими формами одновременно, переключаясь между ними.

Создадим новую форму и назовем её FormNoModal, полученный модуль сохраним с именем UnitNoModal.

Разместим на основной форме кнопку, в свойстве Caption напишем «No Modal Window». Создадим обработчик события OnClick этого объекта. В получившемся обработчике напишем:

FormNoModal.Show;

Данный метод аналогичен изменению свойства Visible формы на True.

Модальные окна

Создадим форму с кнопкой, нажатие на которую приведет к появлению окна с информацией о программе.

106

Создадим новое приложение (основной модуль Unit1, главная форма Form1). Разместим на главной форме объект класса TButton, в свойстве Caption которого укажем «About».

Изменим имя главной формы (свойство Name) на FormMain. Сохраним проект. При сохранении модуля Unit1 изменим имя файла на UnitMain.

Создадим еще одну форму. Для этого в меню выберем соответствующий пункт File New Form (Файл → Новая → Форма). Убедимся, что в проекте теперь описано два модуля, для этого откроем View Project Manager (Вид → Менеджер проектов). Двойной щелчок по любой из

форм в менеджере проектов вызовет форму в дизайнер для редактирования.

Изменим имя созданной формы Form2 на FormAbout. Сохраним проект (FileSave All…), при этом имя модуля

Unit2 изменим на UnitAbout.

Изменим заголовок формы FormAbout на «Информация о программе». Разместим на данной форме компоненты Label, в которых укажем информацию о программе:

Для открытия формы FormAbout создадим обработчик события OnClick объекта Кнопка на главной форме. В получившемся обработчике напишем:

FormAbout.ShowModal;

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

Откомпилируем код. Получим информационное сообщение:

Это связано с тем, что форма AboutForm описана в модуле UnitAbout, а используется в UnitMain. Чтобы в модуле UnitMain можно было использовать свойства и методы из модуля UnitAbout, его требуется

107

подключить. Для этого необходимо нажать «Yes» на информационном сообщении. При этом в модуле UnitMain в разделе implementation

появиться строка

uses UnitAbout;

Подключение можно сделать и через специальное окно, которое вызывается через File Use Unit… (Файл → Использовать модуль...) или в ручную, как было показано выше.

Теперь можно запустить приложение.

Обмен данными между формами

Если в приложении используется несколько форм, то часто возникает

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

Создадим приложение, в котором после нажатия кнопки Открыть (TButton) в главном окне FormMain, откроется модальное окно FormModal, состоящее из компонентов Edit и Button (см. рис.). Изменим имена

для кнопок в соответствии с назначенными действиями

– «Открыть» ButOpen, «Закрыть» ButClose и «Отмена» ButCancel.

Рассмотрим свойство кнопок ModalResult. В этом свойстве можно задавать значение, возвращаемое при закрытии окна. Это свойство имеет предустановленные значения, которые можно выбрать из выпадающего списка. Выберем для кнопки «Закрыть» значение mrOk, а для «Отмена» mrCancel. Если теперь откроем окно FormModal, как модальное, и потом закроем его кнопкой «Закрыть», то функция ShowModal вернёт нам значение mrOk, если же нажмем «Отмена», то mrCancel.

Создадим обработчик для кнопки ButOpen главной формы.

procedure TForm1.ButOpenClick(Sender: TObject); begin

if FormModal.ShowModal = mrOK then Application.MessageBox (PChar(FormModal.Edit1.Text),

'Что введено', MB_OKCANCEL)

end;

В первой строке вызывается модальное окно и сразу проверяется возвращаемое значение. Если оно равно mrOK, то выполняется следующее действие. Вторая строка показывает стандартное диалоговое окно. Это делается с помощью метода MessageBox объекта Application (подробнее в Главе 3).

108

В качестве текста сообщения в окне выводится текст, введенный в строку ввода модального окна (FormModal.Editl.Text).

Теперь если нажать в модальном окне кнопку «Закрыть», то появится окно с введенным текстом, иначе ничего не произойдет.

Многодокументные MDI окна.

Пример многодокументного MDI окна показан на рисунке. При

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

Для создания MDI программы создадим новое приложение. Главный модуль назовем UnitMain, а главную форму FormMain. В

главном окне укажем в свойстве

FormStyle значение fsMDIForm.

Создадим в проекте еще одну форму, назовем ее FormChild.

Укажем в ее свойстве FormStyle

значение fsMDIChild.

+ В приложение только одна форма может иметь значение fsMDIForm.

Использование простых модулей

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

Создадим новый проект. На главной форме (назовём её FormMain)

разместим два объекта класса TEdit для ввода в приложение двух чисел (назовём их EditA и EditB), объекты класса TButton для выполнения соответствующей арифметической операции, а так же объект TLabel (LabelResult) для вывода результата операции. Сохраним главный модуль под именем Main.

109

Создадим новый модуль, не связанный с визуальной формой File New Unit (Файл → Новый → Модуль) и сохраним его под именем Arifm. Подключим модуль в основной форме. В данном случае Delphi не подключит модуль Arifm в основном модуле Main автоматически. Сделаем это, добавим

следующий код в модуле Main:

...

implementation

uses Arifm;

...

Для примера создадим метод обработки сложения двух чисел. В модуле Arifm реализуем метод (функцию) сложения двух чисел:

...

interface

function Sum(x,y:real):real; implementation

function Sum(x,y:real):real; begin

Sum:=x+y; end;

...

где функция Sum позволит складывать два вещественных числа и возвращать результат в виде вещественного числа.

На кнопке ButSum (кнопка расчёта суммы) реализуем обработчик события OnClick. В методе запишем

LbResult.Caption:= FormatFloat ('0.00', Sum(StrToFloat(EditA.Text), StrToFloat(EditB.Text)));

Все расчеты производятся без введения дополнительных переменных. Текст из объектов Edit преобразуется в вещественные числа, которые передаются в функцию Sum модуля Arifm. Функция FormatFloat позволяет вывести вещественное число в форматированном виде (в данном случае два числа после запятой).

Аналогичным образом можно реализовать методы разности, умножения и деления.

110

Глава 9. Механизмы перетаскивания и стыковки

Механизм перетаскивания

Панели активно используются при необходимости перетаскивания объектов по форме при помощи мыши. Для реализации таких возможностей в программе, создаваемой с помощью системы Delphi, поддерживается механизм перетаскивания (технология drag-and-drop). Соответствующий метод заключается в следующем. После наведения указателя мыши на нужный объект нажимается левая кнопка мыши. Она удерживается нажатой, а объект в это время перетаскивается на новое место. После перетаскивания кнопка отпускается, и объект получает новое фиксированное местоположение. Подобным способом перетаскивают папки в Проводнике Windows, выделенный текст в текстовых редакторах и объекты в других программах.

Процесс программирования механизма перетаскивания осуществляется в несколько этапов:

1.Фиксируется начало работы данного механизма с помощью метода формы BeginDrag (например, при нажатии левой кнопки мыши над соответствующим объектом). При этом указатель мыши примет вид, указанный в свойстве DragCursor (значение по умолчанию crDrag).

2.Далее происходит обработка процесса перетаскивания. Для объектов, которые могут принять перетаскиваемый объект, задается обработчик события

OnDragOver Этот обработчик вызывается, когда указатель мыши в режиме перетаскивания перемещается над принимающим объектом. Объект должен ответить, готов ли он послужить «приёмником», занеся значение True (если готов) в параметр обработчика Accept, передаваемый по ссылке. В каких-то случаях от приема следует отказаться, например, если в рамках одной формы

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

3.Когда перетаскиваемый объект «брошен» (кнопка мыши отпущена), генерируется событие OnDragDrop. В нем выполняются все необходимые действия по обработке информации, хранящейся в перетаскиваемом объекте.

4.По окончании перетаскивания генерируется событие OnEndDrag. Его имеет смысл обрабатывать только если требуется проверить, успешно или нет выполнено перетаскивание. Для этого один из параметров обработчика Target

(тип TObject), хранящий ссылку на принимающий объект, надо сравнить со значением nil. Если «приёмник» отсутствует, то перетаскивание не выполнено.

Механизм стыковки

В ряде современных настольных приложений реализован новый подход к перемещению отдельных объектов и их групп. Элементы управления объединяются в стыкуемые палитры (Dock), которые могут свободно «плавать»