Свойства и характеристики формы (Form) в Дельфи (Delphi). Delphi. Общие свойства компонентов

Еремин Андрей

Что такое свойства? Что является свойствами в реальной жизни? Например, в физике это температура плавления, температура кипения, вязкость, плотность, растворимость и т.д. Аналогично и объектно-ориентированном программировании. Каждый объект имеет какие-либо свойства. Свойства отвечают либо за внешний вид объекта, либо за его поведение в программе во время её выполнения. Рассмотрим свойства в Delphi .

Где найти свойства

Каждый компонент, помещённый на форму, имеет своё отражение в Инспекторе объектов (Object Inspector). Попробуйте, к примеру, поместить на форму кнопку TButton и текстовое поле TEdit и выделить по очереди сначала один объект, а затем другой, наблюдая при этом за Инспектором объектов. Вы заметите, что содержимое его окна изменяется. Это связано с тем, что каждый объект имеет свои свойства. Свойство может быть у одного объекта, но его может не быть у другого. Например, у поля ввода (TEdit) есть свойство ReadOnly , отвечающее за возможность изменения текста в этом поле. Совершенно логично, что у кнопки (TButton) этого свойства нет и быть не может.

Как создаются программы

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

Типы свойств

Прежде чем перейти к рассмотрению типов свойств, нужно понять, что же из себя вообще представляет свойство? Всё очень просто. Свойство - это поле какой-либо структуры, содержащее определённое значение. Отталкиваясь от того, каким образом задаются эти значения и какую "природу", т.е. структуру имеет свойство, выделено несколько типов свойств.

Простыми являются те свойства, значения которых являются числами, либо строками (текстом). Примерами таких свойств могут служить Left и Top формы. Эти свойства определяют положение формы на экране (в частности, её левого верхнего угла). Значения этих свойств - числа. Пример свойства со значением-строкой - Caption формы. Это свойство хранит заголовок формы и задаётся в виде обычного текста.

2. Перечислимые свойства. Такими являются свойства, задать значения которым в явном виде нельзя, а можно только выбрать из списка. Список возможных значений определяется заранее. Пример такого свойства - свойство AutoSize формы. Оно отвечает за то, будет ли форма автоматически изменять свой размер, чтобы отобразить все размещённые на ней компоненты. Значение - либо истина (True), либо ложь (False). Другой пример - свойство BorderStyle . Это свойство отвечает за внешний вид формы, а также за поведение её границ, т.е. можно ли изменять размеры формы во время работы программы. Это свойство принимает одно из 6 значений.

3. Вложенные свойства. Это те свойства, которые имеют внутри несколько других свойств. В Инспекторе объектов слева от названий таких свойств отображается маленькая кнопка со знаком "+ ", нажатие на которую раскрывает данное свойство (знак при этом меняется на "- "). Повторный щелчок "сворачивает" свойство обратно. Вложенные свойства бывают двух основных типов - это множества и комбинированные значения. Множества - это набор каких-либо значений, каждое из которых либо "включено", либо "выключено". Комбинированные значения - это набор из нескольких свойств, которые могут иметь разный тип данных. Примером множества является свойство BorderIcons у формы - оно отвечает за кнопки, которые будут показаны в строке заголовка окна. Понятно, что любая из кнопок может либо отображаться на экране, либо нет - такой набор очень удобно задавать с помощью множества. Примером комбинированного значения является свойство Font (оно есть у большинства визуальных компонентов) - задаёт шрифт для элемента. В его включено несколько других свойств - название шрифта, цвет, стиль, размер и т.п.

Управление свойствами

Управлять свойствами, т.е. изменять их значения можно двумя способами - в режиме проектирования программы (Design-time) и во время выполнения (Run-time). В данный момент нас интересует режим проектирования. Изменять свойства можно всё в том же Инспекторе объектов. Если это простое свойство, то достаточно щёлкнуть по строке с названием этого свойства и ввести новое значение. Если это перечислимое свойство, то значение можно выбрать из списка. Некоторые свойства (например, Left , Top , Width и Height) можно изменять простыми операциями перетаскивания и изменением размеров с помощью мыши.
Примечание: Left , Top - положение формы на экране, Width - ширина, Height - высота формы.

Следует отметить, что в режиме проектирования через Инспектор объектов могут быть доступны не все свойства выбранного компонента. Эти свойства доступны в режиме выполнения и изменяются они программным путём.

Немного о компонентах

Чтобы у Вас не возникало путаниц и непонятных моментов, считаю необходимым сделать следующее уточнение. Все компоненты подразделяются на визуальные и невизуальные. Во время проектирования (Design-time) видны все компоненты без исключения. А вот во время выполнения (Run-time) - не все. Те, которые представляют собой какой-то видимый объект (поле, кнопка, таблица и т.д.) и являются визуальными. Невизуальные компоненты на экране не видны, но при этом используются в самой программе. В качестве примера невизуального компонента можно привести TApplicationEvents со вкладки Additional . Во время проектирования этот компонент присутствует на форме и он доступен через Инспектор объектов, но во время работы программы его не видно. За видимость объекта на экране в большинстве случаев отвечает свойство Visible (True - видимый, False - невидимый).

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


Поделитесь работой в социальных сетях

Если эта работа Вам не подошла внизу страницы есть список похожих работ. Так же Вы можете воспользоваться кнопкой поиск


Лекция-8 (2 часа)

Тема: Свойства в Delphi

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

Существует несколько типов свойств, в зависимости от их “природы”, т.е. внутреннего устройства.

Рис. 1: Отображение комбинированных значений вложенных свойств

  • Простые свойства - это те, значения которых являются числами или строками. Например, свойства Left и Top принимают целые значения, определяющие положение левого верхнего угла компонента или формы. Свойства Caption и Name представляют собой строки и определяют заголовок и имя компонента или формы.
  • Перечислимые свойства - это те, которые могут принимать значения из предопределенного набора (списка). Простейший пример - это свойство типа Boolean , которое может принимать значения True или False .
  • Вложенные свойства - это те, которые поддерживают вложенные значения (или объекты). Object Inspector изображает знак “+” слева от названия таких свойств. Имеется два вида таких свойств: множества и комбинированные значения . Object Inspector изображает множества в квадратных скобках. Если множество пусто, оно отображается как . Установки для вложенных свойств вида “множество” обычно имеют значения типа Boolean . Наиболее распространенным примером такого свойства является свойство Style с вложенным множеством булевых значений. Комбинированные значения отображаются в Инспекторе Объектов как коллекция некоторых величин, каждый со своим типом данных (рис 1). Некоторые свойства, например, Font , для изменения своих значений имеют возможность вызвать диалоговое окно. Для этого достаточно щелкнуть маленькую кнопку с тремя точками в правой части строки Инспектора Объектов, показывающей данное свойство.

Delphi позволяет легко манипулировать свойствами компонент как в режиме проектирования (design time), так и в режиме выполнения программы (run time).

В режиме проектирования манипулирование свойствами осуществляется с помощью Дизайнера Форм (Forms Designer) или, как Вы уже видели, на страничке “Properties” Инспектора Объектов. Например, для того чтобы изменить свойства Height (высоту) и Width (ширину) кнопки, достаточно “зацепить” мышкой за любой ее угол и раздвинуть до нужного представления. Того же результата можно добиться, просто подставив новые значения свойств Height и Width в окне Object Inspector. Рис. 2: Изменение размеров с помощью Дизайнера Форм

С другой стороны, в режиме выполнения пользователь (программист) имеет возможность не только манипулировать всеми свойствами, отображаемыми в Инспекторе Объектов, но и управлять более обширным их списком. В следующем разделе мы рассмотрим, как это делается.

Управление свойствами визуальных компонент в режиме выполнения

Все изменения значений свойств компонент в режиме выполнения должны осуществляться путем прямой записи строк кода на языке Паскаль. В режиме выполнения невозможно использовать Object Inspector. Однако, доступ к свойствам компонентов довольно легко получить программным путем. Все, что Вы должны сделать для изменения какого-либо свойства - это написать простую строчку кода аналогично следующей:

MyComponent . Width := 35;

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

Таким образом, нет ничего магического в Инспекторе Объектов. Object Inspector просто является удобным способом

Рис. 3: Изменение размеров с помощью Инспектора Объектов

выполнения в режиме проектирования того, что может быть осуществлено программным путем в режиме выполнения. Более того, как уже было сказано выше, у компонента могут быть свойства, не отображаемые в окне Инспектора Объектов.

Объектно-ориентированный язык Паскаль, лежащий в основе Delphi, в качестве базового имеет принцип соответствия визуальных компонент тем вещам, которые они представляют. Разработчики Delphi поставили перед собой цель, чтобы, например, представление компонента Button (кнопка), инкапсулирующее некий код, соответствовало визуальному изображению кнопки на экране и являлось как можно более близким эквивалентом реальной кнопки, которую Вы можете найти на клавиатуре. И именно из этого принципа родилось понятие свойства.

Если Вы измените свойства Width и Height компонента Button , кнопка соответствующим образом изменит свои ширину и высоту. Вам нет необходимости после изменения свойства Width указывать объекту, чтобы он перерисовал себя, хотя при обычном программировании именно так Вы и должны поступать. Свойства - это более чем просто данные. Напротив, они делают эти данные “живыми”, и все это происходит перед Вашими глазами! Свойства дают Вам иллюзию, как будто Вы имеете дело с реальными объектами, а не с их программным представлением.

Программа SHAPEDEM.DPR, изображенная на рис. 4, демонстрирует различные способы, с помощью которых можно изменять пользовательский интерфейс при выполнении программы. Эта программа не производит никаких полезных действий кроме демонстрации того, как легко можно создать “дельфийское” приложение с настраиваемым интерфейсом.

Программа SHAPEDEM содержит всего лишь объект TShape , размещенный на форме, вместе с двумя полосами прокрутки и несколькими кнопками. Эта программа интересна тем, что позволяет в режиме выполнения изменять размер, цвет и внешний вид объекта TShape , равно как размер и цвет самой формы.

Листинг А показывает код программы SHAPEDEM. Код головного модуля этой программы мы приведем по частям - по мере его написания.

Листинг А: Исходный код программы SHAPEDEM.DPR.

program Shapedem;

uses

Forms,

Mina in "MAIN.PAS" {Form1} ;

begin

Application.CreateForm(TForm1, Form1);

Application . Run ; Рис. 4: Программа SHAPEDEM

end . имеет 2 полосы прокрутки и несколько кнопок

В нашем примере полосы прокрутки (ScrollBars) используются для изменения размера фигуры, изображенной в средней части экрана, как показано на рис.5. Для выбора нового вида фигуры используйте выпадающий список (ComboBox), а для изменения цвета фигуры или окна (формы) используйте стандартное диалоговое окно выбора цвета, вызываемое кнопками “ Цвет фигуры ” и “ Цвет формы ”.

Что нужно сделать пользователю (программисту) для того чтобы получить

