6.7.4 Регистрация компоненты Перед тем как ваша компонента сможет работать на стадии проектирования приложения, C++Builder должен зарегистрировать ее. При регистрации становится известным положение новой компоненты в Палитре компонент C++Builder. Регистрация компоненты - это простой процесс, который информирует C++Builder о том, какая компонента добавляется к VCL и на какой вкладке Палитры она должна появиться. Чтобы зарегистрировать компоненту: 1. Добавьте функцию Register к файлу МуСоmр.срр, заключив ее имя в пространство имен (заметьте, что название пространства имен начинается с заглавной буквы, а все остальные буквы - прописные). 2. В теле функции Register объявите массив типа TComponentClass, в который введите регистрируемую компоненту. 3. В теле функции Register вызовите функцию RegisterComponents стремя параметрами: название вкладки Палитры компонент, массив компонентных классов и размер компонентных классов. namespace Mycomp Листинг 6.13. Регистрация компоненты. Листинг 6.13 представляет включение в файл МуСоmр.срр кода для регистрации компоненты TMyComponent на вкладке Samples Палитры компонент. Когда компонента зарегистрирована, вы можете испытать и инсталлировать ее на Палитру, завершая тем самым процесс разработки новой компоненты. 6.7.5 Отладка неинсталлированной компоненты Вам следует испытать поведение созданной компоненты при выполнении программы до ее инсталляция на Палитру. По существу, вам придется смоделировать те действия, которые производит C++Builder, когда пользователь перемещает компоненту из Палитры на форму. Этот процесс требует выполнения следующих шагов: 1. Включите файл модуля MyComp.h вашей компоненты в заголовочный файл некоторой формы. 2. Добавьте объектный член данных, представляющий испытываемую компоненту, в конец секции public объявлений класса формы, вне области объявлений, которые делает C++Builder. 3. Подсоедините обработчик к событию OnCreate формы. 4. Вызовите конструктор компонентного объекта (компонента отвечает за самоуничтожение, когда наступит время) из обработчика этого события, передав ему параметр, указывающий на владельца компоненты. Обычно параметром служит указатель this на объект, который содержит этот метод. В нашем примере параметр this ссылается на форму. 5. Сразу же за вызовом конструктора установите свойство Parent - родителя
компоненты, обычно представляющего собой форму, группирующую рамку или
панель инструментов. Обычно значением этого свойства является указатель
this. 6. Инициируйте значения других свойств компоненты. Предположим, вы собираетесь испытать компоненту TMyComponent в модуле с именем МуСоmр. Создайте новый проект, а затем следуйте перечисленным шагам процесса подготовки модуля формы. Листинг 6.14 содержит законченный образец текста модуля формы отлаживаемой компоненты. #ifndef TestFormH //--------------------------------- #include <Classes.hpp> //--------------------------------- class TForm1 : public TForm private: public: //--------------------------------- extern TForm1 *Form1; //--------------------------------- #endif // Это файл MyComp.cpp модуля формы: #include <vcl.h> #pragma resource "*.dfm" TForm1 *Form1; //-------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) Листинг 6.14. Текст модуля формы новой компоненты. 6.7.6 Инсталляция компоненты на Палитру Компонентные модули, написанные на C++, имеют расширение .срр, а компоненты, написанные на Объектном Паскале, имеют расширение .pas. При инсталляции новой компоненты или при выполнении команды Component | Rebuild Library, Библиотека Визуальных Компонент перестраивается, и C++Builder создает временный файл CMPLIB32.CPP исходных текстов VCL. Чтобы сохранить этот файл, с помощью команды Options | Environment | Library откройте диалог опций и установите флаг Save Library Source Code. Чтобы добавить к VCL компоненту, выполните следующие шаги: 1. С помощью команды Component | Install откройте диалоговое окно инсталляции компонент. 2. Нажмите кнопку Add, которая открывает диалог добавления модуля. Введите имя модуля непосредственно в поле Module Name или найдите его местоположение, нажав на кнопку поиска Browse. Имя добавленного вами компонентного модуля появится внизу списка названий группы Installed Components. В списке Component classes вы увидите имена компонентных классов, уже находящихся в выбранной группе Библиотеки. У вновь введенного модуля имя компонентного класса отсутствует. 3. Нажмите кнопку ОК, закрывая диалог инсталляции компонент. Библиотека будет перестроена и новая компонента установлена на ту вкладку Палитры, которую вы определили как параметр функции регистрации (см. Листинг 6.13). Чтобы удалить компоненту из VCL, выполните следующие шаги: 1. Выполните команду Component | Install, которая открывает диалоговое окно установки компонент. 2. Найдите ненужный вам более компонентный класс в списке Component classes выбранной группы Библиотеки и нажмите кнопку Remove. 3. Нажмите кнопку ОК. Библиотека будет перестроена и новая компонента удалена из Палитры. Чтобы перестроить Палитру, выполните следующие шаги: 1. Откройте диалог установки опций Палитры с помощью команд Component | Configure Palette или Options | Environment | Palette. 2. Нажмите кнопку Add и выберите имя для новой вкладки. Имя добавленной вами вкладки появится внизу списка Pages названий вкладок. 3. Перетащите мышью выбранную компоненту в списке Components на нужную вкладку списка Pages. 4. Нажмите кнопку ОК. Библиотека и Палитра будут перестроены. 6.7.7 Сохранение файлов новой компоненты Когда вы закончите процесс разработки, созданная компонента будет представлена следующими файлами: • объектный файл результата компиляции MyComp.obj; • заголовочный файл объявлений, сгенерированный компилятором (MyComp.h для исходного текста на C++ или MyComp.hpp для исходного текста на Объектном Паскале); • файл битового образа Палитры (MyComp.res или MyComp.dcr); • файл формы MyComp.dfm, если компонента использует форму. Перед тем, как использовать вновь созданную компоненту, перепишите в каталог \.. .\CBuilder\LIB\OBJ следующие файлы компоненты МуСоmр: все двоичные файлы (с расширениями .dfm, .res и .dcr), все исходные файлы (с расширениями .срр или .pas), все объектные файлы (с расширениями .obj и .Но) и все заголовочные файлы (с расширениями .h или .hpp). Желательно создать и сохранить контекстно-справочный файл (с расширением .hip). 6.8 Разработка простой компоненты Перед тем, как приступить к разработке новой компоненты, вы должны заранее четко представить себе, что точно она должна делать и как будет реализовано ее оригинальное поведение. Удостоверьтесь, что ни одна из имеющихся компонент не обладает требуемыми вами способностями. Поскольку в cтaндapтнoм варианте поставки C++Builder отсутствует Инструкция по написанию компонент и исходные тексты VCL, пришлось заимствовать элементарное руководство Криса Эриксона, которое я скачал по сети Internet. Его компонента моделирует бинарный индикатор, который меняет цвет при изменении состоянии. Пока очевидно только, что некоторое свойство компоненты будет хранить текущее состояние (true, если индикатор включен, и false - в противном случае). Из данной главы мы уяснили, что желательно выбрать для наследования наиболее близкий в иерархии VCL базовый компонентный класс; очевидно, что индикатор представляет собой графическую компоненту семейства TGraphicControl. Поскольку мы разрабатываем "ну очень простую" компоненту, пусть она будет иметь тривиальную форму окружности, а не более хитроумный битовый образ. На первый взгляд, компонента TShape из вкладки Палитры Additional выглядит ближайшим родственником. При внимательном рассмотрении TShape имеет больше свойств и событий, чем нам требуется, хотя и обладает всей нужной функциональностью. Внимание: Вы не сможете удалить свойства или события из базовой компоненты, а только подняться выше по иерархии объектов на пути к общему предку TComponent. Это означает, что выбрав слишком далекого предшественника, вы рискуете запутать потенциального пользователя (да и самого себя тоже) обилием избыточных свойств и событий, которые по сути не нужны вашей компоненте. Напротив, выбрав слишком близкого предшественника, вам придется самостоятельно и полностью программировать функциональное поведение своей компоненты. Итак, все что мы хотим изменить при наследовании от TShape - это форму; индикатора и цвет кисти при его переключении. Звучит достаточно просто. Поcле того, как мы точно сформулировали, что будет делать создаваемая компонента, настало время перейти к ее фактической разработке. 6.8.1 Форма тестового приложения Пока мы не убедились, что разрабатываемая компонента работает надлежащим образом (а это может занять много времени даже с простейшим элементом управления), ее нельзя включать в VCL. Сначала следует создать тестовое приложение с прототипом новой компоненты LED: => С помощью команды File | New Application создайте пустую форму. => Разместите кнопку TButton на форме. => С помощью команды File | Save All сохраните форму и проект приложения в файлах под именами LEDForm.cpp и LEDProj.mak. 6.8.2 Модуль тестового приложения Мастер компонент (Component Wizard) упрощает начальные шаги создания компоненты. Мастер не может автоматически добавлять компоненту к существующему модулю, вам придется проделать это вручную. => Выполните команду Component | New и в открывшемся диалоге Мастера компонент заполните поля диалога указанными значениями (Рис. 6.9). Нажмите кнопку ОК. Рис. 6.9. Диалог Мастера компонент. => С помощью команды File | Save или File | Save As сохраните файл Unit1.cpp под именем LED.cpp. Теперь можно посмотреть в окне Редактора кода, что сделал C++Builder для подготовки нашей компоненты. Файл LED.h будет содержать объявление нового компонентного класса с конструктором, а также несколько заголовочных файлов предкомпиляции. Файл LED.cpp будет содержать пустой конструктор объекта и функцию Register для регистрации компоненты. Не слишком много для автоматизированного начала... 6.8.3 Члены данных, свойства и методы Ознакомившись с заготовками программного модуля компоненты, которые создал для нас C++Builder, можно приступить к написанию собственно кода компоненты. Прежде всего, в файле LED.h опишем булеву переменную состояния индикатора и две переменные перечисляемого типа TColor для хранения цветов, отображающих оба состояния. Из главы 3 об основах объектно-ориентированного программирования мы знаем как ограничивать область видимости и уяснили, что эти члены данных следует спрятать в секции private объявлений класса. Там же расположим прототипы функций записи соответствующих свойств, а сами свойства объявим в секции _published (Листинг 6.15). //-------------------- #ifndef LEDH //-------------------- #include <vcl\SysUtils.hpp> //------------------------------ class TLED : public TShape protected: public: published: //---------------------- #endif Листинг 6.15. Добавления в файл LED.h модуля компоненты. Еще проще окажутся добавления в файл LED.cpp (Листинг 6.16). Необходимо написать три функции для присвоения значений свойств соответствующим членам данных, а также наполнить конструктор компоненты инструкциями для инициализации переменных. #include <vcl\vcl.h> //----------------------- static inline TLED *ValidCtrCheck() void _fastcall TLED::SetOnOff(const bool Value) //-------------------- void _fastcall TLED::SetOnColor(const TColor OnColor) //-------------------- void _fastcall TLED::SetOЈfColor(const TColor OffColor) //------------------- _fastcall TLED::TLED(TComponent* Owner) : TShape(Owner) //------------------------ namespace Led Листинг 6.16. Добавления в файл LED.cpp модуля компоненты. Установленные конструктором значения членов данных по умолчанию па вятся в окне Инспектора объектов при создании объекта индикатора. Дейстительно, при помещении компоненты на форму конструктор вызывается автоматически. В результате появляется возможность менять значения свойств компоненты не только во время выполнения программы, но и на стадии проектирования приложения. * 6.8.4 Испытание компоненты Теперь, когда мы закончили с написанием текста модуля компоненты, проверим работает ли она. => С помощью команды File | Save All сохраните все сделанные добавления. => Выбрав вкладку LEDForm.cpp в окне Редактора кода, по команд File | Include Unite Hdr включите строку #include "LED. h" в заголовок файла формы. По неведомой причине, эта команда не работает с файлом LEDForm.h, поэтому строку #include "LED.h" приходится вставлять вручную. К секции private этого же файла добавьте описание объекта индикатора: private: // User declarations => Активизируйте форму Form1 и в окне Инспектора объектов дважды щелкните мышью в графе значений события OnCreate. С помощью Редактора кода введите обработчик этого события в файл LEDForm.cpp. Следующий код создаст компоненту TLED динамически (определяя ее родителя Parent и помещая в в центре родительской формы) во время выполнения тестового приложения: void_fastcall TFormI::FormCreate(TObject *Sender) Чтобы кнопка управляла индикатором, дважды щелкните мышью в графе значений события OnClick объекта Button1 в окне Инспектора объектов. С помощью Редактора кода введите следующую инструкцию в тело обработчика события: void_fasfccall TPormI::ButtonlClick(TObject *Sender) => Наконец, скомпилируйте и запустите тестовое приложение посредством команды Run | Run. Если компилятор не выдаст ошибок (а их не должно быть, если вы точно следовали изложенной процедуре), то посередине формы тестового приложения вы увидите красный индикатор в состоянии "выключен". Нажав кнопку, вы включите индикатор и он окрасится зеленым цветом (Рис. 6.10). Теперь осталось создать битовый образ пиктограммы, которой новая компонента будет представлена в Палитре. Из меню редактора изображений, открывающегося по команде Tools | Image Editor, выберите File | New | Resource File, a затем - Resource | New Bitmap. В диалоге свойств битового образа установите размеры пиктограммы 24х24 и число цветов VGA (16 Colors). Переименуйте битовый образ компоненты (TLED) по команде Resourse | Rename и дважды щелкните мышью на выбранном имени в древовидном списке ресурсных файлов, чтобы нарисовать подходящую картинку индикатора (например, зеленый кружок). Командой File | Save As сохраните ресурсный файл LED.res в своем рабочем каталоге и закройте Редактор изображений. Рис. 6.10. Динамическое создание компоненты индикатора. 6.8.5 Инсталляция компоненты Перед тем, как приступить к инсталляции новой компоненты на Палитру, выполните последний раз команду File | Save All. => С помощью команды Component | Install откройте диалоговое окно инсталляции компонент. Нажмите кнопку Add, которая открывает диалог добавления модуля. Найдите местоположение модуля LED.cpp, нажав на кнопку поиска Browse. Нажмите кнопку ОК и приготовьтесь ждать окончания перестройки VCL и установки новой компоненты на Палитру. => Выполните команду File | Close All, а затем File | New Application. Поместите новую компоненту LED и кнопку TButton на форму. Снова определите обработчик события OnClick кнопки управления индикатором: void_fastcall TFormI::ButtonlClick(TObject *Sender) => Выполните команду Run | Run и вы увидите, что компонента действительно работает. Порадуйтесь тому, как просто все оказалось на деле, сохраните на всякий случай все рабочие файлы (Borland рекомендует использовать каталог ..\CBuilder\LIB\OBJ) и приступайте к планированию вашей следующей компоненты. 6.9 Итоги Планируете ли вы использовать Библиотеку Визуальных Компонент при создании прикладного программного обеспечения, или развивать существующую Библиотеку при разработке новых компонент — глубокие знания состава и уст роиства VCL будут способствовать успешному решению поставленных задач
|