Вперед.    Содержание.

Вce мы любим иногда поболтать. Это человеческое свойство передалось программам и они частенько у вас что-то спрашивают, а вы им что-то отвечаете, иногда невпопад. "Беседа", правда, идет текстом, а не голосом. Так вот, разговор между программой и пользователем называется диалогом. Организация диалога - важнейшая часть любой программы и ваша прямая обязанность. Внешне диалог прост - появляется окно с некоторым сообщением, полем для ввода вашего ответа и кнопкой ОК. Вы внимательно читаете сообщение, набираете строку-ответ и нажимаете ОК. Вот и все. Создатели Delphi предусмотрели все возможные типы диалогов и дали вам ряд великолепных "домашних заготовок" на все случаи жизни.

ПОНЯТИЕ ОКНА ДИАЛОГА

В основе диалога лежит окно диалога (dialog box) - вспомогательное окно фиксированного размера, содержащее различные управляющие элементы (controls): кнопки, строки редактирования, независимые и зависимые переключатели, списки и т. д. С помощью управляющих элементов пользователь просматривает и вводит данные, а также управляет диалогом. В среде Delphi окно диалога создается на основе обычной формы.

Окна диалога могут работать в одном из двух режимов, модальном (modal) и немодальном (modeless).

Модальные окна диалога служат для взаимодействия с пользователем в режиме неделимого действия. Они не позволяют переключаться на другие окна своего приложения до тех пор, пока работа с ними не будет завершена (однако это не мешает вам переключаться на другие приложения, например с помощью кнопок на Панели Задач Windows или нажатием комбинации клавиш Alt+ Tab). В модальном режиме выполняется большинство всех окон диалога.

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

ОКНО "ABOUT"

Простейшим примером окна диалога является окно About ("О программе"). Оно открывается по команде меню Help/About..., выполняется в модальном режиме и служит чисто информационным целям (данные в нем не вводятся). В предыдущей главе мы рассматривали программу PICVIEW, там как раз недостает окна About. Давайте исправим это упущение и практически познакомимся с созданием простейших окон диалога.

Шаг 1. Запустите Delphi и откройте проект PICVIEW. Добавьте в строку главного меню выпадающее меню Help (программный идентификатор Helpitem) с командой About... (программный идентификатор Aboutltem). По команде About... будет вызываться окно диалога About, которое мы дальше разработаем.

Шаг 2. Добавьте в проект новую форму, переименуйте ее в AboutForm и сохраните модуль под именем About. pas. Придайте форме нужные размеры и установите ее заголовок (свойство Caption) в значение About Picture Viewer. Сделаем теперь из этой формы окно диалога.

Шаг 3. По умолчанию форма имеет много "фитюлек", которые совсем не нужны окну диалога, например раздвижную границу, меню управления окном, кнопки сворачивания и разворачивания окна. Чтобы их убрать, установите свойство BorderStyle в значении bdDialog.

Результат сделанного изменения проявится только во время работы и будет выражаться в следующем:

• у формы будет нераздвижная граница;

• у формы не будет кнопок сворачивания и разворачивания;

• в управляющем меню будут лишь два пункта: Move и Close.

Шаг 4. Большинство модальных окон диалога появляются в центре экрана. За это отвечает свойство формы Position. По умолчанию оно равно poDesigned - форма появляется точно в том же месте, где она видна во время разработки. Чтобы сцентрировать форму на экране, установите свойство Position в значение poScreenCenter.

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

КНОПКИ

Разрабатывая окно диалога, прежде всего необходимо обеспечить для пользователя стандартный путь завершения его работы. Вот тут как раз и нужны кнопки (buttons). В простейшем окне диалога, каким является окно About, достаточно всего одной кнопки (она обычно называется ОК или Close). В более сложных окнах может понадобиться несколько кнопок. Например, в том случае, когда окно диалога принимает от пользователя данные, в него помещают кнопки ОК и Cancel, которые позволяют пользователю решить, нужно ли обрабатывать данные после завершения диалога.

Стандартная командная кнопка создается с помощью компонента Button, расположенного в Палитре Компонентов на странице Standard (рис. 7. 3).