Рис. 5: Вы можете использовать полосы прокрутки, кнопки и список для изменения внешнего вида приложения

возможность “в режиме выполнения” изменять цвет какого-либо элемента или всего окна (формы)? Для этого достаточно выполнить всего лишь несколько действий. Убедитесь сами. Для изменения цвета окна просто выберите компонент ColorDialog из палитры компонентов (она находится на страничке “Dialogs”) и поместите его на форму. Кроме того, поместите на форму обычную кнопку (компонент Button , находится на страничке “Standard”). Для удобства чтения с помощью Object Inspector измените имя компонента (свойство Name ) с “Button1” (которое дается по умолчанию) на “FormColor”, а его заголовок (свойство Caption ) - на “Цвет формы”. Дважды щелкните по кнопке “Цвет формы” - Delphi сгенерирует заготовку метода, который выглядит следующим образом:

procedure

begin

end ;

Теперь введите две простые строчки кода:

procedure TForm1.FormColorClick(Sender: TObject);

begin

Form1.Color:= ColorDialog1.Color;

end ;

Данный код во время выполнения при нажатии кнопки “Цвет формы” вызывает стандартное диалоговое окно выбора цвета, как показано на рис.6.Если в этом диалоговом окне Вы щелкните кнопку OK, выполнится следующая строка:

Form 1. Color := ColorDialog 1. Color ;

Этот код установит свойство Color формы Form 1 в цвет, который был выбран с помощью диалогового окна ColorDialog 1 . Это очень просто!!!

Та же самая техника может использоваться для изменения цвета фигуры (компонент Shape , объект TShape). Все, что Вам нужно сделать - это поместить на форму другую кнопку, изменить (при желании) ее имя на “ShapeColor”, а заголовок - на “Цвет Фигуры”, дважды щелкнуть по ней мышкой и создать метод аналогичный следующему:

procedure TForm1.ShapeColorClick(Sender: TObject);

begin

if ColorDialog1.Execute then

Shape1.Brush.Color:= ColorDialog1.Color;

end ;

Что может быть проще?!!

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

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

Весь механизм Windows-сообщений, используемый при взаимодействии компонент во время выполнения, оказывается скрытым от программиста, делая процесс создания программ наиболее легким. Сложное программирование в среде Windows становится доступным “широким” массам программистов. Например, программирование изменения размера фигуры с помощью полос прокрутки, требовавшее в “чистом” Windows сложной обработки сообщений в конструкции типа “case”, в Delphi сводится к написанию одной-единственной строчки кода.

Для начала, поместите два компонента ScrollBar на форму (находится на страничке “Standard”) и установите свойство Kind первого компонента в sbHorizontal , а второго - в sbVertical . Переключитесь на страничку “Events” в Инспекторе Объектов и создайте заготовки метода для отклика на событие OnChange для каждой полосы прокрутки. Напишите в каждом из методов по одной строчке следующим образом:

procedure TForm1.ScrollBar1Change(Sender: TObject);

begin

Shape1.Width:= ScrollBar1.Position * 3;

end ;

procedure TForm1.ScrollBar2Change(Sender: TObject);

begin

Shape1.Height:= ScrollBar2.Position * 2;

end ;

Код, показанный здесь, устанавливает свойства Width и Height фигуры TShape в соответствие с положением “бегунка” на полосах прокрутки (сомножители 3 и 2 введены только для лучшего представления).

Последняя часть программы SHAPEDEM демонстрирует большие возможности языка Object Pascal, на основе которого построен Delphi. Вы можете ввести элементы в список компонента ComboBox как в режиме проектирования, так и при выполнении программы. При этом в режиме проектирования Вы можете просто ввести нужные элементы в список Items , щелкнув маленькую кнопку с тремя точками в правой части строки Инспектора Объектов, показывающей данное свойство (Items ).

Рис. 7: Текстовый редактор для ввода строк

Перед Вами появится диалоговое окно текстового редактора (String List Editor), в котором Вы и введете элементы (рис.7). Вы могли заметить, что список этих элементов совпадает со списком опций свойства Shape компонента Shape1 (Shape ). Другими словами, если Вы выделите компонент Shape1 на форме (просто щелкнув по нему) и посмотрите свойство Shape в Инспекторе Объектов, Вы увидите список возможных видов фигур, которые может принимать данный компонент. Это как раз те самые виды фигур, которые мы перечисляли в списке у компонента ComboBox1. Этот список Вы можете найти в on-line справочнике по Delphi по контексту “TShapeType”. Или же, если Вы заглянете в исходный код класса TShape , там увидите те же элементы, формирующие перечислимый тип TShapeType:

TShapeType = (stRectangle, stSquare, stRoundRect,

StRoundSquare, stEllipse, stCircle);

Итак, смысл всего сказанного в том, что за всеми объектами, которые Вы видите в “дельфийской” программе, стоит некий код на Паскале, к которому Вы имеете доступ при “прямом” программировании. Ничто не скрыто от Вас. Это значит, что Вы можете изменить поведение любой части Вашей программы во время выполнения путем написания соответствующего кода.

В нашем конкретном случае, Вам нужно написать только одну строчку кода, которая будет выполнена в качестве отклика на щелчок пользователем по выпадающему списку ComboBox1. Чтобы написать код этого отклика, в режиме проектирования выделите компонент ComboBox1 на форме (как всегда, просто щелкнув по нему левой кнопкой мыши), затем перейдите на страничку “Events” в Инспекторе Объектов. Дважды щелкните по пустому полю напротив события OnClick . В редакторе автоматически сгенерируется следующая заготовка метода:

procedure

begin

end ;

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

procedure TForm1.ComboBox1Click(Sender: TObject);

begin

Shape1.Shape:= TShapeType(ComboBox1.ItemIndex);

end ;

Эта строчка кода устанавливает свойство Shape компонента Shape1 в вид, который пользователь выберет в выпадающем списке. Этот код работает благодаря соответствию между порядковыми членами перечислимого типа и числовыми значениями различных элементов в ComboBox . Другими словами, первый элемент перечислимого типа имеет значение 0, что соответствует первому элементу, показанному в ComboBox (см. рис.7). Давайте рассмотрим этот подход несколько подробней.

Если Вы рассмотрите декларацию перечислимого типа TShapeType, Вы увидите, что первый его элемент называется “stRectangle”. По определению, компилятор назначает этому элементу порядковый номер 0. Следующему по порядку элементу назначается номер 1 и т.д. Таким образом, слова “stRectangle”, “stSquare” и т.п., в действительности, просто символизируют порядковые номера в данном перечислимом типе. На элементы в списке ComboBox также можно сослаться по их порядковому номеру, начиная с 0. Именно поэтому так важно (в данном случае) вводить указанные строки в строгом соответствии с декларацией типа TShapeType. Таким образом, используя преобразование типа “ TShapeType (ComboBox 1. ItemIndex ) ”, Вы можете указать компилятору, что общего имеют элементы в ComboBox и перечислимый тип в TShapeType: а именно, порядковые номера.

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

Другие похожие работы, которые могут вас заинтересовать.вшм>

6923. Методы в Delphi 57.07 KB
Для создания программы CONTROL1 поместите с помощью мышки компонент Edit находится на страничке “Stndrd†Палитры Компонентов на форму. После этого в активизировавшемся окне Редактора Вы увидите сгенерированный “скелет†метода Edit1DblClick являющегося реакцией на событие OnDblClick: procedure TForm1.Edit1DblClickSender: TObject; begin Edit1. Текст в этой строке изменится в соответствии с тем что мы написали в методе Edit1DblClick: см.
6924. События в Delphi 19.79 KB
События в Delphi Объекты из библиотеки визуальных компонент VCL Delphi равно как и объекты реального мира имеют свой набор свойств и свое поведение набор откликов на события происходящие с ними. Среди набора событий для различных объектов из VCL есть как события портируемые из Windows MouseMove KeyDown так и события порождаемые непосредственно в программе DtChnge для TDtSource. Простейшие события на которые иногда нужно реагировать это например события связанные с мышкой они есть практически у всех видимых объектов...
2451. GDI: графика в Delphi 26.05 KB
В Delphi контекст устройства представлен как TCnvs. Ниже приведены две функции которые используются для рисования линий и обе принадлежат TCnvs: Имя Описание Пример MoveTo Перемещает точку начала рисования линии в указанные координаты x и y Cnvs. Cnvs. например Cnvs.
6933. Управление проектом Delphi 80.6 KB
Как Вы увидите позже, большинство операций из пункта меню “File” можно выполнить с помощью Менеджера Проекта (Project Manager), который можно вызвать из пункта меню View. Некоторые операции доступны и через SpeedBar. Данная стратегия типична для Delphi: она предоставляет несколько путей для решения одной и той же задачи, Вы сами можете решать, какой из них более эффективен в данной ситуации.
6929. История языка Delphi 13.01 KB
Delphi это греческий город где жил дельфийский оракул. Delphi это комбинация нескольких важнейших технологий: Высокопроизводительный компилятор в машинный код Объектно-ориентированная модель компонент Визуальное а следовательно и скоростное построение приложений из программных прототипов Масштабируемые средства для построения баз данных Компилятор в машинный код Компилятор встроенный в Delphi обеспечивает высокую производительность необходимую для построения приложений в архитектуре...
6932. Стандартные компоненты Delphi 28.77 KB
На первой странице Палитры Компонент размещены 14 объектов рис. Создание меню включает три шага: 1 помещение TMinMenu на форму 2 вызов Дизайнера Меню через свойство Items в Инспекторе Объектов 3 определение пунктов меню в Дизайнере Меню. Вы можете изменить шрифт и цвет метки если дважды щелкнете на свойство Font в Инспекторе Объектов. Это полный список объектов на первой странице Палитры Компонент.
6931. Среда программирования Delphi 25.84 KB
0 Word for Windows Progrm Mnger это все MDI приложения и выглядят подругому чем Delphi. Среда Delphi же следует другой спецификации называемой Single Document Interfce SDI и состоит из нескольких отдельно расположенных окон. Если Вы используете SDI приложение типа Delphi то уже знаете что перед началом работы лучше минимизировать другие приложения чтобы их окна не загромождали рабочее пространство.
1421. Способы активизации 4-х окон Delphi 232.27 KB
Вычислить зарплату преподавателя с вычетом подоходного налога(13%) либо без него за указанный период (в часах) с учетом ставки почасовой оплаты: ассистент – 75 рублей/час, доцент – 150 рублей/час, профессор – 200 рублей/час. Рекомендованный вид формы показан на рисунке. Предусмотреть, чтобы пользователь мог ввести в поле
20996. Графические объекты в среде Delphi 365.54 KB
Цель работы: изучение графических возможностей среды Delphi для создания учебного материала по графике в Delphi. Для работы с графикой в Delphi существует библиотека визуальных компонентов VCL скрывающая механизм взаимодействия приложения с операционной системой и облегчающая работу с графикой. В каждом параграфе предлагается основной теоретический материал по теме практические задания с описанием пошагового выполнения действий для их выполнения вопросы для закрепления основных умений и навыков вырабатываемых в процессе изучения...
12494. Разработка аудиоплеера в кроссплатформенной среде Embarcadero Delphi 1.21 MB
Профессия программиста состоит не только из написания кода к физическим и логическим объектам программной среды она подразумевает умение работать с растровыми и векторными графическими редакторами использовать внешние аудио библиотеки и кодеки группировать объекты согласно их назначению и придавать законченный программный вид понятный и доступный для работы широкого спектра пользователей. Embrcdero Delphi [дэ́лф’и] ранее Borlnd Delphi и CodeGer Delphi интегрированная среда разработки ПО для Microsoft Windows Mc OS iOS иndroid на...

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

