
C _Учебник_МОНУ
.pdf
|
Об’єктно-орієнтоване програмування |
529 |
|
|
|
|
|
|
|
|
|
Таблиця 14.2 |
|
|
|
Деякі методи класу TWinControl |
|
|
|
|
|
|
|
|
|
Прототип методу |
Призначення |
|
|
|
|
|
|
|
|
virtual void __fastcall |
Передає об‟єктові “фокус”, після чого натискання |
|
|
|
SetFocus(void); |
клавіш клавіатури сприйматимуться саме цим |
|
|
|
|
об‟єктом |
|
|
|
DYNAMIC void __fastcall |
Викликає функцію відгуку на подію OnKeyDown, |
|
|
|
KeyDown(Word &Key, |
яка відбувається за натискання будь-якої клавіші |
|
|
|
Classes:: TShiftState |
на клавіатурі. Параметр Key визначає клавішу, |
|
|
|
Shift); |
|
|
|
|
яку натиснуто. Параметр Shift є такий самий, |
|
|
|
|
|
|
|
|
|
|
як у MouseDown |
|
|
|
DYNAMIC void __fastcall |
Викликає функції відгуку на подію OnKeyPress, |
|
|
|
KeyPress( char&Key); |
яка відбувається за натискання будь-якої |
|
|
|
|
символьної клавіші |
|
|
|
DYNAMIC void __fastcall |
Викликає функції відгуку на подію OnKeyUp, |
|
|
|
KeyUp(Word &Key,Classes:: |
яка відбувається за відпускання будь-якої клавіші |
|
|
|
TShiftState Shift); |
|
|
|
|
|
|
|
|
Клас TGraphicControl – це абстрактний клас, похідний від TControl, але який, на відміну від класу TWinControl, не має віконного дескриптора. Цей клас використовують для графічних зображень на формі без звертань до системних ресурсів Windows. Важлива властивість цього класу – Canvas, яка забезпечує доступ до поверхні малювання (див. підрозд. 12.4). Похідні від цього класу також можуть обслуговувати події маніпулювання з мишею.
Завдяки важливій властивості класів – успадкуванню – можна створювати нові компоненти не з нуля, а як клас, який успадковує властивості, методи чи події батьківського класу, тобто класу, на базі якого створюється цей нащадок. Наприклад, при створюванні нової кнопки можна взяти за основу один з уже розроблених класів кнопок, наприклад клас TButton, й лише долучити до нього певні нові властивості чи то відкинути певні властивості та методи батьківського класу.
14.9.2 Побудова компонента-нащадка
Яскравим прикладом застосування успадкування є створення нового компонента у візуальному середовищі програмування як нащадка існуючого компонента. При цьому компоненту можна долучити нові властивості чи нові події.
Процес створювання компонента складається з послідовності етапів:
1)обирання батьківського компонента;
2)створення модуля нового компонента;
3)тестування компонента;
4)інсталяція (долучення) компонента до пакета компонентів.
Розглянемо цей процес на прикладі створення нового компонента, який
запам‟ятовує кількість натискань на нього та відображує цю інформацію.

Об’єктно-орієнтоване програмування |
531 |
|
|
до власного каталогу, C++ Builder автоматично допише його до Search path; тоді залишиться лише перевірити, чи правильно це було зроблено.
Тепер слід натиснути кнопку ОК, – і буде утворено модуль нового компонента, який складається з двох файлів: заголовного файла BtnNClick.h та файла реалізації BtnNClick.cpp. При цьому буде відкрито вікно файла BtnClick.cpp; проте оголошення нового класу буде сформовано у заголовному файлі BtnNClick.h.
До шаблона компонента, який утворено, треба ввести певні доповнення: оголошення нових полів даних, функції доступу до них, властивості та методи. Для нашого компонента створимо нове поле NClick типу int та допишемо прототип методу Click.
Файл BtnNClick.h:
#ifndef BtnNClickH #define BtnNClickH #include <SysUtils.hpp> #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp>
class PACKAGE TBtnNClick : public TButton { private:
int NClick; // Змінна для підрахунку кількості натискань protected:
public: // Прототип конструктора нового компонента
__fastcall TBtnNClick(TComponent* Owner);
// Прототип події Click
DYNAMIC void __fastcall Click(void);
__published: };
#endif
У цьому файлі рядок
class PACKAGE TBtnNClk : public TButton
повідомляє про те, що клас TBtnNClk є нащадком класу TButton. Слово public означає, що поля й методи батьківського класу будуть доступними з екземплярів його нащадка. Поле NСlick вміщено до секції private, щоб користувач не мав до нього доступу. Тепер слід долучити до класу TBtnNClick додаткові методи. У секції public нового класу вже вміщено прототип методу:
__fastcall TBtnNClick (TComponent* Owner);
Це так званий метод-конструктор об‟єктів нового класу. Далі у секції public йде прототип методу Click, який перекриває метод Click класу TButton. Цей прототип має вигляд:
DYNAMIC void __fastcall Click(void);
Тепер перейдемо до файла BtnNClick.cpp. У цьому файлі розмістимо реалізацію оновленого конструктора та методу Click.