Характерные свойства этого компонента кратко описаны в табл.:

Свойство

Описание

Cancel

Если равно True, то кнопка срабатывает при нажатии клавиши <Esc>.

Caption

Текст на кнопке.

Default

Если равно True, то кнопка срабатывает при нажатии клавиши <Enter>.

ModalResult

Установка в этом свойстве ненулевого значения обеспечивает завершение модального окна диалога при нажатии кнопки.

Компонент Button создает иллюзию нажимающейся кнопки с текстовой надписью. Текст на кнопке определяется значением свойства Caption. В тексте может повстречаться символ &, который не отображается на кнопке, но обеспечивает подчеркивание следующего за ним символа. Подчеркнутый символ используется в комбинации с клавишей Alt для активизации кнопки с клавиатуры. Например, если Caption содержит строку &Yes, то на кнопке написано Yes и для нажатия кнопки можно воспользоваться комбинацией клавиш Alt+ Y.

Пользователи, привыкшие работать с клавиатурой, знают, что одна из кнопок в окне диалога срабатывает при нажатии клавиши Enter. Это так называемая кнопка ввода, она обычно называется ОК. Внешне кнопка ввода отличается от остальных кнопок наличием черной рамки. Чтобы сделать кнопку кнопкой ввода, установите в ней свойство Default в True.

Кроме кнопки ввода модальное окно диалога часто имеет так называемую кнопку отмены. Она срабатывает при нажатии клавиши Esc и обычно называется Отмена (Cancel). Чтобы сделать кнопку кнопкой отмены, установите в ней свойство Cancel в True.

Когда пользователь нажимает кнопку с помощью мыши или клавиатуры, в компоненте Button возникает событие OnClick. Определив для него обработчик, вы можете реализовать ответную реакцию, которая для модальных окон диалога обычно заключается в завершении диалога с определенным признаком возврата.

Завершение модального окна диалога выполняется установкой ненулевого значения в свойстве формы ModalResult (оно доступно только из программы). Анализируя это свойство после завершения диалога, программа узнает, какую кнопку нажал пользователь и в соответствии с этим направляет вычисления в нужное русло.

Легко сообразить, что для завершения модального окна диалога достаточно определить в кнопке обработчик события OnClick и в нем присвоить какое-нибудь значение свойству формы ModalResult. Впрочем, без этого можно обойтись, если воспользоваться свойством ModalResult компонента Button (мы не ошиблись, это свойство имеет и форма, и кнопка). Свойство ModalResult компонента Button устанавливается в Инспекторе Объектов и по умолчанию равно mrNone (0). Если вы выберете другое значение, то нажатие кнопки будет вызывать автоматическое завершение окна диалога с переписыванием этого значения в свойство ModalResult формы.

Шаг 5. Перейдем теперь от теории к практике и создадим в нашем окне About кнопку ОК. Для этого выберите в Палитре Компонентов компонент Button, опустите его на форму и установите его свойства в следующие значения:

Cancel = True; Caption = OK; Default = True; ModalResult = mrOk

КНОПКИ С КАРТИНКАМИ

Каждый из нас в душе художник. Поэтому рано или поздно стандартные невзрачные кнопки, содержащие лишь "голый" текст, перестанут вам нравиться. Появится естественное желание их как-то приукрасить. В этом случае мы советуем вам вместо компонента Button воспользоваться компонентом BitBtn. Он расположен в Палитре Компонентов на странице Additional (рис. 7. 5).

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

Свойство

Описание

Glyph

Картинка на кнопке.

NumGlyphs

Количество образов кнопки на картинке. Delphi рисует один из образов в зависимости от состояния кнопки.

Layout

Положение картинки относительно текста.

Margin

Расстояние от границы кнопки до картинки. Если равно -1, то картинка вместе текстом центрируются на кнопке.

Spacing

Расстояние от картинки до текста. Если равно -1, то текст центрируется между картинкой и границей кнопки.

King

Задает кнопку стандартного вида (Ok, Cancel и др.).

