Главная страница
Навигация по странице:

  • 7. СОЗДАНИЕ СОБСТВЕННЫХ КОМПОНЕНТОВ

  • 7.1. Создание модуля компонента

  • //class

  • 7.2. Наследование компонента

  • _published.

  • 7.3. Добавление свойств, событий и методов

  • 7.4. Регистрация компонента

  • Samples

  • __fastcall

  • 7.6. Инсталляция компонента на Палитру компонентов

  • 7.7. Сохранение файлов нового компонента

  • 8. ПРИМЕР РАЗРАБОТКИ ПРОСТОГО КОМПОНЕНТА

  • 1. Создание формы тестового приложения

  • 2. Создание модуля компонента Мастер компонентов (Component Wizard) упрощает начальные шаги создания компонента: а) Выполните командуComponent|

  • 3. Члены данных, свойства и методы

  • private

  • БГУ Пособие - Программирование в C++ Builder. Учебное пособие по курсу методы программирования для студентов специальностей


    Скачать 1.24 Mb.
    НазваниеУчебное пособие по курсу методы программирования для студентов специальностей
    АнкорБГУ Пособие - Программирование в C++ Builder.pdf
    Дата26.05.2018
    Размер1.24 Mb.
    Формат файлаpdf
    Имя файлаБГУ Пособие - Программирование в C++ Builder.pdf
    ТипУчебное пособие
    #19699
    страница11 из 12
    1   ...   4   5   6   7   8   9   10   11   12
    Вопросы
    1. Какие свойства используются при создании приложения-сервера с использованием компонента TserverSocket?
    2. Какие свойства используются при создании приложения-клиента с использованием компонента TclientSocket?
    3. С помощью какого метода можно получить данные с сервера по инициативе клиента ?
    4. С помощью какого метода клиент может переслать текстовые дан- ные на сервер ?
    5. Куда в приложении-клиенте поступают данные, пересылаемые от сервера?
    6. Какие методы используются для передачи информации от клиента серверу?
    7. С помощью какого метода можно получить данные с сервера по инициативе клиента?
    8. Как организовать постоянное отслеживание информации на серве- ре в приложении-клиенте?
    9. Какое событие в приложении-сервере может быть использовано для определения того, что от клиента серверу послана информация?
    10. Какие способы установления контакта с сервером Вы знаете?
    11. Что нужно сделать, чтобы при запуске приложения-клиента авто- матически запускалось и приложение-сервер?
    Упражнения
    1. Организовать пересылку текстовых сообщений между клиентом и сервером в обоих направлениях с постоянным отслеживанием информа- ции.
    2. Реализовать передачу координат курсора мыши между клиентом и сервером в обоих направлениях с постоянным отслеживанием коорди- нат.
    3. Реализовать простейший “чат”.
    4. Реализовать игру в “слова”, например по очереди называть назва- ния городов.
    5. Реализовать игру «крестики/нолики» в сети.
    6. Реализовать игру «морской бой» в сети.

    112
    7. СОЗДАНИЕ СОБСТВЕННЫХ КОМПОНЕНТОВ
    Процесс разработки собственного компонента (назовем его
    TMyComp) состоит из следующих этапов:
    1. Создание модуля для нового компонента.
    2. Наследование производным классом для нового компонента уже существующего базового класса библиотеки VCL.
    3. Добавление нужных свойств, событий и методов.
    4. Регистрация компонента в среде C++Builder.
    5. Отладка.
    6. Инсталляция компонента на Палитру компонентов.
    7. Сохранение файлов компонента.
    Мастер компонентов способен выполнить автоматически создание файлов модуля, наследование компонентного класса, объявление нового конструктора и регистрацию компонента. Разработчик компонента "вручную" или с помощью имеющихся средств добавляет свойства, со- бытия, методы и устанавливает компонент на Палитру компонентов.
    Рассмотрим подробнее действия, которые выполняются на каждом из перечисленных этапов.
    7.1. Создание модуля компонента
    Программный модуль компонента состоит из двух файлов Му-
    Соmр.срр и MyComp.h, которые компилируются в объектный файл
    MyComp.obj. При paзработке компонента либо создают новый модуль, либо модифицируют существующий. Чтобы создать модуль, необходимо выполнить командуFile|New и в открывшемся диалоговом окне New
    Items выбрать значок Unit. Чтобы добавить компонент к существующему модулю, нужно выполнить командуFile|Open и в открывшемся диалого- вом окне выбрать файл имя_модуля.cpp для модуля, в который будет до- бавлен компонент. Далее формируется заготовка файла МуСоmр.h:
    #ifndef MyCompH
    #define MyCompH
    #include
    #include
    #include
    #include
    //class TMyComponent : public < базовый компонентный класс >
    class PACKAGE TMyComponent : public < базовый класс >
    { public:
    __fastcall TMyComponent(TСomponent *Owner);

    113
    };
    #endif
    Объявление нового класса компонента должно включать макрос
    PACKAGE. Функционально сходные компоненты группируются в паке- ты – динамические библиотечные файлы с расширением .bpl. Как и обычные dll-библиотеки, пакеты содержат код, разделяемый многими приложениями. Пакетная организация ускоряет компиляцию и сборку приложений, позволяет получить более эффективные исполняемые коды за счет того, что к выполняемой программе VCL уже не загружается це- ликом.
    Созданный компонент пока не отличается от своего родителя.
    7.2. Наследование компонента
    Любой компонент является производным от базового класса
    TComponent и его наследников (таких как TControl или TGraphicControl) или от существующего компонентного класса.
    Простейший способ построить новый компонент – это изменить свойства существующего компонента. Для этого можно использовать любой абстрактный класс VCL, в название которого входит слово
    Custom. Например, можно создать новый компонент списка со специаль- ными свойствами, которых нет в стандартном классе TListBox. Посколь- ку нельзя непосредственно модифицировать TListBox, то можно начать с его ближайшего предшественника в иерархии классов. Для этой цели подходит класс TCustomListBox, который реализует все мыслимые свой- ства производных компонентов списка, однако не выставляет всех их в секции _published. Наследуя компонент, нужно объявить в разделе
    _published те свойства, которые требуется включить в создаваемый ком- понент.
    Все оконные компоненты являются производными от базового класса
    TWinControl. Стандартный элемент оконного управления характеризует так называемый "оконный дескриптор" (window handle), который заклю- чен в свойстве Handle. Благодаря дескриптору, Windows идентифицирует данный компонент, в частности, она может принять фокус ввода. Хотя можно создать оригинальный оконный интерфейсный элемент (который не имеет существующих аналогов и никак не связан с ними), используя в качестве базового класса TWinControl, C++Builder предоставляет класс
    TCustomControl – специализированный оконный элемент управления, который упрощает рисование сложных визуальных изображений. Все компоненты стандартного оконного управления: кнопки, списки, тексто- вые поля (за исключением компонента TLabel, который никогда не при-

    114
    нимает фокус ввода) – являются косвенными производными
    TWinControl.
    В отличие от оконных компонентов, производных от класса
    TCustomControl, графические компоненты лишены оконного дескрипто- ра и не могут принять фокус ввода. Графические компоненты обеспечи- вают отображение объектов без использования системных ресурсов.
    Новые графические компоненты необходимо наследовать от базового абстрактного класса TGraphicControl (потомка TControl). Класс
    TGraphicControl предоставляет канву для рисования и обрабатывает со- общения WM_PAINT. Все, что нужно сделать, это переопределить метод рисования Paint в соответствии с заданными требованиями.
    Все компоненты имеют общий абстрактный базовый класс
    TСomponent, однако, только невидимые компоненты можно наследовать непосредственно от класса TComponent. Невидимые компоненты ис- пользуются в качестве интерфейсных элементов с другими компонента- ми (доступ к базам данных или диалоговым окнам).
    7.3. Добавление свойств, событий и методов
    Свойства, в отличие от данных-членов, сами не хранят данные, одна- ко методы чтения и записи организуют к ним доступ. Об этом необходи- мо помнить при создании или изменении компонентных свойств.
    Событие – это связь между некоторым воздействием на компонент и кодом обработчика события, который реагирует на это воздействие. Об- работчик события пишется прикладным программистом. Используя со- бытия, программист может приспособить поведение компонента к своим требованиям без необходимости изменения самих объектов. События, возникающие в результате типичных действий пользователя (например, движений мышью) встроены во все стандартные компоненты VCL, од- нако вы можете определить новые события. C++Builder реализует собы- тия как свойства.
    7.4. Регистрация компонента
    Регистрация компонента – это процесс, который информирует
    C++Builder о том, какой компонент добавляется к VCL и на какой вклад- ке Палитры компонентов он должен появиться. Для регистрации компо- нента выполняются следующие действия:
    1) Добавляется функция Register() в файле МуСоmр.срр. При этом функция заключается в пространство имен с именем, совпадающим с

    115
    именем модуля компонента (при этом первая буква должна быть заглав- ной, а все остальные – строчными).
    2)
    В теле функции Register объявляется массив типа
    TComponentClass, в который вводится имя класса регистрируемого ком- понента.
    3) В теле функции Register вызывается функция RegisterComponents с тремя параметрами: названием вкладки Палитры компонентов, массивом компонентных классов и индексом последнего класса в этом массиве.
    Например:
    namespace Mycomp {
    void __fastcall PACKAGE Register()
    {
    TComponentClass classes[1] = {_classid(TMyComponent)};
    RegisterComponents("Samples", classes, 0);}
    }
    Листинг представляет включение в файл МуСоmр.срр кода для реги- страции компонентf TMyComponent на вкладке Samples Палитры ком- понентов.
    Когда компонента зарегистрирована, можно ее испытать и инсталли- ровать на Палитру компонентов.
    7.5. Отладка неинсталлированного компонента
    Поведение компонента следует проверить до инсталляции на Палит- ру компонентов. По существу необходимо смоделировать действия, ко- торые производит C++Builder, когда пользователь перемещает компо- нент из Палитры компонентов на форму. Процесс требует выполнения следующих шагов:
    1) Включить файл модуля MyComp.h компонента в заголовочный файл некоторой формы: #include " MyComp.h "
    2) Добавить объектный член данных, представляющий испытывае- мый компонент, в раздел объявлений public класса формы: TMyCompo- nent *MyComponent1;.
    3) Подсоединить обработчик к событию OnCreate формы.
    4) Вызвать конструктор компонентного объекта из обработчика этого события, передав ему параметр, указывающий на владельца компонента.
    Обычно это указатель this на объект, который содержит компонент (на- пример, форма).
    5) Сразу же за вызовом конструктора установить свойство Parent – родителя компонента. Обычно значением этого свойства является указа-

    116
    тель this. Если компонент не является элементом управления, т.е. не на- следовался от TControl, то этот шаг пропускается.
    6) Инициировать значения других свойств компонента.
    Ниже приводится листинг модуля формы, используемой для отладки компонента:
    // Заголовочный файл TestForm.h
    #ifndef TestFormH
    #define TestFormH
    #include
    #include
    #include
    #include
    #include "MyComp.h" // 1
    class TForm1 : public TForm {
    __published:
    private:
    public:
    TMyComponent * MyComponent1; // 2
    __fastcall TForm1 (TComponent* Owner); // 3
    };
    extern PACKAGE TForm1 *Forml;
    #endif
    // Файл TestForm.cpp модуля формы
    #include
    #pragma hdrstop
    #include "TestForm.h"
    #pragma package(smart_init) pragma resource "*.dfm"
    TForm1 *Forml;
    __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
    {
    MyComponent1 = new TMyComponent(this); // 4
    MyComponent1->Parent = this; // 5
    MyComponentl->Left = 12; // 6
    }
    Для отладки компонента необходимо выполнить компиляцию и за- пустить тестовое приложение. Если поведение компонента соответствует предъявляемым к ему требованиям, то можно перейти к его установке на
    Палитру компонентов.
    7.6. Инсталляция компонента на Палитру компонентов
    Чтобы добавить к VCL компонент, необходимо выполнить следую- щие шаги:

    117 1) С помощью командыComponent|Install Componentоткрывается диалоговое окно инсталляции компонент. Можно выбрать вкладку Into
    New Package, если компонент включается в новый пакет, или вкладку
    Into existing package, если используется существующий пакет.
    2) Вводится имя модуля компонента MyComp.cpp и путь к нему в по- ле Unit file name. Далее вводится имя нового пакета (совпадающее с на- званием вкладки Палитры компонентов, на которую устанавливается но- вый компонент) в поле Package file name, а его краткое описание – в поле
    Package description. Щелчок на кнопке ОК закрывает диалоговое окно ус- тановки. Добавление компонента в существующий пакет выполняется аналогично.
    3) С текущим содержимым пакета можно ознакомиться вь открыв- шемся окне Менеджера пакетов. Все файлы, составляющие рассматри- ваемый пакет, будут созданы (или перестроены), и новый компонент ус- тановлен на ту вкладку Палитры компонентов, которая была задана в ка- честве одного из параметров функции регистрации Register. C++Builder автоматически включает в проект системные файлы периода выполнения
    (с расширениями .bpi, .res), необходимые для сборки пакета.
    4) Выбирается команда Install в Менеджере пакетов. В результате выполняется компиляция, перестройка VCL и установка нового компо- нента на Палитру компонентов.
    5) Командой Component|Install Packages или Project|Options открыва- ется список установленных пакетов. По щелчку на кнопке Components можно увидеть список всех компонентов, включенных в выбранный па- кет. Если нужно, чтобы текущая конфигурация пакетов принималась по умолчанию в каждом новом создаваемом проекте, то необходимо уста- новить флажок Default.
    Чтобы удалить компонент из VCL, необходимо выполнить следую- щие действия:
    1) Выполнить командуComponent|Install Component, которая откры- вает диалоговое окно установки компонентов.
    2) Найти удаляемый компонентный класс в списке Component classes выбранной группы Библиотеки и нажать кнопкуRemove.
    3) Нажать кнопку ОК. Библиотека будет перестроена и компонент удален из Палитры компонентов.
    Чтобы перестроить Палитру компонентов, необходимо выполнить следующие действия:
    1) Открыть диалог установки опций Палитры компонентов с помо- щью команд Component|Configure Palette илиOptions|Environment|Palette.

    118 2) Нажать кнопкуAdd и выбрать имя для новой вкладки. Имя добав- ленной вкладки появится внизу списка Pages названий вкладок.
    3) Перетащить мышью выбранный компонент в списке Components на нужную вкладку списка Pages.
    4) Нажать кнопку ОК. Библиотека и Палитра компонентов будут пе- рестроены.
    7.7. Сохранение файлов нового компонента
    После окончания процесса разработки, компонент будет представлен следующими файлами: объектный файл результата компиляции MyComp.obj; файлы модуля компонента (MyComp.h, MyComp.cpp); файлы пакета с именем имя_пакета и расширениями bpl, bpk, lib, bpi, cpp, res; файл пиктограммы компонента для Палитры компонентов My-
    Comp.dcr; файл формы MyComp.dfm, если компонент использует форму; желательно создать и сохранить контекстно-справочный файл My-
    Comp.hlp.
    По умолчанию C++Builder сохраняет компонентный пакетный файл с расширением bpl в каталоге \...\ProgramFiles\Borland\CBuilder6\ Pro- jects\Bpl, а библиотечные файлы с расширениями lib и bpi – в каталоге
    \...\ProgramFiles\Borland\CBuilder6\Projects\Lib. Используя новый компо- нент в дальнейшем, нельзя забывать проверять вкладку Directo- ries|Conditionals диалогового окна команды Project|Options, где должен быть указан путь к библиотечным каталогам.
    8. ПРИМЕР РАЗРАБОТКИ ПРОСТОГО КОМПОНЕНТА
    Перед тем, как приступить к разработке компонент, необходимо знать, что он должен делать и как будет реализовано его оригинальное поведение. Рассмотрим пример компонента, моделирующего бинарный индикатор, который меняет цвет при изменении состояния. Некоторое свойство компонента будет хранить его текущее состояние (true – инди- катор включен, и false – в противном случае). Мы уже знаем, что жела- тельно выбрать для наследования наиболее близкий в иерархии VCL ба- зовый компонентный класс. Очевидно, что индикатор представляет со- бой графический компонент семейства TGraphicControl. Поскольку мы разрабатываем простой компонент, пусть он будет иметь форму круга, а

    119
    не более хитроумный образ. Компонент TShape из вкладки Палитры компонентов Additional выглядит ближайшим родственным компонен- том. При внимательном рассмотрении Tshape мы видим, что он имеет больше свойств и событий, чем нам требуется. Все что мы хотим изме- нить при наследовании от TShape – это форму индикатора и цвет кисти при его переключении. Перейдем к фактической разработке компонента:
    1. Создание формы тестового приложения
    Пока мы не убедились, что разрабатываемый компонент работает, его нельзя включать в VCL. Сначала следует создать тестовое приложение для формы с прототипом нового компонента MyComp: а) С помощью командыFile|NewApplication создайте пустую форму. б) Разместите кнопку TButton на форме. в) С помощью командыFile|SaveAll сохраните форму и проект при- ложения в файлах под именами MyCompForm.cpp и MyCompProj.bpr.
    2. Создание модуля компонента
    Мастер компонентов (Component Wizard) упрощает начальные шаги создания компонента: а) Выполните командуComponent|New и в открывшемся диалоговом окне Мастера компонентов заполните поля диалога указанными на рис.
    26 значениями. Нажмите кнопку ОК. б) С помощью команды File|Save As сохраните файл Unitl.cpp под именем MyComp.cpp.
    Файл MyComp.cpp будет содержать пустой конструктор объекта и функцию Register для регистрации компонента. Созданный при этом файл MyComp.h будет содержать объявление нового компонентного класса с конструктором, а также несколько заголовочных файлов пред- компиляции.
    3. Члены данных, свойства и методы
    Прежде всего, в файле MyComp.h опишем булеву переменную со- стояния индикатора и две переменные перечисляемого типа TColor для хранения цветов, отображающих оба состояния. Члены данных следует поместить в разделе private объявлений класса. Там же расположим про- тотипы методов записи соответствующих свойств, а сами свойства объя- вим в разделе _published.

    120
    Рис. 26. Окно Мастера компонентов
    Ниже приводится заголовочный файл модуля компонента:
    // MyComp.h ------------------------------------------------------------
    #ifndef MyCompH
    #define MyCompH
    #include
    #include
    #include
    #include
    //--------------------------------------------------------------------------- class PACKAGE MyComp : public TShape
    { private: bool FOnOff;
    TColor FOnColor;
    TColor FOffColor; void __fastcall SetOnOff(const bool Value) ; void __fastcall SetOnColor(const TColor OnColor); void __fastcall SetOffColor (const TColor OffColor) ; protected: public:
    __fastcall MyComp(TComponent* Owner);
    __published:
    __property bool OnOff= { read= FOnOff,write= SetOnOff} ;
    __property ТСоlог OnColor= { read=FOnColor,write=SetOnColor} ;
    __property TColor OffColor={ read=FOff Color, write= SetOffColor} ;
    };
    //---------------------------------------------------------------------------

    121
    #endif
    Для добавления в файл MyComp.cpp необходимо написать три функ- ции для присваивания значений свойств соответствующим членам дан- ных и наполнить конструктор компонента инструкциями для инициали- зации переменных. Ниже приводится листинг файла MyComp.cpp после внесения изменений:
    //MyComp.cpp
    #include
    #pragma hdrstop
    #include "MyComp.h"
    #pragma package(smart_init)
    //---------------------------------------------------------------------------
    // ValidCtrCheck is used to assure that the components created
    // do not have any pure virtual functions. static inline void ValidCtrCheck(MyComp *)
    { new MyComp(NULL); } void __fastcall MyComp::SetOnOff(const bool Value) {
    FOnOff = Value;
    Brush->Color= (FOnOff) ? FOnColor : FOffColor ;
    } void __fastcall MyComp::SetOnColor(const TColor OnColor) {
    FOnColor = OnColor;
    Brush->Color = (FOnOff) ? FOnColor : FOffColor;
    } void __fastcall MyComp::SetOffColor(const TColor OffColor) {
    FOffColor = OffColor;
    Brush->Color = (FOnOff) ? FOnColor : FOffColor;
    }
    //---------------------------------------------------------------------------
    __fastcall MyComp::MyComp(TComponent* Owner)
    : TShape(Owner)
    { Width = 15; //ширина по умолчанию
    Height = 15; // высота по умолчанию
    FOnColor = clLime; // зеленый, когда включен
    FOffColor = clRed; // красный, когда выключен
    FOnOff = false; // выключен по умолчанию
    Shape = stEllipse; //в форме эллипса по умолчанию
    Pen->Color = clBlack; // черный контур по умолчанию
    Pen->Width = 2; // ширина контура по умолчанию
    Brush->Color = FOffColor; // цвет заливки по умолчанию
    } namespace Mycomp
    { void __fastcall PACKAGE Register()
    {
    TComponentClass classes[1] = {__classid(MyComp)};

    122
    RegisterComponents("Samples", classes, 0);
    }
    }
    //---------------------------------------------------------------------------
    Установленные конструктором значения членов данных по умолча- нию появятся в окне Инспектора объектов при создании объекта. Дей- стительно, при помещении компоненты на форму конструктор вызыва- ется автоматически. В результате появляется возможность менять значе- ния свойств компонента не только во время выполнения программы, но и на стадии проектирования приложения.
    1   ...   4   5   6   7   8   9   10   11   12


    написать администратору сайта