Об’єктно-орієнтоване програмування |
533 |
|
|
отечну підпрограму RegisterComponents, перший параметр якої визначає сторінку, на яку буде вміщено новий компонент, другий – масив імен класів, які реєструються, а останній параметр має бути на 1 меншим за кількість класів у масиві. Директива namespace визначає константу BtnNClick, яка збігається з ім‟ям модуля з точністю до регістра літер. У подальшому ця константа дозволяє викликати “правильну” функцію Register для реєстрації різних класів.
Тестування компонента. Після створення модуля нового компонента його бажано протестувати перед інсталяцією, щоби переконатися, що новий компонент працює правильно. Для цього розробленні модулі зберігають та створюють проект, який використовує модуль нового компонента. Компонент буде створено як динамічну змінну, тому що на палітрі компонентів його піктограми ще нема.
На форму проекту нанесемо тільки стандартну кнопку Button1 для керування роботою проекту. Варіант форми для тестування:
#include <vcl.h> #pragma hdrstop
#include "BtnNClick.cpp" // Приєднуємо модуль компонента
#include "Unit1.h" //------------------------------------------------------------
#pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1;
//------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
}
//-------------------------------------------------------------
TBtnNClick |
*Btn; // Оголошення динамічної змінної – об‟єкта класу |
//--------- |
Відгук для кнопки “Створити нову кнопку”--------- |
void __fastcall TForm1::Button1Click(TObject *Sender) { Btn = new TBtnNClick (Form1);

|
Об’єктно-орієнтоване програмування |
535 |
|
|
|
|
|
Наведемо коди файлів SG.h та SG.cpp. |
|
|
|
Файл SG.h: |
|
|
|
#ifndef SGH |
|
|
|
#define SGH |
|
|
|
#include <SysUtils.hpp> |
|
|
|
#include <Classes.hpp> |
|
|
|
#include <Controls.hpp> |
|
|
|
#include <Grids.hpp> |
|
|
|
//------------------------------------------------------------ |
|
|
|
class PACKAGE TSG : public TStringGrid |
|
||
{private: |
|
|
|
bool flag; // Оголошення змінної логічного типу |
|
||
protected: |
|
|
|
public: // Прототип конструктора нового компонента |
|
||
__fastcall TSG(TComponent* Owner); |
|
||
// Прототип події KeyDown |
|
|
|
DYNAMIC void __fastcall KeyDown(Word &Key, |
|
||
|
Classes::TShiftState Shift); |
|
|
// Прототип події Click |
|
|
|
DYNAMIC void __fastcall Click(void); |
|
||
__published: |
|
|
|
}; |
|
|
|
#endif |
|
|
|
Файл SG.cpp: |
|
|
|
#include <vcl.h> |
|
|
|
#pragma hdrstop |
|
|
|
#include "SG.h" |
|
|
|
#pragma package(smart_init) |
|
|
|
static inline void ValidCtrCheck(TSG *) |
|
||
{ new TSG(NULL); } |
|
|
|
//------------------------------------------------------------ |
|
|
|
__fastcall TSG::TSG(TComponent* Owner) |
|
||
: TStringGrid(Owner) |
|
|
|
{ flag=true; |
// Надання початкового значення змінній flag |
|
|
} |
|
|
|
// Новий код функції на подію Click |
|
|
|
void __fastcall TSG::Click() |
|
|
|
{ if(flag) Font->Size=Font->Size*2; |
// Збільшення шрифту удвічі |
|
|
else Font->Size=Font->Size/2; |
// Зменшення шрифту удвічі |
|
|
flag=!flag; |
// Змінювання значення flag на протилежне |
|
|
// Подальше |
успадкування роботи методу Click() від класу TStringGrid |
|
TStringGrid::Click();
}
//------------------------------------------------------------
// Новий код функції на подію KeyDown
void __fastcall TSG::KeyDown(Word &Key,


|
Об’єктно-орієнтоване програмування |
537 |
|
|
|
//----------------------------------------------------------- |
|
|
TSG *SGt; // Оголошення динамічної змінної класу нового компонента |
|
|
//---- |
Відгук на кнопку “Відобразити компонент”-------------------- |
|
void __fastcall TForm1::Button1Click(TObject *Sender)
{SGt=new TSG(Form1); SGt->Parent=Form1;
//Координати розміщення нового компонента на формі
SGt->Left=20; SGt->Top=10;
//Значення властивостей нового компонента
SGt->FixedRows=0;
SGt->FixedCols=0;
SGt->RowCount=4;
SGt->ColCount=5; SGt->Options<<goEditing<<goTabs;
}
Власником об‟єкта, що тестується, є вікно форми Form1 (власник показано як параметр конструктора TSG). Властивість Parent створеного екземпляра класу також має значення Form1, а це означає, що новий компонент SGt буде розміщено у вікні Form1. Після запуску проекту та натискання на стандартну кнопку “Відобразити компонент” на формі з‟явиться новий компонент. Коли курсор знаходитиметься у будь-якій комірці компонента SGt стануть доступними такі можливості: при натисканні клавіші <F11>, компонент заповнюватиметься випадковими числами (рис. 14.4, а), при клацанні лівою клавішею миші шрифт символів комірок збільшуватиметься удвічі (рис. 14.4, б), при натисканні клавіші <Esc> всі комірки автоматично очищуватимуться (рис. 14.4, в).
а |
б |
в |
Рис. 14.4. Результати роботи з компонентом SGt: а) при натисканні клавіші <F11> ;
б) при клацанні лівою клавішею; в) натисканні клавіші <Esc>.
14.9.3 Інсталяція компонента
Компоненти у C++ Builder компілюються у пакети. Тому, для того, щоб ярлик створеного компонента відобразився на палітрі компонентів C++ Builder,