Свойство Align

Задает способ выравнивания компонента внутри формы. Имеет одно из следующих значений:

Значение

Описание

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

Компонент перемещается в верхнюю часть формы, и его ширина становится равной ширине формы. Высота компонента не изменяется

Компонент перемещается в нижнюю часть формы, и его ширина становится равной ширине формы. Высота компонента не изменяется

Компонент перемещается в левую часть формы, и его высота становится равной высоте формы. Ширина компонента не изменяется

Компонент перемещается в правую часть формы, и его высота становится равной высоте формы. Ширина компонента не изменяется

Компонент занимает всю рабочую область формы

Свойство Color

Задает цвет фона формы или цвет компонента или графического объекта. Может иметь одно из следующих значений:

Цвета, приведенные в следующей таблице, являются системными цветами Windows и зависят от используемой цветовой схемы.

Значение

Текущий цвет фона окна

CllnactiveCaption

Текущий цвет заголовка неактивного окна

Текущий цвет фона меню

Текущий цвет фона Windows

Текущий цвет рамки окна

Текущий цвет текста элемента меню

Текущий цвет текста внутри окна

Текущий цвет заголовка активного окна

Текущий цвет рамки активного окна

CllnactiveBorder

Текущий цвет рамки неактивного окна

Текущий цвет рабочей области окна

Текущий цвет фона выделенного текста

ClHightlightText

Текущий цвет выделенного текста

Текущий цвет кнопки

Текущий цвет фона кнопки

Текущий цвет недоступного элемента меню

Текущий цвет текста кнопки

Помимо перечисленных в таблице цветов значение свой­ства Color может задаваться шестнадцатеричными значениями.

Свойство Ctl3D

Позволяет задать вид компонента. Если значение этого свойства равно False, компонент имеет двумерный вид, если True - трехмерный (значение по умолчанию).

Свойство Cursor

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

Свойство DrogCursor

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

Свойство DrogMode

Позволяет определить режим поддержки протокола drag-and-drop. Возможны следующие значения:

Свойство Enabled

Если это свойство имеет значение True, компонент реагирует на сообщения от мыши, клавиатуры и таймера. В противном случае (значение False) эти сообщения игнорируются.

Свойство Font

Многие визуальные компоненты используют шрифт по умолчанию. При создании компонента изначальное значение свойства Font (класс TFont) имеет следующие параметры:

Свойство

Значение

— MulDiv(10, GetDeviceCaps(DC, LOGPIXELSY), 72)

Свойство Height

Это свойство задает вертикальный размер компонента или формы.

Свойство HelpContext

Задает номер контекста справочной системы. Этот номер должен быть уникальным для каждого компонента. Если компонент активен (находится в фокусе), нажатие клавиши F1 приводит к отображению экрана справочной системы (если такой существует для данного компонента).

Свойство Hint

Задает текст, который будет отображаться при обработке события OnHint, происходящего, если курсор находится в области компонента.

Свойство Left

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

Свойство ParentColor

Это свойство позволяет указать, каким цветом будет отображаться компонент. Если значение этого свойства равно True, компонент использует цвет (значение свойства Color) родительского компонента. Если же значение свойства ParentColor равно False, компонент использует значение собственного свойства Color.

Свойство ParentCtl3D

Это свойство позволяет указать, каким образом компонент будет определять, является он трехмерным, или нет. Если значение этого свойства равно True, то вид компонента задается значением свойства Ctl3D его владельца, если же значение этого свойства равно False - то значением его собственного свойства Ctl3D.

Свойство ParentFont

Это свойство позволяет указать, каким образом компонент будет определять используемый им шрифт. Если значение этого свойства равно True, используется шрифт, заданный у владельца компонента, если же это значение равно False, то шрифт задается значением его собственного свойства Font.

Свойство PopupMenu

Это свойство задает название локального меню, которое будет отображаться при нажатии правой кнопки мыши. Локальное меню отображается только в случае, когда свойство AutoPopup имеет значение True или когда вызывается метод Popup.

Свойство TabOrder

Задает порядок получения компонентами фокуса при нажатии клавиши Tab. По умолчанию этот порядок определяется размещением компонентов в форме: первый компонент имеет значение этого свойства, равное 0, второй - 1 и т. д. Для изменения этого порядка необходимо изменить значение свойства TabOrder определенного компонента. TabOrder может использоваться только совместно со свойством Tab Stop.

Свойство TabStop

Это свойство позволяет указать, может компонент получать фокус или нет. Компонент получает фокус, если значение его свойства TabStop равно Тruе.

Свойство Tag

С помощью этого свойства можно «привязать» к любому компоненту значение типа Longlnt.

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

Кнопки

Пожалуй, самым важным элементом управления в любой программе является кнопка, ведь, фактически, без нажатия на кнопку не начинается ни одно действие в Windows-приложениях. Для создания этого элемента управления в VCL предусмотрено несколько компонент, но наиболее востребованным является Button (кнопка). Он находится на закладке Standard палитры компонентов и выглядит как маленькая кнопка с надписью «ОК».

Компонент Button достаточно простой, и в дополнение к унаследованным от TWinControl свойствам и методам, имеет лишь 5 собственных свойств. Помимо свойства Caption, определяющего отображаемый на кнопке текст, и WordWrap, отвечающего за возможность переноса слов в случае, если надпись не помещается в одну строку, у компонента Button имеются такие специфические свойства, как Cancel и Default. Их смысл заключается в следующем:

  • Cancel – если это свойство установлено в истину, то нажатие на клавишу Esc будет равнозначно щелчку по этой кнопке. Как правило, это значение устанавливают в истину для кнопки «Отмена»;
  • Default – установка в истину данного свойства делает кнопку восприимчивой к нажатию Enter, даже если она не имеет фокуса ввода. Это бывает полезным для кнопок подтверждения, например, «ОК».

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

Наконец, последнее свойство – ModalResult, имеет смысл использовать в том случае, если кнопка помещена на модальную диалоговую форму. В таком случае, если кнопке присвоено значение ModalResult, отличное от mrNone, то нажатие на такую кнопку приведет к закрытию диалогового окна и возвращению вызвавшей его процедуре значения данной кнопки.

Для примера создадим проект, состоящий из главной формы, на которую следует поместить кнопку. После этого добавим к проекту еще одну форму (File ? New ? Form), на которую, в свою очередь, поместим уже 2 кнопки. Левую сделаем кнопкой по умолчанию, возвращающую результат подтверждения. Для этого надо выбрать эту кнопку на форме и произвести в инспекторе объектов следующие действия:

  1. В свойстве Caption написать строку «ОК»;
  2. Свойство Default установить в true;
  3. Для свойства ModalResult выбрать значение mrOk.

Для второй кнопки следует сделать подобные операции, со следующими отличиями:

  1. В Caption написать «Отмена»;
  2. Свойство Cancel установить в true (свойство Default оставить false);
  3. Для свойства ModalResult выбрать значение mrCancel

Теперь можно щелкнуть по самой форме, и в инспекторе объектов выбрать для ее свойства Position значение poMainFormCenter, поскольку для модельных диалоговых окон характерно появление как раз по центру главного окна приложения. Так же не помешает установить свойство BorderStyle в bsDialog. Наконец, размеры формы желательно сделать не очень большими, поскольку все равно кроме этих 2 кнопок не ней ничего не будет (рис. 12.1), а в качестве заголовка можно написать «Модальное окно». На этом работу над этой формой можно считать завершенной.

Рис. 12.1. Форма модального диалогового окна

Сохраним проект, согласившись с предложенными по умолчанию именами (Unit2, Unit1 и Project1) в какой-либо папке на жестком диске и вернемся к первой, главной форме программы. На ней уже имеется кнопка, так что теперь следует написать код для обработчика события щелчка мышью. Для этого щелкните по кнопке мышкой и выберите на закладке Events инспектора объектов событие onClick и дважды щелкните по полю напротив, чтобы Delphi подготовила необходимый программный код.

СОВЕТ
На самом деле, для того, чтобы создать обработчик события onClick для кнопки достаточно дважды щелкнуть по самой кнопке. Двойной щелчок по визуальному компоненту, помещенному на форму, создает обработчик для наиболее характерного события, связанного с данным элементом управления. Раузметтся, для кнопки это как раз и будет onClick.

В результате вы получите заготовку для обработчика события onClick этой кнопки:

Procedure TForm1.Button1Click(Sender: TObject); begin end;

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

Uses unit2;

Здесь следует отметить тот момент, что хотя в данном модуле уже имеется часть uses, помещенная в самом начале, вслед за ключевым словом interface, включать другие формы программы туда не рекомендуется во избежание возникновения перекрестных связей. Они могут возникнуть, например, если не только первая форма обращается ко второй, но и вторая – к первой.

Теперь все готово к написанию обработчика события onClick. Прежде всего, он должен показывать диалоговую форму в модальном режиме. Для этого достаточно написать такую строку кода:

Form2.ShowModal;

Вслед за ним разместим код, который будет выводить в заголовок этого окна результат, полученный от вызванного диалога:

If Form2.ModalResult = mrOk then Form1.Caption:="OK"; if Form2.ModalResult = mrCancel then Form1.Caption:="Cancel";

Отметим, что после обращения к методу ShowModal управление будет передано вызванной таким образом форме. Соответственно, пока пользователь не закроет тем или иным способом модальное окно, следующий оператор выполнен не будет. Пример можно посмотреть в папке Demo\Part3\Button.

Надписи

Надписи, или текстовые метки (labels), часто используются в программах для вывода пояснительной информации. В VCL для этих целей используется компонент TLabel. На палитре компонентов он расположен 4-м слева, в виде кнопки с буквой «А».

ПРИМЕЧАНИЕ
Самой первой на любой закладке палитры компонент является кнопка со стрелкой, которая является не компонентой, а инструментом IDE. Ее следует использовать в том случае, если вы выберите компонент, но передумаете размещать его на форме. В таком случае щелчок по этой кнопке сбросит выбранный компонент.

Текст, помещенный на форму при помощи меток, пользователю нельзя редактировать. Кроме того, такой элемент не может даже получить фокус ввода. Это объясняется тем, что класс TLabel происходит не от оконных элементов интерфейса (TWinControl), а от более легких графических (TGraphicControl). От этого предка классу TLabel достается свойство Canvas. Что касается остальных свойств метки, то помимо всех унаследованных, включая самое важное для метки свойство – Caption, отвечающее за собственно надпись, она имеет несколько специфических свойств, отвечающих за выравнивание и расположение. Все эти свойства приведены в таблице 12.1.

