Файл: Учебное пособие для студентов Авторы А. Н. Вальвачев, К. А. Сурков, Д. А. Сурков, Ю. М. Четырько Содержание Содержание 1.doc
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 04.05.2024
Просмотров: 134
Скачиваний: 4
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
FocusControl.
Шаг 9. Вспомним, что компонент Label понадобился нам для того, чтобы сделать необходимые надписи в окне About. Опустите в форму первую надпись справа от изображения и установите ее свойства следующим образом:
WordWrap = True
Caption = Picture Viewer
Font Color = clNavy
Font Name = Times New Roman
Font Size = 20
Font Style = [fsBold]
Рисунок 9.9. Надпись выполнена с помощью компонента Label
Шаг 10. После этого поместите в форму еще один компонент Label с текстом "Developed in Delphi" в свойстве Caption.
9.2.6. Рельефная канавка
Окно диалога почти готово, но для полного ажура не хватает одной мелочи — рельефной канавки вокруг рисунка и надписей (это придаст окну законченность). Для решения подобных задач служит компонент Bevel, расположенный в палитре компонентов на вкладке Additional.
Рисунок 9.10. Компонент Bevel
Шаг 11. Поместите в форму компонент Bevel, придайте ему нужные размеры и положение, после чего установите свойство Shape в значение bsFrame.
Рисунок 9.11. Компонент Bevel в форме
9.2.7. Рельефная панель
Рельефные канавки удобно создавать с помощью компонента Bevel. Однако компонент Bevel не может быть контейнером для других компонентов, а следовательно, перемещение рамки не вызывает перемещение компонентов, находящихся внутри нее. Если нужна не просто рамка, а контейнер с рамкой, то пользуются рельефной панелью — компонентом Panel (вкладка Standard панели инструментов).
Рисунок 9.12. Компонент Panel
Отличительные свойства компонента Panel сведены в таблицу 9.5.
Таблица 9.5. Важнейшие свойства компонента Panel
Шаг 12. Уберите компонент Bevel из формы и поместите на его место компонент Panel. Откорректируйте его положение и размеры и установите свойства следующим образом (рисунок 9.13):
Caption = <пусто>
BevelInner = bvRaised
BevelOuter = bvLowered
Рисунок 9.13. Компонент Panel заменил в форме компонент Bevel
Шаг 13. С помощью окна Object TreeView перенесите компоненты Image1, Label1 и Label2 на панель Panel1 (рисунок 9.14).
Рисунок 9.14. Компоненты Image1, Label1 и Label2 переносятся на панель Panel1
Теперь рельефная рамка заменена рельефной панелью и при ее перемещении перемещаются все надписи и рисунок (рисунок 9.15).
Рисунок 9.15. Компоненты Image1, Label1 и Label2 — теперь на панели Panel1
Будьте аккуратны при удалении панели! Вместе с ней всегда удаляются внутренние компоненты.
9.2.8. Выполнение диалога
Визуальное проектирование окна About закончено, осталось обеспечить его вызов при выборе пользователем команды Help | About... главного меню. Для этого нужно сделать следующее:
Шаг 14. Как реализовать первый пункт плана вы уже знаете, поэтому мы не будем на нем останавливаться, и сразу перейдем ко второму пункту плана. Активизируйте PictureForm, а затем выберите в меню File команду Use Unit... . На экране появится окно (рисунок 9.16):
Рисунок 9.16. С помощью окна UseUnit модуль About подключается в модуле Main
Выберите в этом окне модуль AboutUnit и щелкните на кнопке OK. Модуль AboutUnit, содержащий определение формы AboutForm, подключится в модуле MainUnit, содержащем определение главной формы PictureForm. Чтобы в этом убедиться, перейдите к редактору кода. В разделе implementation модуля MainUnit вы обнаружите строку
uses AboutUnit;
Ее можно было бы набрать и вручную, но мы решили продемонстрировать вам еще одну возможность визуальной среды программирования.
Шаг 15. Выполните теперь второй пункт плана — создайте обработчик события OnExecute для команды AboutAction компонента ActionList:
procedure TPictureForm.AboutActionExecute(Sender: TObject);
begin
AboutForm.ShowModal;
end;
Метод ShowModal запускает окно диалога в монопольном режиме и возвращает управление только после его завершения. В нашем примере метод вызывается как процедура, но в действительности это функция, которая возвращает код завершения диалога. Код берется у формы из свойства ModalResult. Напомним, что для выполнения диалога в немонопольном режиме его нужно вызвать с помощью метода Show, а не метода ShowModal.
Шаг 16. Выполните компиляцию и запустите программу, затем проверьте работу новоиспеченного окна диалога, выполнив команду меню Help | About... (рисунок 9.17).
Рисунок 9.17. Диалоговое окно в работе
Все работает правильно, остается только выяснить один вопрос: где, когда и кем конструируется объект AboutForm. Ведь никаких усилий мы для этого не предпринимали, и тем не менее использовали объект при вызове метода ShowModal как уже существующий.
Объект AboutForm создается при запуске программы и существует на протяжении всей ее работы. В этом можно убедиться, заглянув в главный файл программы с помощью команды меню View|ProjectSource. В главном программном блоке вы найдете оператор:
Application.CreateForm(TAboutForm, AboutForm);
Он-то и обеспечивает "автоматическое" создание объекта формы. Это удобно, но имеет и отрицательные стороны, так как память, выделенная объекту остается занятой даже тогда, когда форма невидима, т.е. до запуска диалога и после его завершения. Если программа имеет одну-две формы, это не так важно, а если много? В этом случае от автоматического создания всех форм, кроме главной, лучше отказаться.
Шаг 17. Чтобы исключить автоматическое создание формы AboutForm, откройте окно Project Options и на вкладке Forms отбуксируйте элемент AboutForm из списка Auto-create forms в список Available forms (рисунок 9.18):
Рисунок 9.18. Форма AboutForm исключена из списка автоматически создаваемых форм
В результате среда Delphi удалит приведенный выше оператор из главного файла программы, переложив заботу о создании формы на ваши плечи.
Шаг 18. Разумеется, что после сделанных действий метод AboutItemClick, из которого вызывается окно диалога, нужно переписать:
procedure TPictureForm.AboutActionExecute(Sender: TObject);
begin
AboutForm := TAboutForm.Create(Self);
try
AboutForm.ShowModal;
finally
AboutForm.Free;
end;
end;
Ну вот, теперь ресурс оперативной памяти используется более рационально. Кстати, обратите внимание, как обеспечивается защита объекта AboutForm от исключительных ситуаций, которые могут возникнуть в период его работы (это конечно маловероятно, но чего в этой жизни не бывает!). Если объект AboutForm успешно создается, то благодаря оператору try...finally...end он всегда корректно освобождается, даже в случае возникновения исключительной ситуации.
9.3. Компоненты для ввода данных
Вы получили первое представление об окнах диалога, научились создавать и выполнять простейшие из них. Но вы еще не знаете, как организовать диалог для получения данных от пользователя. Эта задача решается с помощью компонентов для ввода данных, к изучению которых мы сейчас приступаем.
Использование компонентов для ввода данных рассмотрим на примере приложения Alarms. Эта полезная программа позволит создать список будильников для уведомления о предстоящих событиях. По сигналу будильника в заданные время и день появится окно с сообщением и прозвучит сигнал. Список будильников будет отображаться в главном окне программы, а установка их параметров будет выполняться в модальном окне диалога. В процессе разработки этого приложения вы познакомитесь с такими компонентами, как CheckBox, RadioButton, ComboBox, ListBox, GroupBox, Edit, MaskEdit и некоторыми другими. Итак, приступим.
Шаг 1. Сначала приготовьте новый проект с пустой формой, выбрав команду меню File|NewApplication. Дайте форме идентификатор MainForm, скорректируйте ее размеры и установите следующие значения свойств:
Caption = Clock Alarms
BorderIcons = [biSystemMenu,biMinimize]
BorderStyle = bsSingle
Position = poDefaultPosOnly
Сохраните модуль формы под именем MainUnit.pas, а проект — под именем Alarms.dpr.
Шаг 2. В форме MainForm будет отображаться список будильников. Для управления списком нужны кнопки: New, Edit и Delete. Для быстрого и удобного закрытия формы нужна еще кнопка Close. Поэтому поместите в форму соответствующее число компонентов Button (с идентификаторами NewButton, EditButton, DeleteButton, CloseButton) и задайте для них надписи, размеры и положение как на рисунке 9.19.
Рисунок 9.19. Кнопки для управления списком будильников
Шаг 9. Вспомним, что компонент Label понадобился нам для того, чтобы сделать необходимые надписи в окне About. Опустите в форму первую надпись справа от изображения и установите ее свойства следующим образом:
WordWrap = True
Caption = Picture Viewer
Font Color = clNavy
Font Name = Times New Roman
Font Size = 20
Font Style = [fsBold]
Рисунок 9.9. Надпись выполнена с помощью компонента Label
Шаг 10. После этого поместите в форму еще один компонент Label с текстом "Developed in Delphi" в свойстве Caption.
9.2.6. Рельефная канавка
Окно диалога почти готово, но для полного ажура не хватает одной мелочи — рельефной канавки вокруг рисунка и надписей (это придаст окну законченность). Для решения подобных задач служит компонент Bevel, расположенный в палитре компонентов на вкладке Additional.
Рисунок 9.10. Компонент Bevel
Шаг 11. Поместите в форму компонент Bevel, придайте ему нужные размеры и положение, после чего установите свойство Shape в значение bsFrame.
Рисунок 9.11. Компонент Bevel в форме
9.2.7. Рельефная панель
Рельефные канавки удобно создавать с помощью компонента Bevel. Однако компонент Bevel не может быть контейнером для других компонентов, а следовательно, перемещение рамки не вызывает перемещение компонентов, находящихся внутри нее. Если нужна не просто рамка, а контейнер с рамкой, то пользуются рельефной панелью — компонентом Panel (вкладка Standard панели инструментов).
Рисунок 9.12. Компонент Panel
Отличительные свойства компонента Panel сведены в таблицу 9.5.
Свойство | Описание |
Align | Способ выравнивания панели в пределах владельца. |
BevelInner | Внутренний скос рельефной рамки: bvNone — скос отсутствует, bvLowered — скос внутрь, bvRaised — скос наружу; bvSpace — скос заменяется отступом. |
BevelOuter | Внешний скос рельефной рамки: bvNone — скос отсутствует, bvLowered — скос внутрь, bvRaised — скос наружу; bvSpace — скос заменяется отступом. |
BevelWidth | Ширина скосов рельефной рамки. |
BorderWidth | Расстояние в пикселях между внутренним и внешним скосами. |
BorderStyle | Определяет, имеет ли панель рамку. |
Caption | Текст на панели. |
DockSite | Определяет, используется ли панель для стыковки других компонентов. |
FullRepaint | Свойство сохранено для совместимости с предыдущими версиями библиотеки VCL. Оно не влияет на способ перерисовки компонента. |
Locked | Если равно False, то OLE-серверу разрешено заменить панель на свою панель инструментов. Если равно True и панель выравнена по какой-нибудь стороне формы, то она остается нетронутой при активизации OLE-сервера по месту. |
UseDockManager | Включает режим автоматического размещения стыкуемых компонентов на панели. Компоненты стыкуются методом деления панели по горизонтали и вертикали. Если свойство равно значению False, то программист должен сам позаботиться о размерах и местоположении стыкуемых компонентов, определив обработчики событий OnGetSiteInfo и OnDockDrop. |
OnCanResize | Происходит при попытке изменить размеры панели. Запрос на изменение размеров может исходить от пользователя. Устанавливая значение параметра Resize, обработчик события OnCanResize может разрешить или запретить действительное изменение размеров панели. |
OnConstrainedResize | Происходит при изменении размеров панели и позволяет на лету изменять ее минимальные и максимальные размеры. |
OnGetSiteInfo | Происходит, когда у компонента запрашивается место для стыковки. |
Таблица 9.5. Важнейшие свойства компонента Panel
Шаг 12. Уберите компонент Bevel из формы и поместите на его место компонент Panel. Откорректируйте его положение и размеры и установите свойства следующим образом (рисунок 9.13):
Caption = <пусто>
BevelInner = bvRaised
BevelOuter = bvLowered
Рисунок 9.13. Компонент Panel заменил в форме компонент Bevel
Шаг 13. С помощью окна Object TreeView перенесите компоненты Image1, Label1 и Label2 на панель Panel1 (рисунок 9.14).
Рисунок 9.14. Компоненты Image1, Label1 и Label2 переносятся на панель Panel1
Теперь рельефная рамка заменена рельефной панелью и при ее перемещении перемещаются все надписи и рисунок (рисунок 9.15).
Рисунок 9.15. Компоненты Image1, Label1 и Label2 — теперь на панели Panel1
Будьте аккуратны при удалении панели! Вместе с ней всегда удаляются внутренние компоненты.
9.2.8. Выполнение диалога
Визуальное проектирование окна About закончено, осталось обеспечить его вызов при выборе пользователем команды Help | About... главного меню. Для этого нужно сделать следующее:
-
создать команду AboutAction в компоненте ActionList и связать ее с пунктом меню About...; -
в модуле MainUnit подключить модуль AboutUnit. Это обеспечит доступ к форме AboutForm из главной формы PictureForm; -
создать обработчик события OnExecute команды AboutAction и обеспечить в нем монопольное выполнение диалога.
Шаг 14. Как реализовать первый пункт плана вы уже знаете, поэтому мы не будем на нем останавливаться, и сразу перейдем ко второму пункту плана. Активизируйте PictureForm, а затем выберите в меню File команду Use Unit... . На экране появится окно (рисунок 9.16):
Рисунок 9.16. С помощью окна UseUnit модуль About подключается в модуле Main
Выберите в этом окне модуль AboutUnit и щелкните на кнопке OK. Модуль AboutUnit, содержащий определение формы AboutForm, подключится в модуле MainUnit, содержащем определение главной формы PictureForm. Чтобы в этом убедиться, перейдите к редактору кода. В разделе implementation модуля MainUnit вы обнаружите строку
uses AboutUnit;
Ее можно было бы набрать и вручную, но мы решили продемонстрировать вам еще одну возможность визуальной среды программирования.
Шаг 15. Выполните теперь второй пункт плана — создайте обработчик события OnExecute для команды AboutAction компонента ActionList:
procedure TPictureForm.AboutActionExecute(Sender: TObject);
begin
AboutForm.ShowModal;
end;
Метод ShowModal запускает окно диалога в монопольном режиме и возвращает управление только после его завершения. В нашем примере метод вызывается как процедура, но в действительности это функция, которая возвращает код завершения диалога. Код берется у формы из свойства ModalResult. Напомним, что для выполнения диалога в немонопольном режиме его нужно вызвать с помощью метода Show, а не метода ShowModal.
Шаг 16. Выполните компиляцию и запустите программу, затем проверьте работу новоиспеченного окна диалога, выполнив команду меню Help | About... (рисунок 9.17).
Рисунок 9.17. Диалоговое окно в работе
Все работает правильно, остается только выяснить один вопрос: где, когда и кем конструируется объект AboutForm. Ведь никаких усилий мы для этого не предпринимали, и тем не менее использовали объект при вызове метода ShowModal как уже существующий.
Объект AboutForm создается при запуске программы и существует на протяжении всей ее работы. В этом можно убедиться, заглянув в главный файл программы с помощью команды меню View|ProjectSource. В главном программном блоке вы найдете оператор:
Application.CreateForm(TAboutForm, AboutForm);
Он-то и обеспечивает "автоматическое" создание объекта формы. Это удобно, но имеет и отрицательные стороны, так как память, выделенная объекту остается занятой даже тогда, когда форма невидима, т.е. до запуска диалога и после его завершения. Если программа имеет одну-две формы, это не так важно, а если много? В этом случае от автоматического создания всех форм, кроме главной, лучше отказаться.
Шаг 17. Чтобы исключить автоматическое создание формы AboutForm, откройте окно Project Options и на вкладке Forms отбуксируйте элемент AboutForm из списка Auto-create forms в список Available forms (рисунок 9.18):
Рисунок 9.18. Форма AboutForm исключена из списка автоматически создаваемых форм
В результате среда Delphi удалит приведенный выше оператор из главного файла программы, переложив заботу о создании формы на ваши плечи.
Шаг 18. Разумеется, что после сделанных действий метод AboutItemClick, из которого вызывается окно диалога, нужно переписать:
procedure TPictureForm.AboutActionExecute(Sender: TObject);
begin
AboutForm := TAboutForm.Create(Self);
try
AboutForm.ShowModal;
finally
AboutForm.Free;
end;
end;
Ну вот, теперь ресурс оперативной памяти используется более рационально. Кстати, обратите внимание, как обеспечивается защита объекта AboutForm от исключительных ситуаций, которые могут возникнуть в период его работы (это конечно маловероятно, но чего в этой жизни не бывает!). Если объект AboutForm успешно создается, то благодаря оператору try...finally...end он всегда корректно освобождается, даже в случае возникновения исключительной ситуации.
9.3. Компоненты для ввода данных
Вы получили первое представление об окнах диалога, научились создавать и выполнять простейшие из них. Но вы еще не знаете, как организовать диалог для получения данных от пользователя. Эта задача решается с помощью компонентов для ввода данных, к изучению которых мы сейчас приступаем.
Использование компонентов для ввода данных рассмотрим на примере приложения Alarms. Эта полезная программа позволит создать список будильников для уведомления о предстоящих событиях. По сигналу будильника в заданные время и день появится окно с сообщением и прозвучит сигнал. Список будильников будет отображаться в главном окне программы, а установка их параметров будет выполняться в модальном окне диалога. В процессе разработки этого приложения вы познакомитесь с такими компонентами, как CheckBox, RadioButton, ComboBox, ListBox, GroupBox, Edit, MaskEdit и некоторыми другими. Итак, приступим.
Шаг 1. Сначала приготовьте новый проект с пустой формой, выбрав команду меню File|NewApplication. Дайте форме идентификатор MainForm, скорректируйте ее размеры и установите следующие значения свойств:
Caption = Clock Alarms
BorderIcons = [biSystemMenu,biMinimize]
BorderStyle = bsSingle
Position = poDefaultPosOnly
Сохраните модуль формы под именем MainUnit.pas, а проект — под именем Alarms.dpr.
Шаг 2. В форме MainForm будет отображаться список будильников. Для управления списком нужны кнопки: New, Edit и Delete. Для быстрого и удобного закрытия формы нужна еще кнопка Close. Поэтому поместите в форму соответствующее число компонентов Button (с идентификаторами NewButton, EditButton, DeleteButton, CloseButton) и задайте для них надписи, размеры и положение как на рисунке 9.19.
Рисунок 9.19. Кнопки для управления списком будильников