| ||||||||||||||||
![]() | ||||||||||||||||
| ||||||||||||||||
![]() | ||||||||||||||||
| ||||||||||||||||
![]() |
Теперь вернемся к тому странному факту, что мутаторы объявлены как private.Здесь мы пользуемся расширением фирмы Борланд в C++, ключевым словом __published. Все свойтва объекта, которыми планируется манипулировать визуально, должны быть объявлены как __published, а аксессоры и мутаторы подключаются к ним с помощью следующего синтаксиса: Добавьте три свойства в секции __published, и класс будет выглядеть примерно так: __published: __property bool LEDOn = {read = FOnOff, write = SetOnOff}; __property TColor OnColour = {read = FOnColour, write = SetOnColour}; __property TColor OffColour = {read = FOffColour, write = SetOffColour}; Все объявления свойств начинаются с ключевого слова __property, затем следуют тип переменной (свойства), и объявления членов доступа к свойству. Интересно, что read указывает на переменную, а write на функцию. И read, и write могут указывать и на функцию, и на переменную, но обычно делают так, чтобы write указывал на функцию, в которой есть некоторые проверки правильности значений и т.д. Имя свойства может не иметь ничего общего с именем переменной, которую оно модифицирует (например, переменная FOnOff модифицируется свойством LEDOn). Хотя рекомендуется использовать стандартные соглашения имен - имя свойства должно быть таким же, как и имя связанной с ним переменной, за исключением префикса F в начале. Это все, что нам нужно изменить в файле заголовка класса. Хотя введение свойств может показаться инородным, может быть, даже кощунственным для старых программистов C++, но если вы хотите полностью использовать новые возможности C++Builder, вы вынуждены будете использовать свойства. Замечание:Следующий параграф описывает значения по умолчанию, и если вы нетерпеливы, то можете перейти к следующей странице. У свойтва может быть значение default, то есть - __property bool LEDOn = {read=FOnOff, write=SetOnOff, default=false}; Это значение НЕ то, что видно по умолчанию в object inspector (их вы должны задать в конструкторе компонента, мы займемся этим позже). Тут заложен другой смысл. Каждый раз при добавлении компонента на форму, Билдер сохраняет информацию о нем в файле .DFM. Так как все свойства компонента определяют, как он будет выглядеть, где будет на форме и так далее, они просто сохраняются в двойчном .DFM-файле на диске. Значение по умолчанию, которое вы присваиваете компоненту, будет определять, будет ли свойство сохраняться в .DFM-файле или нет. Если значение свойства на форме совпадает со значением по умолчанию, оно НЕ будет сохраняться, а если оно другое, то сохранится. Свойства могут быть объявлены с ключевым словом nodefault: __property bool LEDOn = {read=FOnOff, write=SetOnOff, nodefault}; Это означает, что они ВСЕГДА будут сохраняться. Также имеется атрибут stored. Вы можете переопределить сохраняющие действия Билдера по умолчанию с помощью него. Если вы установите stored в true, свойтво всегда будет сохраняться, если в false - никогда не будет сохраняться. Кроме того, вы можете определить его с помощью метода, возвращающего логическое значение (в нижеприведенном примере функция check возвращает булево значение). __property bool LEDOn = {read=FOnOff, write=SetOnOff, stored=true}; __property bool LEDOn = {read=FOnOff, write=SetOnOff, stored=false}; __property bool LEDOn = {read=FOnOff, write=SetOnOff, stored=Check}; Последний атрибут, который имеет свойство - это index. Он полезен, когда нужно иметь несколько аксессоров и мутаторов с дублирующимся кодом. Вместо того, чтобы писать несколько отдельных функций, можно написать одну с использованием index. Чтобы его использовать, нужно добавить соответствующее ключевое слово в объявление свойства, и индекс будет первым элементом, который передается вашему аксессору/мутатору. Например: __property TColor OnColour = {read=FOnColour, write=SetOnOffColour, index=1}; __property TColor OffColour = {read=FOffColour, write=SetOnOffColour, index=2}; И реализация функции SetOnOffColour должна выглядеть примерно так: void __fastcall TLED::SetOnOffColour(int Index,TColor Colour) { switch(Index) { case 1 : FOnColour = Colour; break; case 2 : FOffColour = Colour; break; } Brush->Color = (FOnOff)?FOnColour:FOffColour; } |
|
![]() | ||||||||||||||||
| ||||||||||||||||
![]() | ||||||||||||||||
|