1. Общий синтаксис объявления свойства

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

Однако у них есть существенные отличия, о которые необходимо сказать несколько слов.

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

Для того чтобы увидеть файл формы в текстовом виде с помощью Delphi необходимо в редакторе формы правой кнопкой мыши вызвать всплывающее меню и выбрать пункт меню «View as Text». Тот же эффект имеет нажатие сочетания клавиш <Alt+F12>.

Пример 2.1. Пример файла формы

         object Form1: TForm1
         Left = 280
         Top = 110
         Width = 696
         Height = 480
         Caption = 'Form1'
         Color = clBtnFace
         Font.Charset = DEFAULT_CHARSET
         Font.Color = clWindowText
         Font.Height = -11
         Font.Name = 'MS Sans Serif'
         Font.Style = []
         OldCreateOrder = False
         PixelsPerInch = 96
         TextHeight = 13
         object Button1: TButton
         Left = 144
         Top = 56
         Width = 75
         Height = 25
         Caption = 'Button1'
         TabOrder = 0
         end
         end
       

Реальная необходимость в ручном редактировании файла формы возникает крайне редко, но если уж возникает, то без него не обойтись. Например, вы разместили на форме компонент некоторого класса (к примеру, кнопку класса TSpeedButton), подписали ее, настроили ее положение, определили обработчики событий. Затем вы пришли к выводу, что форма будет модальной, а кнопка – возвращать значение ModalResult, а у TSpeedButton такого свойства нет. Что же делать? Выход один – сменить класс кнопки, для этого нужно кнопку TSpeedButton удалить и из палитры компонентов поставить новую класса TButton, у которой есть свойство ModalResult.

Но кнопка у нас так хорошо настроена и нам очень не хочется настраивать ее заново. Как бы сменить ее тип? Очень просто – открываем файл формы, находим декларацию кнопки и вручную меняем тип. Главное при этом не ошибиться в имени класса, иначе мы просто потеряем компонент!

Примечание

Может возникнуть вопрос: «А куда же помещается файл формы после компиляции программы в исполняемый EXE-файл?» Он помещается в ресурс типа RCDATA и используется программой для инициализации объекта формы при ее создании.

Перейдем непосредственно к синтаксису объявления свойств.

Пример 2.2.

         property Active: boolean read FActive write SetActive;
       

Свойство объявляется с использованием ключевого слова property. Далее следует название свойства, уникальное для данного класса, и после двоеточия - тип. Затем с ключевыми словами read и write указываются методы (или непосредственно поля) чтения и записи соответственно. Если свойство только для чтения, то указывается только метод чтения после слова read.

Внимание

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

Совет

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

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

Директива stored явно указывает, сохранять ли значение свойства в файле формы или нет. За директивой stored должны следовать либо константы True или False, либо имя логического (Boolean) поля, либо метода-функции без параметров, возвращающего значения типа Boolean.

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

Пример 2.3.

         property Active: boolean read FActive write SetActive default True;
       

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

Если значение свойства равно значению по умолчанию и параметр stored равен False, то оно не сохраняется в файле формы, а если отличается - сохраняется.

Убедимся в этом. Просмотрим файл формы, как это было показано ранее. В файле перечислены значения явно не всех свойств формы, а лишь тех, которые либо не имеют значений по умолчанию, либо значение свойство отличается от значения по умолчанию. Изменим значения какого-либо свойства, которое в Инспекторе объектов не выделено шрифтом. Например, AlphaBlend, управляющего полупрозрачностью формы. Еще раз посмотрим на файл формы и убедимся, что теперь значение свойства занесено в файл формы.

Совет

Из этого простого эксперимента следует важный вывод - следует по возможности всегда указывать значение свойств по умолчанию с помощью директивы default – это уменьшит не только размеры файла формы, но и ресурса RCDATA, а значит и готового приложения.

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

Внимание

К сожалению, директивы default и nodefault работают не со всеми типами свойств. Они действуют только по отношению к порядковым типам и множествам, нижняя и верхняя границы которых находятся в интервале 0..31. Для вещественных типов, указателей и строковых типов значение по умолчанию может быть 0, nil и ‘’ (пустая строка) соответственно.

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

Перейдем к рассмотрению особенностей объявления и работы со свойствами различного типа.