Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
_N8_.doc
Скачиваний:
2
Добавлен:
24.04.2019
Размер:
123.39 Кб
Скачать

5 Управление формами

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

Обычно сколько-нибудь сложное приложение содержит несколько форм. Включение в проект новой формы осуществляется командой File | New | Form или другими способами, {подробно описанными в разделе 2.4}. По умолчанию все формы создаются автоматически при запуске приложения, и первая из введенных в приложение форм считается главной. Главная форма отличается от прочих рядом свойств. Во-первых, именно этой форме передается управление в начале выполнения приложения. Во-вторых, закрытие пользователем главной формы означает завершение выполнения приложения. В-третьих, главная форма так же, как и любая другая, может быть спроектирована невидимой, но если все остальные формы зарыты, то главная форма становится в любом случае видимой (иначе пользователь не смог бы продолжать работать с приложением и даже не смог бы его завершить).

Указанные выше условия, принятые по умолчанию (первая форма — главная, все формы создаются автоматически), могут быть изменены. Главной в вашем приложении может быть вовсе не та форма, которая была спроектирована первой. Не стоит также в общем случае все формы делать создаваемыми автоматически. В приложении могут быть предусмотрены формы (например, формы для установки различных опций), которые требуются далеко не в каждом сеансе работы с приложением. Было бы расточительством создавать на всякий случай такие формы автоматически при каждом запуске приложения и занимать под них память. А в приложениях MDI дочерние формы в принципе не могут быть автоматически создаваемыми, так как число таких форм определяет пользователь во время работы приложения, создавая каждую новую форму командой типа Новое окно.

Изменить принятые по умолчанию условия относительно форм можно в окне опций проекта, которое вызывается командой Project Options. В открывшемся окне опций проекта (Project Options) надо выбрать страницу Forms.

В верхнем выпадающем списке Main form можно выбрать главную форму среди имеющихся в проекте. Пользуясь двумя нижними окнами можно установить, какие формы должны создаваться автоматически, а какие не должны. Например, если надо исключить форму Form2 из списка автоматически создаваемых, то надо выделить ее в левом окне (Auto-create forms) и с помощью кнопки со стрелкой, направленной вправо, переместить в правое окно доступных форм (Available forms).

Для каждой автоматически создаваемой формы Delphi добавляет в файл программы соответствующий оператор ее создания методом CreateForm. Это можно увидеть, если выполнить команду Project | View Source и просмотреть появившийся файл проекта .dpr. Он может, например, содержать следующие выполняемые операторы:

Application.CreateForm(TForml, Forml);

Application.CreateForm(TAboutBox, AboutBox);

Application.Run;

Первый и второй из них создают соответствующие формы, а третий начинает выполнение приложения.

Для форм, которые были исключены из списка автоматически создаваемых, аналогичный метод CreateForm надо выполнить в тот момент, когда форма должна быть создана.

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

В нужный момент форму можно сделать видимой методами Show или ShowModal. Последний метод открывает • форму как модальную. Это означает, что управление передается этой форме и пользователь не может передать фокус другой форме данного приложения до тех пор, пока он не закроет модальную форму.

Методы Show и ShowModal можно применять только к невидимой в данный момент форме. Если нет уверенности, что форма в данный момент видима, то прежде, чем применять эти методы, следует проверить свойство Visible формы. Например:

if (not Form2.Visible) then Form2.ShowModal;

При выполнении методов Show или ShowModal возникает событие формы onShow. Это событие возникает до того момента, как форма действительно станет видимой. Поэтому обработку события onShow можно использовать для настройки каких-то компонентов открываемой формы. Отличие от упомянутой ранее настройки компонентов в момент события onCreate заключается в том, что событие onCreate наступает для каждой формы только один раз в момент ее создания, а события onShow наступают каждый раз, когда форма делается видимой. Так что при этом в настройке можно использовать какую-то оперативную информацию, возникающую в процессе выполнения приложения.

Методом Hide форму в любой момент можно сделать невидимой. В этот момент в ней возникает событие onHide.

Необходимо помнить, что для выполнения методов CreateForm, Show, ShowModal, Hide и вообще для обмена любой информацией между формами модули соответствующих форм должны использовать друг друга. Например, если форма в модуле Unit1 должна управлять формой в модуле Unit2, то в предложение uses модуля Unit1 должно быть включено имя второго модуля Unit2. А если к тому же форма в модуле Unit2 должна пользоваться какой-то информацией, содержащейся в модуле Unit1, то в предложение uses модуля Unit2 должно быть включено имя первого модуля Unitl. В этом случае, если предложения uses в обоих модулях расположены в разделах Interface, возникнут проблемы с недопустимыми циклическими ссылками (circular unit reference) и компилятор выдаст соответствующую ошибку. От недопустимых циклических ссылок можно избавиться, поместив один или оба оператора uses в раздел implementation. Впрочем, проще не включать имена модулей приложения в предложения uses вручную, а использовать команду File | Use Unit, которая автоматизирует этот процесс и гарантирует отсутствие циклических ссылок.