Таблица 12.1. Свойства TLabel
Свойство Тип значения Описание
Alignment TAlignment Определяет выравнивание текста по горизонтали в области метки. Может принимать значения taLeftJustify, taRightJustify и taCenter
AutoSize Boolean Определяет, должна ли метка изменять свои размеры в зависимости от текста
FocusControl TWinControl Указывает на элемент управления, который может быть ассоциирован с меткой
Layout TTextLayout Определяет выравнивание текста по вертикали. Может принимать значения tlTop, tlCenter и tlBottom
ShowAccelChar Boolean Определяет, должен ли символ & обозначать подчеркнутую букву. Если да, то для вывода самого символа & его надо будет указать дважды (&&)
Transparent Boolean Определяет, должен ли фон метки быть прозрачным
WordWrap Boolean Определяет, должен ли текст, не помещающийся по ширине, переноситься на следующие строки

При установке свойств выравнивания следует учитывать, что такие свойства, как Alignment и Layout имеют смысл лишь в том случае, если свойство AutoSize не установлено в истину, поскольку в противном случае границы надписи всегда будут определяться лишь текстовым содержимым. А свойство ShowAccelChar следует использовать лишь в паре с FocusControl, поскольку, по правилам интерфейса Windows, подчеркнутая буква означает, что при нажатии ее на клавиатуре совместно с клавишей Alt, ассоциированный с надписью элемент управления получит фокус ввода.

Вместе с тем, в Delphi имеется и другой аналогичный по своему назначению компонент – StaticText, расположенный на закладке Additional палитры компонентов. Его отличие от Label состоит в том, что он является потомком класса TWinControl, со всеми вытекающими отсюда последствиями, а именно – наличия собственного дескриптора оконного элемента (Handle), возможности быть заключенным в рамку (свойство BorderStyle) и т.д. Но в типичном случае все-таки предпочтительнее использовать менее ресурсоемкий элемент Label.

Поля ввода текста

Вслед за меткой на палитре компонент располагается другой часто используемый в интерфейсе Windows-приложений элемент управления, Edit – строка ввода текста. Этот компонент, в отличие от метки, является полноценным оконным элементом управления, происходящим от TWinControl, и может не только получать фокус ввода, но и использоваться для правки однострочного текста пользователем. При этом поддерживаются такие операции, как перемещение по строке при помощи клавиш управления курсором, удаление символов, выделение текста, в том числе при помощи мышки, а так же взаимодействие с буфером обмена Windows (clipboard).

Компонента Edit имеет ряд свойств и методов, специфических для элементов редактирования текста. Все они инкапсулированы в классе TCustomEdit, потомками которого, помимо TEdit, являются и другие элементы интерфейса, связанные с вводом текста. Что касается его свойств, то они приведены в таблице 12.2.

Таблица 12.2. Свойства TCustomEdit
Свойство Тип значения Описание
AutoSelect Boolean Определяет, должен ли быть выделен весь текст при получении фокуса ввода
AutoSize Boolean Определяет, должна ли автоматически изменяться высота элемента при изменении размера шрифта
BorderStyle TBorderStyle Определяет, должен быть компонент обрамлен рамкой (bsSingle), или нет (bsNone)
CanUndo Boolean Указывает, может ли в данный момент быть применен метод Undo
CharCase TEditCharCase Определяет, должен ли вводимый текст преобразовываться в символы верхнего или нижнего регистра. Допустимые значения: ecNormal, ecUpperCase и ecLowerCase
HideSelection Boolean Определяет, должно ли сохраняться визуальное выделение текста при потере фокуса ввода
MaxLength Integer Определяет максимально допустимое количество символов в строке
Modified Boolean Указывает, был ли текст изменен пользователем
PasswordChar Char Определяет символ, который должен отображаться вместо вводимых символов
ReadOnly Boolean Определяет, может или нет пользователь редактировать текст
SelLength Integer Указывает на длину выделенного фрагмента текста
SelStart Integer Указывает на позицию первого выделенного символа
SelText String Содержит строку c выделенным фрагментом текста

Из свойств, влияющих на внешнее оформление компоненты, отметим AutoSize и BorderStyle. Первое, в отличие от одноименных свойств метки, в данном случае изменяет размеры компоненты только по высоте. А второе, на сей раз – в отличие от такого же свойства у формы, может принимать только 2 значения, которые сводятся к тому, будет рамка вообще или нет.