Нетрудно заметить, что компонент BitBtn имеет много общего с уже знакомым по предыдущей главе компонентом SpeedButton. Поэтому мы удержимся от повторного изложения того, как установить и расположить картинку на кнопке. Заметим только, что кнопка принимает наиболее красивый вид, если свойство Margin равно 4, а свойство Spacing равно 1.

С помощью компонента BitBtn стандартные кнопки OK, Cancel, Yes, No, Close, Abort, Retry, Ignore, All и Help создаются проще, чем при использовании компонента Button. Для этого в свойстве Kind достаточно установить соответствующее значение (см. табл. 7. 3).

Например, если вам нужна кнопка ОК, установите свойство Kind в bkOK. В результате на кнопке появится зеленая "галочка" и текст ОК, свойство Default получит значение True (кнопка ввода) и свойство ModalResult получит значение mrOK (щелчок по кнопке закрывает окно диалога).

УКРАШЕНИЕ ОКНА ДИАЛОГА КАРТИНКОЙ

Хорошее приложение должно быть не только функционально, но и эстетично. Как говорится, хорошее блюдо должно быть красиво подано. Это относится и к нашему замечательному приложению, и, конечно, к его окну About. А что может лучше украсить окно About, чем яркая, запоминающаяся картинка?

Шаг 6. Как вы уже знаете, картинка создается с помощью компонента Image, расположенного в Палитре Компонентов на странице Additional. Выберите этот компонент и опустите на форму AboutForm.

Чтобы установить изображение, активизируйте в Инспекторе Объектов свойство Picture и щелчком на кнопке с многоточием откройте Редактор Картинки.

Шаг 7. В этом окне задается значение свойства Picture. Вы можете загрузить в него точечный рисунок (bitmap), метафайл (metafile), расширенный метафайл (enhanced metafile) или значок (icon). Загрузите файл Athena. bmp, находящийся по маршруту Delphi 2. 0\Images\Splash\16color и щелкните по кнопке ОК. Картинка установлена и отображена (рис. 7. 8).

ТЕКСТОВЫЕ НАДПИСИ

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

Следуя традиции, напишем название приложения большими жирными буквами, а средства разработки - обычным мелким шрифтом. Для этого воспользуемся компонентом Label, который находится в Палитре Компонентов на странице Standard (рис. 7. 9).

Характерные свойства компонента Label кратко описаны в табл.:

Свойство

Описание

Align

Способ выравнивания компонента в пределах владельца.

Alignment

Расположение текста в пределах компонента.

AutoSize

Если равно True, то размеры компонента автоматически подгоняются по ширине и высоте текста.

Caption

Текст надписи.

Transparent

Если равно True, то фон надписи является прозрачным.

WordWrap

Если равно True, то работает перенос слов.

Компонент Label отображает нередактируемый текст, заданный в свойстве Caption. Текст выравнивается в пределах управляющего элемента одним из трех способов: по левому краю, по правому краю или по центру. Способ выравнивания определяется свойством Alignment. Если текст надписи слишком велик, можно организовать его вывод в несколько строк с переносом слов. Для этого достаточно установить свойство Wordwrap в True. Еще одна удобная возможность - автоматическая подгонка размеров управляющего элемента по ширине и высоте текста. Она контролируется свойством AutoSize и по умолчанию включена.

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

С помощью надписи часто создаются подсказки к другим управляющим элементам, в частности к строкам редактора. При этом свойство Caption надписи содержит не только текст, но и акселераторную клавишу, при выборе которой активизируется связанный с надписью управляющий элемент. Активизируемый управляющий элемент устанавливается в свойстве FocusControl.

Шаг 8. Вспомним, что компонент Label понадобился нам для того, чтобы сделать необходимые надписи в блоке About. Опустите на форму первую надпись справа от изображения и установите ее свойства следующим образом (рис. 7. 10):

Wordwrap = True; Caption = Picture Viewer; Font Color = cINavy; Font Name = Times New Roman; Font Size = 26; Font Style = [fsBold]

Шаг 9. После этого поместите на форму еще один компонент Label с текстом Developed in Delphi 2. 0 в значении свойства Caption.

 

РЕЛЬЕФНЫЕ КАНАВКИ И БОРДЮРЫ

