// Закрытые элементы-данные класса bool FEnableNum;
bool FEnableLet; bool FModified; } ;
Теперь надо объявить свойства — методы чтения и записи этих полей.
Свойство объявляется оператором вида:
__property <тип> <имя> = {read=<имя поля или метода чтения> write=<имя поля или метода записи> <директивы запоминания и значения по умолчанию>;
Если в разделах read или write записано имя поля, значит,
предполагается прямое чтение или запись данных.
Если в разделе read записано имя метода чтения, то чтение будет осуществляться только функцией с этим именем. Функция чтения — это функция без параметра, возвращающая значение того типа, который объявлен для свойства. Имя функции чтения принято начинать с префикса
Get, после которого следует имя свойства.
Если в разделе write записано имя метода записи, то запись будет осуществляться только процедурой с этим именем. Процедура записи — это процедура с одним параметром того типа, который объявлен для свойства. Имя процедуры записи принято начинать с префикса Set, после которого следует имя свойства.
Если раздел write отсутствует в объявлении свойства, значит это свойство только для чтения и пользователь не может задавать его значение.
Директивы запоминания определяют, как надо сохранять значения свойств при сохранении пользователем файла формы *.dfm. Чаще всего используется директива
default = <значение по умолчанию>
Она не задает начальные условия. Это дело конструктора. Директива просто говорит, что если пользователь в процессе проектирования не изменил значение свойства по умолчанию, то сохранять значение свойства не надо.
Итак, для нашего примера объявления свойств могут иметь вид: public:
__fastcall TEditLetNum(TComponent* Owner); // Свойство только времени выполнения
__property bool Modified = {read=FModified, default=false}; __published:
// Свойства компонента, включаемые в Инспектор Объектов
__property bool EnableLet = {read=FEnableLet, write=SetEnableLet, default=true};
__property bool EnableNum = {read=FEnableNum, write=SetEnableNum, default=true};
Объявление свойства Modified помещается в раздел public, поскольку это свойство должно быть доступно только во время выполнения.
Свойства EnableNum и EnableLet помещаются в раздел published, так как они должны отображаться в Инспекторе Объектов во время проектирования.
Свойства EnableNum и EnableLet имеют прямой доступ к полям для чтения. Но для записи они имеют методы SetEnableNum и SetEnableLet
соответственно. Это связано с тем, что при записи свойств надо проверять,
не окажутся ли значения обоих этих свойств равными false. Подобное задание значений надо предотвращать, поскольку в этом случае в окно редактирования вообще ничего нельзя будет ввести.
Свойство Modified вообще не имеет метода записи, поскольку оно предназначено только для чтения.
Указанные в объявлениях методы записи могут быть реализованы обычными функциями, объявления которых помещаются в private —
закрытый раздел класса, а их реализация включается в тело модуля. Для того чтобы задать свойствам начальные значения, надо еще включить соответствующие операторы в тело конструктора. В итоге в данный момент модуль компонента может иметь следующий вид.
Файл EditLetNum.h:
class PACKAGE TEditLetNum : public TEdit
{
private:
// Закрытые элементы-данные класса
bool FEnableLet; bool FEnableNum; bool FModified; protected:
// Защищенные методы записи
void __fastcall SetEnableLet{bool AEnableLet); void __fastcall SetEnableNum(bool AEnableNum);
public:
// Объявление конструктора
__fastcall TEditLetNum(TComponent* Owner); // Свойство только времени выполнения
__property bool Modified = {read=FModified, default=false}; _ published:
// Свойства компонента, включаемые в Инспектор Объектов
__property bool EnableLet = {read=FEnableLet, write=SetEnableLet, default=true};
__property bool EnableNum = {read=FEnableNum, write=SetEnableNum, default=true};
} ;
Файл EditLetNum.cpp:
static inline void ValidCtrCheck(TEditLetNum *) {
new TEditLetNum(NULL);
}
//--------------------------------------------------------------------
__fastcall TEditLetNum::TEditLetNum(TComponent* Owner) : TEdit(Owner)
{
FEnableLet = true;
FEnableNum = true;
FModified = false;
}
//--------------------------------------------------------------------
namespace Editletnum {
void _ fastcall PACKAGE Register()
{
TComponentClass classes[l] = {__classid{TEditLetNum)); RegisterComponents{"MyComponents", classes, 0);
}
}
//--------------------------------------------------------------------
void __fastcall TEditLetNum::SetEnableNum(bool AEnableNum)
{
//Присваивание значения полю FEnableNum FEnableNum = AEnableNum;
//Если значения FEnableNum и FEnableLet = false,
//то полю FEnableLet присваивается true if(!AEnableNum)
if(!FEnableLet) FEnableLet = true;
}
//---------------------------------------------------------------------------------------
void __fastcall TEditLetNum:: SetEnableLet(bool AEnableLet)
{
//Присваивание значения полю FEnableLet FEnableLet = AEnableLet;
//Если значения FEnableNum и FEnableLet = false,
//то полю FEnableNum присваивается true if(!AEnableLet)
if(!FEnableNum) FEnableNum = true;
}
Процедуры, реализующие методы записи, присваивают полю переданное в них значение параметра и в случае, если передано значение false, проверяют значение другого поля. Если и другое поле имеет значение false, то оно исправляется на true.
Объявления процедур записи включены в раздел protected. Это означает, что они закрыты для внешнего пользователя, но доступны для возможных потомков вашего класса.
Конструктор объявлен в открытом разделе класса public и имеет имя
TEditLetNum, совпадающее с именем класса. В реализации конструктора задаются начальные значения новым свойствам, которые вы добавили в компонент.
Теперь давайте сохраним подготовленные файлы, откомпилируем их
(кнопка Compile в Диспетчера Пакетов) и построим тестовое приложение для отладки установленного компонента. Хотя он еще не до конца создан,
кое-что уже можно увидеть.
Откройте новый проект и внесите в него с соответствующей страницы библиотеки ваш новый компонент. Откройте (командой File | Open) файл вашего компонента, чтобы можно было вносить в него какие-то изменения. Сохраните проект под каким-нибудь именем (например,