Все остальные свойства, так или иначе, связаны непосредственно с текстовым содержимым. Например, если установить PasswordChar в значение, отличное от нулевого символа (#0), что принято по умолчанию, то мы получим элемент управления, предназначенный для ввода паролей. Как правило, в этом случае для замены используют символ «звездочка». Разумеется, при этом вводимые символы не будут в действительности заменяться, а останутся теми, что были введены в действительности.

Зато другое свойство, влияющее на ввод текста – CharCase – действительно может влиять на вводимые символы. При этом если оно будет установлено в значение ecUpperCase, то все вводимые буквы станут преобразовываться в символы верхнего регистра, а если в ecLowerCase – то в нижнего.

Свойство MaxLength, при значении, большим нуля, ограничивает длину текста. А свойство ReadOnly, будучи установленным в истину, вообще запретит правку текста пользователем. Если же правка возможна, то при помощи свойства Modified можно узнать, изменял ли пользователь текст: оно автоматически устанавливается в истину при любом изменении содержимого, кроме тех, что были произведены программными методами. Ну а если какая-либо правка была произведена, то возможен и возврат к предыдущему состоянию – за этим «следит» свойство CanUndo.

Все оставшиеся свойства связаны с выделением текста. Как известно, в Windows текст выделяется либо клавиатурой (перемещением с нажатой клавишей Shift), либо мышкой. Разумеется, компоненты VCL, являясь, по большей части, оболочкой для системных средств ОС, поддерживают оба этих метода и предоставляют разработчику все необходимое для работы с выделенным фрагментом. В частности, первый выделенный символ можно определить по свойству SelStart. Если же ничего не выделено, то это свойство будет ссылаться на текущую позицию каретки в строке. Но если текст все-таки выделен, то длину выделенного фрагмента можно узнать по текущему значению свойства SelLength. Просуммировав оба этих значения, при желании, можно определить и последний выделенный символ:

SelEnd:= Edit1.SelStart + Edit1.SelLength;

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

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

Наглядную иллюстрацию этих свойств можно получить, экспериментируя с настройками этой компоненты. Ряд вариантов приведен в примере editprops, находящемся в каталоге Demo\Part3\Edit.

Разобравшись со свойствами, перейдем к методам. Все они также являются унаследованными от класса TCustomEdit, и предназначены для работы с выделенным текстом, включая взаимодействие с буфером обмена. Так же есть методы для работы с содержимым в целом. Так, для удаления всего текста используют метод Clear, для выделения всего содержимого – метод SelectAll, а для сброса выделения – метод ClearSelection.

Для такой незаменимой операции, как отмена, применяются методы Undo и ClearUndo. При этом собственно отмену (при ее возможности, для чего следует проверять свойство CanUndo) производят при помощи метода Undo. Второй же метод позволяет сбросить список произведенных действий, делая отмену невозможной. Например, реализация разовой отмены может выглядеть следующим образом:

If Edit1.CanUndo then begin Edit1.Undo; Edit1.ClearUndo; end;

Оставшиеся методы – CopyToClipboard, CutToClipboard и PasteFromClipboard используются для таких стандартных операций с буфером обмена, как копирование, вырезание и вставка. При этом копирование и вырезание возможно лишь в том случае, если имеется выделенный текст. Таким образом, перед обращением к этим методам следует проверять, есть ли выделенный фрагмент текста. Делать это можно, проверяя значение свойства SelLength:

If Edit1.SelSength > 0 then ...

Что касается операции вставки, то она, разумеется, возможна только в том случае, если в буфере обмена находится текст. Если находящийся в буфере текст состоит более чем из одной строки (т.е. разделен символами «новая строка»), то в поле редактирования будет вставлена лишь первая строка текста.

Многострочный редактор и строки

Для работы с многострочным текстом используется другой наследник класса TCustomEdit – компонент Memo, или многострочный редактор. На палитре компонентов его значок расположен сразу после однострочного редактора. Класс TMemo имеет все свойства однострочного редактора, а так же ряд собственных свойств, необходимых учитывающих специфику многострочного редактирования. Прежде всего, это свойство WordWrap, отвечающее за автоматический перенос не умещающихся по ширине окна строк текста. А свойство Alignment отвечает за выравнивание текста по левому (taLeftJustify) или правому (taRightJustify) краям, или по центру (taCenter).

Для работы с множеством строк могут понадобиться полосы прокрутки. За их наличие и расположение отвечает свойство ScrollBars, которое может принимать одно за 4 значений: ssNone – без полос прокрутки (это значение принято по умолчанию), ssHorizontal – полоса для горизонтальной прокрутки, ssVertical – полоса для вертикальной прокрутки и ssBoth – с обеими полосами прокрутки. При этом отсутствие полос не ограничивает размер вводимого текста, хотя и влияет на его ввод.

Так, если установлена горизонтальная прокрутка, то вводимый текст не будет переноситься, вне зависимости от того, какое значение имеет свойство WordWrap. В то же время, если полосы прокрутки отсутствуют вообще, то при включенном переносе слов, вводимый текст будет ограничиваться по видимой ширине редактора, а при выключенном – уходить вправо, сдвигая видимую границу за левый край окна.

Еще 2 свойства отвечают за обработку отдельных клавиш на клавиатуре. Это WantTabs и WantReturns. Первое отвечает за обработку нажатий клавиши табуляции, а второе – клавиши ввода. При этом значение истины для обоих свойств означает, что эти клавиши будут обрабатываться самим многострочным редактором. Т.е. нажатие на Tab будет вставлять символ табуляции, а нажатие на Enter – к началу новой строки. Если же значение этих свойств будет ложью, то нажатие на Tab приведет к перемещению фокуса ввода к следующему элементу управления, а обработка нажатия клавиши Enter будет передана форме. По умолчанию свойство WantTabs установлено в false, а WantReturns – в true.

Для того чтобы определить, где в данный момент находится каретка, обращаются к свойству CaretPos. Оно возвращает координаты (X, Y) точки по отношению к верхнему левому углу окна редактора. Если же необходимо определить смещение не в пикселях от угла компоненты, а в символах от начала строки, то следует использовать свойство SelStart.

Наконец, рассмотрим свойства, относящиеся собственно к текстовому содержимому многострочного редактора. Разумеется, у него есть свойство Text, через которое можно получить доступ к всему содержимому сразу. Но если вы поместите элемент Memo на форму и посмотрите на инспектор объекта, то не найдете в нем этого свойства. Дело в том, что оно не является опубликованным для класса TMemo, и доступно лишь программно. Зато у многострочного редактора имеется другое, более подходящее свойство – Lines, являющееся опубликованным.

Если в инспекторе объекта щелкнуть по кнопке с многоточием напротив этого свойства, то откроется окно редактирования, в котором можно ввести начальный текст (рис. 12.2).


Рис. 12.2. Текстовый редактор для многострочных компонент в Delphi IDE

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

В качестве типа данных для свойства Lines используется не строка, а специальный объект TStrings, являющийся классом, инкапсулирующем работу со строками, или, если быть точнее – со списками строк. С его помощью можно манипулировать содержимым многострочного редактора, рассматривая его как отдельные строки. Свойства класса TStrings приведены в таблице 12.3.

Таблица 12.3. Свойства TStrings
Свойство Тип данных Описание
CommaText String Представляет весь список одной строкой, разделенной запятыми. При этом строки с пробелами заключаются в двойные кавычки
Count Integer Указывает на количество строк в списке
DelimitedText String Представляет весь список одной строкой в соответствии со значениями свойств Delimeter и QuoteChar
Delimiter Char Определяет разделитель для свойства DelimitedText
Names : string Представляет собой массив имен для строк формата имя-значение
NameValueSeparator Char Определяет символ, по которому будут разделены имя и значение
Objects : TObject Представляет собой массив объектов, ассоциированных со строками
QuoteChar Char Определяет символ кавычек для свойства DelimitedText
Strings : string Представляет список в качестве массива строк
Text String Список строк одной строкой, включая символы «возврат каретки» и «новая строка»
ValueFromIndex : string Представляет собой массив значений для строк формата имя-значение
Values : string Позволяет получить значение по его имени для строк формата имя-значение

Все свойства этого класса можно разделить на 2 категории: те, что предназначены для работы со строками списка по отдельности, и те, что позволяют взаимодействовать со всем текстом в целом. К первой группе относятся свойства Count, Strings, Names и Values. Причем последние 2 свойства используются при работе со списком, состоящим из строк типа имя значение, например, «город=Москва». К этой группе можно причислить свойства NameValueSeparator и ValueFromIndex. Для примера рассмотрим список, состоящий из строк «город=Москва» и «страна=Россия». Чтобы можно было рассматривать этот список как состоящий из пар имя-значение, следует назначить свойству NameValueSeparator значение «=». После этого можно обращаться к свойствам Names, Values и ValueFromIndex. Например, применительно к строкам, содержащимся в многострочном редакторе (пусть он называется Memo1), мы можем использовать подобный код (см. также пример в Demo\Part3\Memo):

Var s: string; ... s:= Memo1.Lines.Names; // s получит «Москва» Memo1.Lines.ValueFromIndex:="Подольск"; s:= Memo1.Lines.Values["город"]; // s получит «Подольск» s:= Memo1.Lines.Values["страна"]; // s получит «Россия»

Если же предстоит работать с обычными строками, то можно использовать свойство Strings. Так, для обращения к первой строке списка достаточно написать:

S:= Memo1.Lines.Strings; Memo1.Lines.Strings:="Вторая строка";

Несколько особняком стоит свойство Objects. Дело в том, что список строк позволяет ассоциировать какой-либо объект с каждой строкой. В ряде случаев это оказывается очень полезным дополнением.

Что касается свойств, предназначенных для работы со списком как с единой строкой текста, то это, прежде всего, свойство Text, представляющее все содержимое списка в качестве одной строки. При этом в тех местах, где заканчиваются реальные строки списка, добавляются символы новой строки и возврата каретки (#10 и #13).

ПРИМЕЧАНИЕ
Применительно к компоненту Memo, его собственное свойство Text содержит точно те же данные, что и Lines.Text.

Другое свойство, CommaText, также представляет весь список одной строкой, но использует для этого формат SDF, когда каждая строка перечисляется через запятую. При этом если исходная строка не содержит ни запятых, ни пробельных символов, то она остается как есть, в противном случае – заключается в кавычки. Например, список, состоящий из строк «Borland Delphi» и «Forever», преобразуется в строку «"Borland Delphi",Forever».

Еще одно свойство, DelimetedText, является во многом аналогичным CommaText, за тем исключением, что можно выбирать тип кавычек и разделителей, которые, в свою очередь, определяются свойствами QuoteChar и Delimiter. Таким образом, если эти свойства установить в «"» и «,», то значение DelimetedText будет полностью соответствовать значению CommaText.

Что касается методов класса TStrings, то среди них можно выделить Add, AddObject, AddStrings, Append, Assign, Clear, Delete, IndexOf, Insert, LoadFromFile и SaveToFile. Пожалуй, самыми интересными являются последние 2 метода, позволяющие без каких-либо дополнительных действий загрузить из файла или сохранить в файл сразу все содержимое текстового редактора. Более подробно все эти методы будут рассмотрены в рамках класса TStringList.

Класс TStringList

Хотя в качестве свойств ряда компонент в VCL выступают объекты типа TStrings, использовать объекты этого класса сами по себе нельзя, поскольку этот класс является абстрактным. Соответственно, для работы непосредственно со списками строк в программах надо либо создавать классы, основанные на TStrings, либо использовать его наследника, «готового к употреблению» – класс TStringList.

Помимо того, что класс TStringList не является виртуальным, он добавляет функциональность к своему предшественнику, а именно – возможность поиска и сортировки строк в списке. В частности, он имеет такие методы, как CustomSort, Find и Sort, а также связанные с сортировкой свойства:

  • CaseSensitive – это свойство определяет, долен ли учитываться символ регистра при сравнении во время поиска совпадений и сортировки;
  • Duplicates – это свойство определяет, разрешено или нет помещать в список одинаковые строки;
  • Sorted – данное свойство определяет, надо ли производить сортировку сразу при добавлении новых строк.

Если свойства CaseSensitive и Sorted могут принимать всего по 2 значения – ложь или истина, то для свойства Duplicates предусмотрено 3 варианта, определяющих поведение списка при добавлении новых строк, совпадающих с уже присутствующими в списке. Так, если для него установлено принятое по умолчанию значение dupAccept, то одинаковые строки будут добавляться, а если установлено dupIgnore – то не будут. Если же установить его в dupError, то попытка добавить к списку повторяющуюся строку будет вызывать исключение типа EStringListError.

Собственно для добавления новых строк к списку используют методы Add, Append или AddObject, а если требуется добавить сразу группу строк, т.е. другой список – то AddStrings. Эти, а так же другие методы классов TStrings и TStringList представлены в таблице 12.4.

Таблица 12.4. Методы списков строк
Метод Параметры Описание
Add const S: string Добавляет новую строку к списку
AddObject const S: string; AObject: TObject Добавляет строку к списку и ассоциирует с ней объект
AddStrings Strings: TStrings Добавляет группу строк к списку
Append const S: string Добавляет строку к списку, но в отличие от Add не возвращает результат операции
Assign Source: TPersistent Присваивает строки, и, по возможности, объекты, из другого списка к данному
Clear - Удаляет все строки списка
CustomSort Compare: TStringListSortCompare Сортирует строки в списке используя правила, определенные в указанной функции
Delete Index: Integer Удаляет из списка строку с указанным индексом
Equals Strings: TStrings Сравнивает 2 списка и возвращает результат сравнения
Exchange Index1, Index2: Integer Меняет между собой расположение 2 строк в списке
Find const S: string; var Index: Integer Находит строку в отсортированном списке и возвращает ее индекс
IndexOf const S: string Аналогично Find, но подходит и для несортированных списков
IndexOfName const Name: string Возвращает индекс первого найденного совпадения имени для списков типа имя-значение
IndexOfObject AObject: TObject Возвращает индекс первой строки, ассоциированной с указанным объектом
Insert Вставляет строку в указанную позицию списка
InsertObject Index: Integer; const S: string AObject: TObject Вставляет строку и объект в указанную позицию списка
LoadFromFile const FileName: string Заполняет список строками текста из указанного текстового файла
Move CurIndex, NewIndex: Integer Перемещает строку в списке
SaveToFile const FileName: string Сохраняет строки списка в указанный файл
Sort - Производит сортировку строк списка

Наиболее часто используемым методом, безусловно, является Add, при помощи которого как раз и создаются списки. При необходимости вставить строку в какое-либо определенное место списка, вместо него используют Insert. Для управления отдельными элементами списков пригодятся Delete, Move и Exchange, а для операций над списком в целом – Clear, SaveToFile и LoadFromFile.

Пример, наглядно демонстрирующий работу целого ряда методов списков строк применительно к свойству Lines многострочного редактора можно посмотреть в каталоге Demo\Part3\StringList.

Что касается методов, предназначенных для поиска и сортировки, то к их использованию следует подходить с некоторой осторожностью. Прежде всего, время, необходимое для сортировки списков, возрастает вместе с его размерами не линейно, а в геометрической прогрессии. Соответственно, если сортировка списка из сотни-другой элементов происходит почти моментально, то время выполнения сортировки для больших списков, содержащих многие тысячи строк, может оказаться весьма продолжительным. В то же время, если список является отсортированным изначально (т.е. свойство Sorted установлено в истину), то в процессе добавления новых строк они сразу же будут размещаться согласно порядку сортировки. Это следует учитывать при написании программ, работающих с объемными списками.

Списки

Помимо многострочного редактора, в Delphi, на той же закладке Standard палитры компонентов, располагаются еще 2 компонента, использующих списки строк для хранения своих значений. Это ListBox и ComboBox.

Простой список, представленный компонентом ListBox, представляет собой прямоугольную область, в которой располагаются его элементы – строки. Если строк в списке больше, чем может поместиться в отведенной области, то автоматически появляется полоса прокрутки.

Класс TListBox является наследником класса TWinControl и имеет собственные свойства, представленные в таблице 12.5.

Таблица 12.5. Основные свойства ListBox
Свойство Тип Описание
AutoComplete Boolean Определяет, должен ли список реагировать на нажатие клавиш таким образом, чтобы находить и выделить совпадающий элемент
BorderStyle TBorderStyle Определяет, должна или нет быть рамка вокруг списка. Допустимые значения: bsNone, bsSingle
Columns Integer Определяет количество колонок, видимых без горизонтальной прокрутки
Count Integer Указывает на количество элементов списка
ItemIndex Integer Определяет порядковый номер выбранного элемента, начиная с 0. Если не выбрано ни одного, то устанавливается в -1
Items TStrings Содержит строки списка
MultiSelect Boolean Определяет, допустимо или нет производить множественный выбор
SelCount Integer Указывает на количество выбранных элементов
Selected array of Boolean Определяет, выбран или нет тот или иной элемент списка
Sorted Boolean Определяет, должен ли список быть отсортирован
TopIndex Integer Определяет порядковый номер элемента, который является самым верхним в видимой части списка

Отдельное пояснение следует дать для свойства Columns. Дело в том, что если оно имеет значение, отличное от принятого по умолчанию нуля, то список становится не простым вертикальным, а многоколоночным, с горизонтальной прокруткой по колонкам для случая, если все элементы не умещаются на отведенной для списка области. Поэтому, в зависимости от того, какое значение имеет параметр Columns, один и тот же список может выглядеть совершенно по-разному (рис. 12.3).


Рис. 12.3. Влияние значения свойства Columns на внешний вид списка

ПРИМЕЧАНИЕ
Следует отметить, что многоколоночные списки используются довольно-таки редко. Пожалуй, едва ли не единственное их применение – это проводник Windows в режиме списка. При этом в нем используется совершенно другой компонент, аналогом которого в VCL является ListView.

Рассмотрим также свойство MultiSelect, которое оказывает непосредственное влияние на ряд других свойств. Так, если оно установлено в истину, то свойство ItemIndex всегда будет равно нулю, а если в ложь, то свойство SelCount всегда будет иметь значение -1. Что касается его непосредственного влияния на список, то оно позволяет выделять сразу несколько элементов с использованием мышки и клавиш Shift и Ctrl.

Если рассматривать методы списка, то основная их часть предназначена для выполнения тех или иных манипуляций над выбранными элементами:

  • ClearSelection – снимает выделение со всех выбранных элементов;
  • CopySelection – копирует выбранные элементы в другой список;
  • DeleteSelected – удаляет все выделенные элементы из списка;
  • SelectAll – выделяет все элементы в списке.

Еще 2 метода выполняют работу, характерную для списков вообще. Так, метод Clear удаляет все элементы списка, а метод AddItem добавляет новый элемент, и, при необходимости, ассоциирует с ним объект:

List1.AddItem("Строка – новый элемент списка",nil);

ПРИМЕЧАНИЕ
Следует учитывать, что при работе с визуальными компонентами, представляющими списки, в случаях, когда одна и та же задача решается как методами свойства Items, так и собственными методами компонента, желательно использовать методы самих компонент. Т.е. List1.Clear предпочтительнее, чем List1.Items.Clear.

Теперь рассмотрим другой вариант списков, представленный компонентом ComboBox. Этот компонент расположен на палитре инструментов непосредственно за ListBox. Он интересен тем, что как бы объединяет в себе сразу 2 компонента – строку редактирования (Edit) и список (ListBox).

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

Очевидно, что ниспадающий список имеет ряд свойств, характерных как для однострочного редактора (SelText, SelStart, SelLength, MaxLength и CharCase), так и для обычного списка (Sorted, Items, ItemIndex и AutoComplete). Вместе с тем, предусмотрен и ряд уникальных свойств, в частности, необходимых для настройки его ниспадающей части. К ним относятся следующие свойства:

  • AutoCloseUp – если установлено в истину, то раскрывающаяся часть списка будет закрываться автоматически, как только пользователь выберет элемент;
  • AutoDropDown – если установлено в истину, то список будет раскрываться автоматически, как только пользователь начнет вводить текст;
  • DropDownCount – это свойство определяет количество строк, которое будет отображаться в раскрывшемся списке;
  • DroppedDown – обратившись к этому свойству, можно определить, раскрыт или нет список в данный момент.

Помимо всех этих свойств, ориентированных непосредственно на ниспадающую часть списка, имеется еще одно – Style, отвечающее за вид и поведение комбинированного списка. Среди возможных вариантов значений этого свойства нам интересны следующие:

  • csDropDown – это значение принято по умолчанию, при нем список ведет себя именно так, как описано;
  • csDropDownList – если установить это значение, то возможность непосредственного редактирования текста пропадет, т.е. подобно обычному списку пользователь сможет лишь выбирать из предложенных вариантов;
  • csSimple – если оставить размеры списка по вертикали без изменений, то мы получим, фактически, элемент Edit, с «привязанным» к нему списком, который при этом не будет виден. Однако если размеры увеличить, растянув его по высоте, то непосредственно под ним появится ни что иное, как обычный список.

Чтобы нагляднее представить себе разницу между этими режимами, достаточно сделать простейшее приложение, использующее компонент ComboBox во всех возможных режимах, включая оба случая для csSimple – с видимой и скрытой частью списка. Пример можно найти в каталоге Demo\Part3\ComboBox.

Что касается методов комбинированного списка, то все они уже были нами рассмотрены в рамках обычного списка. Это AddItem, Clear, ClearSelection, CopySelection, DeleteSelected и SelectAll.

Переключатели

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

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

Начнем с независимых переключателей – флажков. В VCL флажок представлен компонентом CheckBox. Он выглядит как небольшой прямоугольник с текстовым заголовком, расположенным справа. Если же вдруг появится острая необходимость «развернуть» флажок таким образом, чтобы текст находился слева, то можно установить свойство Alignment в taLeftJustify.

Но самым важным свойством флажка, пожалуй, является Checked. Именно оно определяет его состояние. Так, если флажок включен (что визуально проявляется как наличие галочки на квадратике), то это свойство имеет значение истины, а если выключен – лжи. Этим свойством можно управлять программно, визуально это будет проявляться как появление или исчезновение галочки.

Вместе с тем, для флажка предусмотрено еще одно состояние – запрещенное. Это состояние является опциональным и за его наличие или отсутствие отвечает свойство AllowGrayed. В том случае, если оно установлено в истину, то при щелчке мышкой по такому флажку будет происходить циклическая смена между 3 состояниями: установлен, снят и запрещен. В последнем режиме он выглядит как отмеченный, но с очень низкой контрастностью (рис. 12.4).


Рис. 12.4. Все состояния флажка Checkbox

Поскольку состояний может быть не 2, а 3, то булевского значения в таких случаях оказывается недостаточно, чтобы представить все варианты. В таком случае для контроля или назначения состояния флажка используют свойство State. Оно может принимать следующие 3 значения типа TCheckBoxState:

  • cbUnchecked – флажок не отмечен;
  • cbChecked – флажок отмечен;
  • cbGrayed – флажок недоступен.

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

Второй вид переключателей – зависимые – представлен в Delphi компонентом RadioButton (отсюда и его жаргонное название «радиокнопка»). Как уже было отмечено, его основным отличием от флажка является то, что изменение состояния одного такого переключателя влияет на состояние других. Иначе говоря, только один зависимый переключатель в группе может быть отмечен. Поэтому такие переключатели обычно используют для указания взаимоисключающих опций. Соответственно, щелчком мышки его можно только включить. Для отключения же потребуется включить другой зависимый переключатель из этой же группы. Примерно так работают кнопки на старых радиоприемниках, что объясняет название этого компонента.

Поскольку состояний у такой кнопки может быть только 2 – включено или выключено, то и свойств остается только 2 – Checked и Alignment.

Рассмотрим поведение флажков и радиокнопок на примере. Для этого создадим новое приложение, на главную форму которого поместим 2 столбика переключателей: независимые – слева, а зависимые – справа. Для одного из флажков, скажем, последнего, установим свойство AllowGrayed в истину. Затем внизу формы расположим обычную кнопку, а для ее свойства Caption укажем «Сброс» (рис. 12.5).


Рис. 12.5. Переключатели - флажки и радиокнопки

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

Реализовать сброс всех флажков можно последовательно, банальным перечислением каждого элемента и выставления свойства Checked в ложь:

CheckBox1.Checked:=false; CheckBox2.Checked:=false; ... RadioButton3.Cgecked:=false;

В принципе, когда флажков всего несколько штук, этот вариант является оптимальным. Тем не менее, рассмотрим и другой способ, который может оказаться полезным при большом числе переключателей. Состоит он в обходе всех компонентов формы при помощи цикла по свойству Controls и в присваивании нужного значения нужному свойству всех подходящих компонентов. В нашем случае задача несколько усложняется, поскольку мы имеем 2 разных класса компонентов, и свойство Checked у них происходит от разных предков. Поэтому нам придется реализовать проверку на принадлежность объекта к тому или иному классу, и действовать уже исходя из этих данных. В результате мы получим следующий обработчик события для щелчка мышкой по кнопке:

Procedure TForm1.Button1Click(Sender: TObject); var i: integer; begin for i:=0 to Form1.ControlCount-1 do begin if Form1.Controls[i] is TCheckBox then (Form1.Controls[i] as TCheckBox).Checked:=false; if Form1.Controls[i] is TRadioButton then (Form1.Controls[i] as TRadioButton).Checked:=false; end; end;

Прежде всего, здесь организован цикл, обходящий все дочерние компоненты формы. В теле цикла сначала проверяется, принадлежит ли текущий компонент классу TCheckBox. Если да, то он явно приводится к типу TCheckBox при помощи оператора as, после чего с ним можно поступать так же, как если бы это было явное указание на объект этого класса, т.е. идет обращение к свойству Checked, которому присваивается новое значение. Затем то же самое проделывается для случая, когда компонент оказывается принадлежащим классу TRadioButton.

Такой подход, с использованием обязательной проверки на принадлежность к типу (с применением оператора is) исключает возможные ошибки времени выполнения. Например, если даже все переключатели были бы одного типа, скажем, флажками, нельзя упускать из виду того, что на форме кроме них могут находиться и другие компоненты. Даже в рассматриваемом нами случае такой компонент имеется - это та же кнопка «Сброс», которую, разумеется, не получилось бы привести от типа TButton к типу TCheckBox.

Работающий пример вы найдете в каталоге Demo\Part3\Checks.

Панели и группы

При рассмотрении радиокнопок неоднократно отмечалось, что они взаимодействуют в рамках группы. Очевидно, что в приведенных примерах группу образовавали все компоненты типа RadioButton, находящиеся на форме. Но это не означает, что на форме может быть только одна группа таких кнопок. Дело в том, что принадлежность компоненты к группе определяется на основании того, какому компоненту она принадлежит. Во всех рассмотренных ранее примерах таковым являлась сама форма. Но помимо формы имеются и другие компоненты, которые могут иметь дочерние объекты. Одним из наиболее широко применяемых элементов такого типа является панель – Panel. На палитре компонентов она расположена предпоследней на закладке Standard и выглядит как пустой серый квадратик. Поместив этот компонент на форму, вы получите прямоугольную область, ограниченную выпуклой рамкой.

Панели используются не только для логической группировки элементов управления, но и для визуального оформления приложений. Благодаря последнему обстоятельству, панель имеет целый ряд свойств, ответственных за внешний вид панели, вернее, ее рамки. Всего таковых имеется 5 штук, включая уже хорошо знакомо по другим элементам, например, текстовым редакторам, свойство BorderStyle. Точно так же, как и для них, для панели можно либо включить рамку (bsSingle), либо оставить ее выключенной (bsNone). Да, ошибки здесь нет: хотя рамка по умолчанию выключена, панель все равно имеет визуальные границы. А дело в том, что помимо собственно рамки, панель имеет еще и скосы (bevels), причем их 2 – внешние и внутренние. И именно внешний скос мы и видим при стандартных настройках панели. Соответственно, оставшиеся 4 свойства как раз скосами и управляют:

  • BevelInner – это свойство отвечает за вид и наличие внутреннего скоса;
  • BevelOuter – это свойство управляет видом внешнего скоса;
  • BevelWidth – при помощи этого свойства можно управлять толщиной линии, образующей скосы, причем данное свойство одновременно влияет как на внутренний, так и на внешний;
  • BorderWidth – данное свойство позволяет изменять границу между внутренним и внешним скосами.

Для свойств, отвечающих за вид скосов – BevelInner и BevelOuter предусмотрено по несколько значений:

  • bvNone – скос отсутствует (принято по умолчанию для внутреннего скоса, BevelInner);
  • bvRaised – скос образует выпуклую рамку (принято по молчанию для внешнего скоса, BevelOuter);
  • bvLowered – скос образует вогнутую рамку;
  • bvSpace – в типичном случае аналогичен bvRaised.

Таким образом, мы получаем весьма широкие просторы для манипулирования внешним видом границ панели – можно как отключать границы панелей вообще, установив свойства BevelInner и BevelOuter в bvNone, так и заключать панели в объемные рамки самого разнообразного вида (рис. 12.6).


Рис. 12.6. Различные комбинации откосов панелей

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

Следует отметить, что если панель используется не в декоративно-пояснительных целях (например, как подзаголовок окна), а именно как группирующий элемент, то ее свойству Caption присваивают пустую строку, а пояснительный текст размещают в верхнем правом углу при помощи компонента Label. При этом, как правило, скосы не используются (оба отвечающих за их вид свойства устанавливают в bvNone), а если необходимо визуально подчеркнуть, что размещенные на панели компоненты относятся к одной логической группе, используют обычную рамку (свойство BorderStyle).

Вместе с тем, в Delphi имеется компонент, специально предназначенный для группировки элементов – GroupBox, или контейнер группы. В отличие от панели, он не имеет откосов, но всегда заключен в рамку. При этом его заголовок (Caption) изначально расположен как раз там, где надо – в верхнем левом углу, причем накладывается поверх образующей рамку линии. В целом можно отметить, что класс TGroupBox происходит от TWinControl и не имеет каких-либо дополнительных свойств и методов.

Контейнер группы используется для объединения ряда различных компонент в один логически связанный блок. При этом компоненты могут быть использованы самые разные – переключатели, поля редактирования, кнопки и т.д. Если же в группе требуется разместить исключительно радиокнопки, то можно использовать другой компонент – RadioGroup. Его можно назвать контейнером группы зависимых переключателей. Этот специализированный компонент является наследником контейнера группы, предназначенным исключительно для радиокнопок. Причем непосредственно помещать на него компоненты RadioButton нет надобности, вместо этого следует использовать его собственное свойство Items. Каждый элемент, указанный в списке Items, является надписью с переключателю. Соответственно, задав, скажем, 4 строки в списке Items, мы получим готовую группу из 4 радиокнопок, являющуюся одним компонентом. Это очень удобно, поскольку вместо проверки состояния каждого из переключателей достаточно узнать свойство ItemIndex компонента RadioGroup. Для примера рассмотрим оба варианта: один – с обычной группой и 4 компонентами RadioButton, и другой – с компонентом RadioGroup и 4 строками, заданными в списке Items. В первом случае нам понадобится написать 4 строки кода:

If RadioButton1.Checked then Label1.Caption:="Вариант 1"; ... if RadioButton4.Checked then Label1.Caption:="Вариант 4";

Во втором же будет достаточно всего одной строки:

Label2.Caption:="Вариант "+IntToStr(RadioGroup1.ItemIndex+1);

Этот пример можно посмотреть в каталоге Demo\Part3\Groups.

Кроме свойств Items с надписями к переключателям, параллельно определяющим их количество, и ItemIndex, указывающего на выбранный элемент (если не выбран ни один вариант, то ItemIndex имеет значение -1), компонент RadioGroup имеет еще одно свойство – Columns. Оно отвечает за количество столбцов, по которым будет разделен список.


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

Система Delphi при добавлении новой формы в проект автоматически создает один экземпляр класса (Form1, Form2 и т. д.), внося соответствующие изменения в файл проекта, например, добавляя строку кода:

Управлять процессом автоматического создания форм можно, непосредственно редактируя файл проекта (не рекомендуется делать неопытным программистам) или выполняя настройки в окне параметров проекта (список Auto-create forms на странице Form). Если форма переведена из этого списка в список Available forms доступных форм проекта, то инструкция ее создания исключается из файла проекта, и программист в ходе выполнения приложения должен динамически создать экземпляр этой формы.

На данном скринште мы видим, что Form1 будет создана при запуске программы, а Form2 необходимо будет создать динамически при выполнении программы.

Метод Сreate

Для создания экземпляров форм служит метод (конструктор) Сreate . Сам класс формы обычно предварительно описывается при конструировании приложения, и для формы уже существуют файлы формы (dfm) и программного модуля (pas).

В вышеуказанной процедуре создается форма Form2 , принадлежащая объекту приложения и имеющая заголовок новая форма .

События формы (Form)

При создании и использовании формы генерируются следующие события типа TNotifyEvent, указанные в порядке их возникновения:

  1. OnCreate;
  2. OnShow;
  3. OnActivate;
  4. OnPaint.

Событие OnCreate

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

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

Приведем в качестве примера процедуру, обрабатывающую событие OnCreate формы Form2:

При создании форма получает новый заголовок пример формы, в комбинированный список ComboBox2 загружаются данные из файла list.txt , кнопка Button3 блокируется, а фокус ввода устанавливается на редактор Edit1.

Свойство Visible

Из всех созданных форм Delphi при выполнении приложения автоматически делает видимой главную форму, для этого свойство Visible этой формы устанавливается в значение True. Для остальных форм значение данного свойства по умолчанию равно False, и после запуска приложения они на экране не отображаются. Если формы создаются вручную, то их отображение и скрытие в процессе работы приложения регулируется программистом через свойство Visible. Даже если форма невидима, ее компонентами можно управлять, например, из других форм.

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

В вышеуказанных процедурах нажатие кнопок btnShowForm2 и btnHideForm2 , расположенных в форме Form1, приводит, соответственно, к отображению и скрытию формы Form2.

Методы Show и Hide

Управлять видимостью форм на экране можно также с помощью методов Show и Hide . Процедура Show отображает форму в немодальном режиме, при этом свойство Visible устанавливается в значение True, а сама форма переводится на передний план. Процедура Hide скрывает форму, устанавливая ее свойство Visible в значение False.

Если окно видимо, то вызов метода Show переводит форму на передний план и передает ей фокус ввода.

Пример отображения и скрытия формы:

Здесь нажатие кнопок btnShowForm3 и btnHideForm3 , расположенных В форме Form1, приводит соответственно к отображению на экране и удалению с экрана формы Form3.

В момент отображения формы на экране ее свойство visible принимает значение True, и возникает событие OnShow . Соответственно при скрытии формы свойство visible принимает значение False, и возбуждается событие OnHide .

События OnActivate и OnDeActivate

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

Событие OnPaint

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

Метод Сlose — закрывает форму

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

В вышеуказанной процедуре кнопка btnClose закрывает форму Form2 . Форма делается невидимой, но не уничтожается. Для этой кнопки полезно задать соответствующий заголовок (свойство Caption), например, Закрыть .

Процедура Close не уничтожает созданный экземпляр формы, и форма может быть снова вызвана на экран, в частности, с помощью методов Show или ShowModal .

Уничтожение формы (Release, Free или Destroy)

Уничтожение формы происходит с помощью методов Release , Free или Destroy , после чего работа с этой формой становится невозможна, и любая попытка обратиться к ней или ее компонентам вызовет исключение (ошибку). Необходимость уничтожения формы может возникнуть при оформлении заставок или при разработке больших приложений, требующих экономии оперативной памяти. Предпочтительным методом удаления формы считается метод Free, поскольку он предварительно проверяет возможность удаления. Например, в процедуре

В приведенной процедуре кнопка btnDestroy уничтожает форму Form3 . Для этой кнопки полезно задать соответствующий заголовок, например Удалить .

События при закрытии и уничтожении формы

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

  1. OnDeActivate;
  2. OnHide;

Событие OnCloseQuery

Событие типа TcloseQueryEvent возникает в ответ на попытку закрытия формы. Обработчик события получает логическую переменную-признак CanClose, определяющую, может ли быть закрыта данная форма. По умолчанию эта переменная имеет значение True, и форму можно закрыть. Если установить параметр CanClose в значение False, то форма остается открытой. Такую возможность стоит использовать, например, для подтверждения закрытия окна или проверки, сохранена ли редактируемая информация на диске. Событие OnCloseQuery вызывается всегда, независимо от способа закрытия формы.

Приведем в качестве примера процедуру закрытия формы:

Здесь при закрытии формы Form2 выдается запрос на подтверждение операции, который представляет собой модальное диалоговое окно с текстом и двумя кнопками - Yes и No . Нажатие кнопки Yes вызывает закрытие формы, при нажатии кнопки No закрытие формы не происходит.

Событие OnClose

Событие типа TCioseEvent возникает непосредственно перед закрытием формы. Обычно оно используется для изменения стандартного поведения формы при закрытии. Для этого обработчику события передается переменная Action типа TCloseAction, которая может принимать следующие значения:

  • caNone (форму закрыть нельзя);
  • caHide (форма делается невидимой);
  • caFree (форма уничтожается, а связанная с ней память освобождается);
  • caMinimize (окно формы сворачивается) - значение по умолчанию для MDI-форм.

При закрытии окна методом Close переменная Action по умолчанию получает значение caHide, и форма делается невидимой. При уничтожении формы, например, методом Destroy, переменная Action по умолчанию получает значение caFree, и форма уничтожается.

Событие возникает при закрытии формы щелчком мыши на кнопке закрытия системного меню или при вызове метода Close. Когда закрывается главная форма приложения, все остальные окна закрываются без вызова события OnClose.

В выше указанной процедуре при закрытии формы Form2 проверяется признак модификации содержимого редактора Memo1. Если информация в Memo1 была изменена, то форма не закрывается.

Событие onDestroy

Событие типа TNotifyEvent возникает непосредственно перед уничтожением формы и обычно используется для освобождения ресурсов.

Событие onResize

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

    procedure TForml. FormResize (Sender: TObject ) ; begin

    // Установка размеров и положения сетки строк

    StringGrid1. Left : = 10 ;

    StringGrid1. Top : = 5 ;

    StringGrid1. Width : = Form1. ClientWidth �— 20 ;

    StringGrid1. Height : = Form1. ClientHeight �— 15 ;

    Button1. Height ;

    // Установка положения кнопки

    Button1. Left : = Form1. ClientWidth �— 10�— Button1. Width ;

    Button1. Top : = Form1. ClientHeight - 5 - Button1. Height ;

    end ;

В форме Form1 находятся два компонента: сетка строк StringGrid1 и кнопка Button1. Эти компоненты расположены в форме следующим образом:

  • сетка StringGrid1 занимает всю ширину клиентской области формы Form3, отступы слева и справа составляют 10 пикселов;
  • кнопка Button1 (Закрыть) выровнена по правому краю сетки StringGrid1;
  • расстояния между сеткой, кнопкой, верхним и нижним краями формы составляют 5 пикселов.

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

Cвойство FormStyle — стиль формы

Стиль формы определяется свойством типа TFormstyle, принимающим следующие значения:

  • fsNormal (стандартный стиль, используемый для большинства окон, в том числе и диалоговых);
  • fsMDiChild (дочерняя форма в многодокументном приложении);
  • fsMDiForm (родительская форма в многодокументном приложении);
  • fsStayOnTop (форма, которая после запуска всегда отображается поверх других окон) - обычно используется при выводе системной информации или информационной панели программы.

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

Пример динамического изменения стиля формы:

При выборе пункта меню mnuTop форма переключает свой стиль между значениями fsNormal и fsStayOnTop . Смена стиля отображается графически галочкой в заголовке этого пункта меню.

Cвойство BorderStyle — свойства рамки формы

Каждая форма имеет ограничивающую рамку. Вид и поведение рамки определяет свойство типа TFormBorderstyle. Оно может принимать следующие значения:

  • bsDialog (диалоговая форма);
  • bsSingle (форма с неизменяемыми размерами);
  • bsNone (форма не имеет видимой рамки и заголовка и не может изменять свои размеры) - часто используется для заставок;
  • bsSizeable (обычная форма с изменяемыми размерами) - по умолчанию, имеет строку заголовка и может содержать любой набор кнопок;
  • bsToolwindow (форма панели инструментов);
  • bsSizeToolwin (форма панели инструментов с изменяемыми размерами).

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

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

Пример программного изменения размеров формы:

При нажатии кнопки btnResizeForm ширина формы Form2 увеличивается на 100 пикселов, даже если ее свойство BorderStyle имеет значение, равное bsDialog, bsSingle или bsNone.

Метод ShowModal

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

Cвойство BorderIcons

В области заголовка могут отображаться 4 вида кнопок. Реализуемый набор кнопок определяет свойство типа TBorderIcons, которое может принимать комбинации следующих значений:

  • blSystemMenu (окно имеет системное меню и может содержать кнопки системного меню);
  • blMinimize (окно содержит кнопку свертывания);
  • blMaximize (окно содержит кнопку развертывания/восстановления);
  • blHelp (окно содержит кнопку справки, которая отображает вопросительный знак и вызывает контекстно-зависимую справку).

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

Различные значения свойства не являются независимыми друг от друга. Так, если отсутствует системное меню, то ни одна кнопка не отображается. Если имеются кнопки развертывания и свертывания, то не отображается кнопка справки. Возможность появления кнопок также зависит от стиля формы. Например, отображение кнопок развертывания и свертывания возможно только для обычной формы и формы панели инструментов с изменяемыми размерами.

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

Форма включает в себя клиентскую и неклиентскую области. Неклиентская область занята рамкой, заголовком и строкой главного меню. Обычно эта область прорисовывается Windows и программистом не затрагивается. При необходимости изменить отображение в неклиентской области программист может перехватить и обработать сообщение WM_NCPaint .

Cвойства ClientWidth и ClientHeight

В клиентской области обычно размещаются различные элементы управления, выводится текст или отображается графика. Аналогично тому как свойства Width и Height определяют размеры всей формы, свойства ClientWidth и ClientHeight типа Integer задают ширину и высоту (в пикселах) клиентской части формы.

В вышеуказанной процедуре значения размеров клиентской области выводятся в заголовке формы.

Обычно форму перетаскивают мышью, указатель которой устанавливается в любом месте области заголовка. При необходимости можно переместить форму и при помещении указателя на ее клиентскую область, для чего требуется описать соответствующие операции программно. Одним из способов является перехват системного сообщения WM_NCHitTest . Для этого создается процедура FormMove , которая анализирует, в каком месте формы находится указатель мыши при нажатии кнопки. Код местоположения указателя мыши содержится в поле Result системного сообщения типа TMessage. Если значение Result равно 1, что соответствует нажатию кнопки мыши в клиентской области, то полю Result присваивается новое значение, равное 2, имитирующее нахождение указателя мыши в области заголовка. В процедуре FormMove первая инструкция inherited осуществляет вызов предопределенного обработчика перехватываемого события.

Чтобы указать среде Delphi, что процедура FormMove является обработчиком события WM_NCHitTest, при ее описании в классе формы TForm1 используется специальный синтаксис, включающий ключевое слово message . Как обработчик системного сообщения, процедура содержит один параметр типа TMessage.

Имена MoveForm и Msg процедуры и ее параметра могут быть изменены.

Свойство Menu

Отображаемое формой меню задается свойством Menu типа TMainMenu. При разработке приложения размещение компонента MainMenu главного меню в форме вызывает автоматическое присвоение значения MainMenu1 свойству Menu. Это самый простой способ ссылки на главное меню. Если в ходе выполнения приложения какая-либо форма должна отображать различные меню, то через свойство Menu можно указать другое главное меню, например, следующим образом: Form1.Menu:= MainMenu2;

Свойство Icon



Каждая форма отображает в левой стороне области заголовка свой значок, определяемый свойством Icon типа Ticon. Если форма не является главной в приложении, то этот значок отображается при свертывании формы. Для любой формы свойство Icon можно задать с помощью Инспектора объектов или динамически (при выполнении приложения). Если значок не задан, то форма использует значок, указанный в свойстве Icon объекта Application. Последний выводится также при свертывании и отображении в панели задач Windows значка главной формы приложения.

В вышеуказанной процедуре значок динамически загружается из файла Picture1.ico при создании формы Form1 .

Свойство Position

Размещение и размер формы при отображении определяет свойство типа TPosition. Оно может принимать значения, перечисленные далее:

  • poDesigned (форма отображается в той позиции и с теми размерами, которые были установлены при ее конструировании) - значение по умолчанию. Положение и размеры формы определяются свойствами Left, Tор, Width и Height . Если приложение запускается на мониторе с более низким разрешением, чем у того, на котором оно разрабатывалось, часть формы может выйти за пределы экрана;
  • poScreenCenter (форма выводится в центре экрана, ее высота и ширина- свойства Height и width- не изменяются);
  • poDefault (Windows автоматически определяет начальную позицию и размеры формы) - при этом значении программист не имеет возможности управлять этими параметрами, поэтому оно не допускается для форм многодокументных приложений;
  • poDefaultPosOnly (Windows определяет начальную позицию формы, ее размеры не изменяются);
  • poDefaultSizeOnly (Windows определяет начальные ширину и высоту формы и помещает форму в позицию, определенную при разработке);
  • PoDesktopCenter (форма выводится в центре экрана, ее высота и ширина не изменяются);
  • PoMainFormCenter (форма выводится в центре главной формы приложения, ее высота и ширина не изменяются) - это значение используется для вторичных форм, при применении его для главной формы оно действует как значение poScreenCenter;
  • PoOwnerFormCenter (форма выводится в центре формы, которая является ее владельцем, высота и ширина формы не изменяются) - если для формы не указан владелец (свойство Owner), то данное значение аналогично значению poMainFormCenter.

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

Свойство Active

Свойство Active типа Boolean позволяет определить активность формы. В любой момент времени активной может быть только одна форма, при этом ее заголовок выделяется особым цветом (обычно синим). Если свойство Active имеет значение True, то форма активна (находится в фокусе ввода), если False - то неактивна. Это свойство доступно для чтения во время выполнения программы. Если требуется активизировать форму программно, следует использовать свойство или метод Show (showModal).

Cвойство ChildActiveForm

В многодокументном приложении родительское окно не может быть активным независимо от цвета заголовка. Для определения активного дочернего окна многодокументного приложения служит свойство ChildActiveForm типа TForm родительской формы.

    procedure TForm1CheckFormActive модуля главной формы выполняет проверку активности для двух форм приложения и отображает соответствующую информацию в заголовках форм.

    Свойство WindowState

    Свойство типа TWindowstate определяет состояние отображения формы и может принимать одно из трех значений:

    • wsNormal (обычное состояние) - по умолчанию;
    • wsMinimized (свернута);
    • wsMaximized (развернута).

    Кнопки btnMiniForm и btnNormalForm в форме Form1 сворачивают и восстанавливают обычное состояние формы Form2 соответственно.

    Форма, для которой изменяется состояние отображения на экране, предварительно должна быть создана методами CreateForm или Create . Если форма не создана, то при обращении к ней будет сгенерировано исключение, несмотря на то, что переменная формы объявлена в модуле. Если форма создана, но не отображается на экране, то изменения ее состояния (свойства windowstate) происходят, однако пользователь не видит этого до тех пор, пока форма не будет отображена на экране.

    Свойство ActiveControl

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

    Эту же операцию выполняет метод SetFocus , который устанавливает фокус ввода для оконного элемента управления:

    Свойство AutoScroll

    В случае, когда размеры окна недостаточны для отображения всех содержащихся в форме интерфейсных компонентов, у формы могут появляться полосы прокрутки. Свойство AutoScroll типа Boolean определяет, появляются ли они автоматически, Если свойство AutoScroll имеет значение True (по умолчанию), то полосы прокрутки появляются и исчезают автоматически, без каких-либо действий программиста. Необходимость в полосах прокрутки может возникнуть, например, в случае, если пользователь уменьшит размеры формы так, что не все элементы управления будут полностью видны. Если же свойство AutoScroll установлено в значение False, то программист реализует управление просмотром информации вручную через свойства HorzScrollBar (горизонтальная прокрутка) и VertScrollBar (вертикальная прокрутка) типа TControlScrollBar формы.

    Метод ScrollInView

    Для программного управления полосами прокрутки можно использовать метод ScrollInView . Процедура ScrollInView (AControl: TControl) автоматически изменяет позиции полос прокрутки так, чтобы заданный параметром AControl элемент управления стал виден в отображаемой области.

    Свойство KeyPreview

    Свойство типа Boolean определяет, будет ли форма обрабатывать события клавиатуры, прежде чем их обработают элементы управления формы. Если свойство имеет значение False (по умолчанию), то клавиатурные события поступают к активному элементу управления (имеющему фокус ввода). При установке свойства KeyPreview в значение True форма первой получает сообщения о нажатии клавиш и может на них реагировать, что обычно используется для обработки комбинаций клавиш, независимо от активности элементов управления формы.

    В вышеуказанной процедуре форма Form1 обрабатывает нажатие алфавитно-цифровых клавиш, отображая введенный символ в диалоговом окне Information .

    Форма не может обрабатывать нажатие клавиши <ТаЬ> в связи с ее особым назначением.

    Cвойство MDichildCount и метод Cascade

    У формы имеется ряд свойств и методов , например свойство MDichildCount и метод Cascade , предназначенных для организации многодокументных приложений.