Закрыть форму можно методом Close. При этом в закрывающейся форме возникает последовательность событий, которые можно обрабатывать. Их назначение — проверить возможность закрытия формы и указать, что именно подразумевается под закрытием формы. Проверка возможности закрытия формы необходима, например, для того, чтобы проанализировать, сохранил ли пользователь документ, с которым он работал в данной форме и который изменял. Если не сохранил, приложение должно спросить его о необходимости сохранения и, в зависимости от ответа пользователя, сохранить документ, закрыть приложение без сохранения или вообще отменить закрытие.

Рассмотрим последовательность событий, возникающих при выполнении метода Close.

Первым возникает событие onCloseQuery. В его обработчик передается как var (по ссылке) булева переменная CanClose, определяющая, должно ли продолжаться закрытие формы. По умолчанию CanClose равно true, что означает продолжение закрытия. Но если из анализа текущего состояния приложения или из ответа пользователя на запрос о закрытии формы следует, что закрывать ее не надо, параметру CanClose должно быть присвоено значение false. Тогда последующих событий, связанных с закрытием формы не будет.

Например, пусть в приложении имеется окно редактирования RichEditl, в котором свойство Modified указывает на то, был ли изменен пользователем текст в этом окне с момента его последнего сохранения. Тогда обработчик события onCloseQuery может иметь вид:

procedure TForml.FormCloseQuery(Sender: TObject;var CanClose: Boolean);

begin

if RichEditl.Modified then

if (Application.MessageBox('Текст документа не сохранен.'+

' Действительно хотите закончить работу ?', 'Подтвердите завершение

работы', MB_ICONQUESTION+MB_YESNOCANCEL) <>IDYES) then CanClose := false;

end;

В приведенном операторе вызывается методом Application.MessageBox диалоговое окно. Первый параметр метода содержит текст сообщения пользователю. Второй параметр — текст заголовка окна. Третий параметр — набор флагов, определяющих вид окна. Флаг MB_ICONQUESTION отображает в окне пиктограмму вопросительного знака. Флаг MB_YESNOCANCEL заносит в окно кнопки Да, Нет и Отмена.

Функция MessageBox возвращает результат, который указывает на реакцию пользователя в диалоговом окне. Значение IDYES возвращается, если пользователь нажал кнопку Да, значение IDNO возвращается при нажатии кнопки Нет, значение IDCANCEL — при нажатии кнопки Отмена или клавиши Esc.

В нашем примере, если пользователь в диалоговом окне с запросом о сохранении не ответит Да, то CanClose будет равно false и окно не закроется. Причем этот обработчик сработает при любой попытке пользователя закрыть приложение: нажатии в нем кнопки или раздела меню Выход, нажатии кнопки системного меню в полосе заголовка окна и т.п.

Если обработчик события onCloseQuery отсутствует или если в его обработчике сохранено значение true параметра CanClose, то следом наступает событие OnClose. В обработчик этого события передается как var переменная Action, которой можно задавать значения:

caNone

He закрывать форму. Это позволяет и в обработчике данного события еще отказаться от закрытия формы

caHide

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

caMinimize

При этом значении закрыть форму будет означать свернуть ее до пиктограммы. Как и в предыдущем случае, вся информация в форме будет сохранена

caFree

При этом значении закрыть форму будет означать уничтожение формы и освобождение занимаемой ею памяти. Вся информация, содержащаяся в форме, будет уничтожена. Если эта форма в да­льнейшем потребуется еще раз, ее надо будет создавать методом CreateForm

Не все значения Action допустимы для любых форм. Например, для дочерних форм в приложении MDI возможны значения только caNone и caMinimize.

Если в обработчике события OnClose задано значение Action, равное caFree, то при освобождении памяти возникает еще одно последнее событие — OnDestroy. Оно обычно используется для очистки памяти от тех объектов, которые автоматически не уничтожаются при закрытии приложения.

Следует отметить, что если приложение закрывается не непосредственно пользователем а посредством закрытия сессии операционной системы (Пуск | Выход из системы или Пуск | Выключение) то событие OnClose не происходит. Происходит только событие onCloseQuery при этом если обработчик определит значение параметра CanClose - False, то сессия операционной системы не будет закрыта

Свойство форм OldCreateOrder определяет моменты событий OnCreate и onDestroy. Если это свойство установлено в false (значение по умолчанию), то событие OnCreate наступает после того, как закончили работу все конструкторы компонентов, содержащихся на форме, а событие OnDestroy наступает прежде, чем вызывается какой-либо деструктор. При OldCreateOrder = true, что соответствует поведению компонентов в Delphi 3 и более ранних версиях, событие OnCreate наступает при выполнении конструктора TCustomForm, а событие OnDestroy наступает при выполнении деструктора TCustomForm.