Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы Мартын 1(ComCorbaLab2004).doc
Скачиваний:
30
Добавлен:
10.02.2016
Размер:
1.81 Mб
Скачать

2.3. Значения по умолчанию

У свойтва может быть значение 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;

}

Вот как должен выглядеть файл LED.h:

//---------------------------------------------------------------------------

#ifndef LEDH

#define LEDH

//---------------------------------------------------------------------------

#include <SysUtils.hpp>

#include <Controls.hpp>

#include <Classes.hpp>

#include <Forms.hpp>

#include <ExtCtrls.hpp>

//---------------------------------------------------------------------------

class PACKAGE TLED : public TShape

{

private:

bool FOnOff;

TColor FOnColour;

TColor FOffColour;

void __fastcall SetOnOff(const bool Value);

void __fastcall SetOnColour(const TColor OnColour);

void __fastcall SetOffColour(const TColor OffColour);

protected:

public:

__fastcall TLED(TComponent* Owner);

__published:

__property bool LEDOn = {read = FOnOff, write = SetOnOff};

__property TColor OnColour = {read = FOnColour, write = SetOnColour};

__property TColor OffColour = {read = FOffColour, write = SetOffColour};

};

//---------------------------------------------------------------------------

#endif

2.4. CPP - файл

Самая трудная часть позади. Легкая часть - написание .cpp файла. Сначала будет написан код мутаторов:

//---------------------------------------------------------------------------

void __fastcall TLED::SetOnOff(const bool Value)

{

FOnOff = Value; // Set the state of FOnOff

Brush->Color = (FOnOff)?FOnColour:FOffColour;

}

//---------------------------------------------------------------------------

void __fastcall TLED::SetOnColour(const TColor OnColour)

{

FOnColour = OnColour;

Brush->Color = (FOnOff)?FOnColour:FOffColour;

}

//---------------------------------------------------------------------------

void __fastcall TLED::SetOffColour(const TColor OffColour)

{

FOffColour = OffColour;

Brush->Color = (FOnOff)?FOnColour:FOffColour;

}

//---------------------------------------------------------------------------

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

__fastcall TLED::TLED(TComponent* Owner)

: TShape(Owner)

{

Width = 15; // Установим ширину нашего LED в 15.

Height = 15; // Установим высоту нашего LED в 15.

FOnColour = clLime; // Установим OnColour лимонно-зеленым.

FOffColour = clRed; // Установим OffColour красным.

FOnOff = false; // Сосотояние по умолчанию - выключено

Shape = stEllipse; // Форма по умолчанию - эллипс

Pen->Color = clBlack; // Цвет пера - черный

Pen->Width = 1; // Толщина пера 1

Brush->Color = FOffColour; // Цвет кисти одинаков с цветом по умолчанию

}

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

Существует несколько способов инициализации переменных в конструкторе. Вышеприведенный пример можно было написать и так:

__fastcall TLED::TLED(TComponent* Owner)

: TShape(Owner),

FOnColour(clLime), // установить OnColour в лимонно-зеленый

FOffColour(clRed) // установить OffColour красным

{

Width = 15; // Установим ширину нашего LED в 15.

Height = 15; // Установим высоту нашего LED в 15.

Shape = stEllipse; // Форма по умолчанию - эллипс

Pen->Color = clBlack; // Цвет пера - черный

Pen->Width = 2; // Толщина пера 2

Brush->Color = FOffColour; // Цвет кисти одинаков с цветом по умолчанию

}

Можно и так:

__fastcall TLED::TLED(TComponent* Owner)

: TShape(Owner), FOnColour(clLime), FOffColour(clRed), Width(15),

Height(15), Shape(stEllipse), Pen->Width(2),Brush->Color(FOffColour)

{}

Важно понимать, что fOnOff инициализировать не обязательно, так как тип bool имеет встроенное значение по умолчанию(false), в отличие от большинства простых типов C++, которые автоматически не инициализируются. Тем не менее, считается хорошим стилем инициализировать значения всех свойств.

Теперь, когда написан этот небольшой компонент, можно убедиться, что все работает. Сначала сохраняется проект (File | Save All). Затем добавляется модуль LED, который только что создан, к тестовому проекту. Чтобы это сделать, выберается (Project | Add to Project) и находится led.cpp (по умолчанию сохраненный в папку lib в v3 и v4). Потом вводится #include "LED.h" вверху LEDForm.h:

#include <vcl\Classes.hpp>

#include <vcl\Controls.hpp>

#include <vcl\StdCtrls.hpp>

#include <vcl\Forms.hpp>

#include "LED.h"

Теперь добавляется в секцию private файла LEDForm.h:

private: // User declarations

TLED* LED1;

После этого выполняется возврат на форму LEDForm, выберается событие OnCreate в object inspector и вводится следующий код в тело функции:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

LED1 = new TLED(this);

LED1->Parent = this;

LED1->Left = (Width/2)-(LED1->Width/2);

LED1->Top = (Height/2)-(LED1->Height/2);

}

Этот код динамически создает новый компонент TLED и помещает его в центр экрана (если динамически создается компонент, надо задать все значения вручную). Очень важно также запомнить, что в этом случае необходимо задать свойство Parent компонента! Теперь выберается событие OnClick кнопки:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

LED1->LEDOn = !LED1->LEDOn;

}

Теперь самое время нажать волшебную кнопку Run. Программа должна выглядеть так (рис. 2.2.):

Рис. 2.2. Кнопка Run “LED Change”

Щелкая кнопку, можно менять цвет индикатора с красного на зеленый с черным и обратно. Компонент польностью готов, и единственное, что осталось - инсталлировать его в палитру. В версии 3 и выше предварительно надо еще и создать пакетную библиотеку (пакедж).

Прежде чем добавить компонент в палитру, нужно разработать для него иконку (стандартная иконка слишком неинформативна) с помощью утилитки Image Editor (Tools | Image Editor) (если нет желания делать иконку для компонента, можно пропустить этот материал).

C++Builder v3 or later

Необходимо выбрать (File|New|Resource), щелкнуть правой клавишей на ветке дерева "Contents" и выбрать (New | Bitmap). В появившемся диалоге надо выбрать высоту и ширину 24 и VGA(16 colours), затем "OK". После этого следует переименовать иконку в LED (кликнув правой клавишей), и после этого дважды кликнуть на ней. Теперь можно нарисовать иконку. После этого надо выбрать (File | Save), сохранить файл ресурса в ту же папку, что и файл LED.cpp (папка lib по умолчанию), под именем LED.res (см. рис. 2.3.).

C++Builder v1

Необходимо выбрать (File | New | Bitmap), в диалоге выбрать высоту и ширину в 24, VGA (16 colours), щелкнуть "OK". Далее выбрать (Resource | Rename), назвать битмап TLED. Дважды кликнув, создать рисунок. Далее, (File | Save As) и сохранить файл ресурса в ту же папку, что и файл LED.cpp под именем LED.res.

Рис. 2.3. Создание иконки

Теперь можно инсталлировать компонент.

Теперь все готово к инсталляции компонента. Процедура сильно отличается в зависимости от того, какая версия Билдера используется.

Инсталляция в C++Builder v1

Процедура инсталляции разработанного компонента ничем не отличается от процедуры инсталляции любого другого. Сначала последний вызывает (File | Save All), затем выбирается (Component | Install) из главного меню C++Builder. Появится диалогInstallComponents, где надо нажать кнопкуAdd, и затем (из диалогаAddModule) нажать кнопкуBrowse. После выбираетсяLED.cppв диалогеAddComponent, и наконец нажимается кнопка "OK" в диалогеInstallComponents. C++Builder скомпилирует и подлинкует компонент, а затем добавит его в палитру.

Инсталляция в C++Builder v3 или старше

В C++Builder v3 Borland впервые ввела пакетные библиотеки (пакеджи). Компоненты теперь сначала компилируются в пакедж, который потом инсталлируется. Этим обеспечивается разделение компонентного кода между приложениями (через BPL, которые представляют собой особый вид DLL).

Сначала сохраняется все (File | Save All), затем закрываются все файлы (File | Close All). Теперь выбирается (Component | Install Component), далее выбирается "Into new package" и подключается файл LED.cpp. Необходимо назначить имя для пакеджа (оно должно отличаться от имени компонента) - например, LEDPack, и потом можно, если потребуется, ввести краткое описание пакеджа. Далее надо щелкнуть "OK". C++Builder спросит подтверждение того, что инсталлируется компонент, после этого скомпилирует и установит компонент.