Окно диалога почти готово, но для полного ажура не хватает одной мелочи - рельефной канавки вокруг картинки и надписей (это придаст окну законченность). Для решения подобных задач служит компонент Bevel, расположенный в Палитре Компонентов на странице Additional (рис. 7. 11).

Шаг 10. Поместите на форму компонент Bevel, придайте ему нужные размеры и положение и установите свойство Shape в значение bsFrame (рис. 7. 12).

ВЫПОЛНЕНИЕ ДИАЛОГА

Визуальное проектирование окна About закончено, осталось обеспечить его вызов при выборе пользователем команды меню Help | About.... Для этого нужно сделать следующее:

• в модуле Main подключить модуль About; это обеспечит видимость формы AboutForm в главной форме PictureForm;

• определить для команды меню About... обработчик события OnClick и обеспечить модальное выполнение диалога.

Шаг 11. Сначала реализуем первый пункт плана. Активизируйте PictureForm, а затем  выберите в меню File команду Use Unit.... На экране появится окно (рис. 7. 13):

Выберите в этом окне модуль About и щелкните на кнопке ОК. Модуль About, содержащий определение формы AboutForm, подключится в модуле Main, содержащем определение главной формы PictureForm. Чтобы в этом убедиться, перенеситесь в Редактор Кода. В разделе implementation модуля Main вы обнаружите строку

uses About;

Ее можно было бы набрать и вручную, но мы решили продемонстрировать вам еще одну возможность визуальной среды программирования.

Шаг 12. Выполните теперь второй пункт плана, определив следующий обработчик события OnClick для команды меню About...:

procedure TPictureForm. AboutItemClick (Sender: TObject);

begin

AboutForm. ShowModal;

end;

Метод ShowModal запускает окно диалога в модальном режиме и возвращает управление только после его завершения. В нашем примере метод вызывается как процедура, но в действительности это функция, которая возвращает значение свойства формы ModalResult. Добавим, что для" немодального выполнения диалога вместо метода ShowModal используется метод Show.

Шаг 13. Скомпилируйте и запустите приложение, затем проверьте работу новоиспеченного окна диалога, выполнив команду меню Help | About... (рис. 7. 14).

Все работает правильно, остается только выяснить один вопрос: где и когда конструируется объект AboutForm. Ведь никаких усилий мы для этого не предпринимали, а использовали объект при вызове метода ShowModal как уже существующий.

Объект AboutForm создается сразу после старта приложения и существует на протяжении всей его работы. В этом можно убедиться, заглянув в файл проекта, открываемый в Редакторе Кода после выбора команды меню View | Project Source. В главном программном блоке вы найдете оператор:

Application. CreateForm (TAboutForm, AboutForm);

Он-то и обеспечивает "автоматическое" создание объекта формы. Это удобно, но имеет и отрицательные стороны, так как память, выделенная объекту, остается занятой даже тогда, когда форма невидима, т. е. до запуска диалога и после его завершения. Если приложение имеет одну-две формы, это не так важно, а если много? В этом случае от автоматического создания всех форм кроме главной лучше отказаться.

Шаг 14. Чтобы исключить автоматическое создание формы AboutForm, откройте окно Project Options и на странице Forms отбуксируйте элемент AboutForm из списка Auto-create forms в список Available forms (рис. 7. 15):

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

Шаг 15. Разумеется, что после сделанных действий метод AboutltemClick, из которого вызывается окно диалога, нужно переписать:

procedure TPictureForm. AboutItemClick (Sender: TObject);

begin

AboutForm: = TAboutForm. Create (Self);

try

AboutForm. ShowModal;

finally

AboutForm. Free;

end;

end;

Ну вот, теперь ресурс оперативной памяти используется более рационально. Кстати, обратите внимание, как обеспечивается защита объекта AboutForm от исключительных ситуаций, которые могут возникнуть в период его работы (это, конечно, мало вероятно, но чего в этой жизни не бывает). Если объект AboutForm успешно создается, то благодаря оператору try... finally... end он всегда корректно освобождается, даже в случае исключительной ситуации.

Вперед.    Содержание.