- •1. Общие характеристики
- •1.1 Основные характеристики
- •1.1.1 Скорость визуальной разработки
- •1.1.2 Продуктивность компонент
- •1.1.4 Масштабируемые соединения с базами данных
- •1.2 Другие программные продукты Borland
- •1.3 Проблемы совместимости
- •1.3.2.1 Какую систему выбрать?
- •1.3.2.2 Какая система является более мошной?
- •2.1 Первое знакомство
- •2.1.1 Визуальное проектирование
- •2.1 Первое знакомство
- •2.1.2 Свойства, методы и события
- •2.1.3 Технология двунаправленной разработки
- •2.1.4 Использование проектных шаблонов
- •2.2 Палитра компонент - краткий обзор
- •2.3 Приложения управления базами данных
- •2.3.1 Пример из существующего проекта
- •2.4 Итоги
- •3.1 Инкапсуляция
- •3.2 Классы, компоненты и объекты
- •3.3 Наследование
- •3.5 Полиморфизм
- •3.5.2 Дружественные функции
- •3.6.1.1 Объявления компонентных классов
- •3.6.1.2 Объявления свойств
- •3.6.1.3 Объявления обработчиков событий '
- •3.6.1.4 Объявления автоматизированных свойств и методов
- •3.6.1.5 Быстрый вызов функций
- •3.6.1.6 Расширенные типы данных Delphi
- •3.6.2.1 Шаблоны
- •3.6.2.2 Пространства имен
- •3.6.2.3 Явные объявления
- •3.6.2.4 Непостоянные объявления
- •3.6.2.5 Идентификация типов rtti
- •3.6.2.6 Исключения
- •4. Инструменты визуальной разработки приложений
- •4.1 Администратор проекта
- •4.2 Редактор форм
- •4.3 Инспектор объектов
- •4.4 Хранилище объектов
- •4.4.1 Разделение объектов
- •4.5 Редактор кода
- •4.6 Палитра компонент
- •4.6.1.2 TPopUpMenu
- •4.6.1.4 TEdit
- •4.6.1.6 TButton
- •4.6.1.7 TCheckBox
- •4.6.1.8 Ей tRadioButton
- •4.6.1.9 TListBox
- •4.6.1.10 TComboBox
- •4.6.1.12 TGroupВох
- •4.6.2.1 TTabControl
- •4.6.2.2 TPageControl
- •4.6.2.5 TImageList
- •4.6.2.6 THeaderControl
- •4.6.2.7 TRichEdit
- •4.6.2.9 TTrackBar
- •4.6.2.10 TProgressBar
- •4.6.2.11 TUpDown
- •4.6.2.12 И tHotKey
- •4.6.3.5 TDrawGrid
- •4.6.4.1 TDataSource
- •4.6.4.2 ТТаble
- •4.6.4.3 TQuery
- •4.6.4.4 TStoredProc
- •4.6.4.6 TSession
- •4.6.4.8 TUpdateSql
- •4.6.5.1 TdbGrid
- •4.6.5.2 TdbNavigator
- •4.6.5.3 TdbText
- •4.6.5.4 TdbEdit
- •4.6.5.6 TdbImage
- •4.6.5.7 TdbListBox
- •4.6.5.8 TdbComboBox
- •4.6.5.9 TdbCheckBox
- •4.6.5.11 TdbLookupListBox
- •4.6.7.1 TOpenDialog
- •4.6.7.2 TSaveDialog
- •4.6.7.3 TFontDialog
- •4.6.7.4 TColorDialog
- •4.6.7.5 TPrintDialog
- •4.6.7.6 TPrinterSetupDialog
- •4.6.7.8 TReplaceDialog
- •4.6.7.9 Использование диалоговых компонент текстовым редактором. Приемы отладки
- •4.6.8.1 TTimer
- •4.6.8.2 TPaintBox
- •4.6.8.3 TFileListBox
- •4.6.8.6 TFilterComboBox
- •4.6.8.7 TMediaPlayer
- •4.6.8.8 TOleContainer
- •4.6.8.9 TDdeClientConv
- •4.6.8.10 TDdeClientltem
- •4.6.8.11 TDdeServerConv
- •4.6.8.12 TDdeServerltem
- •4.6.9.1 TQuickReport
- •4.6.9.2 TqrBand
- •4.7 Дизайнер меню
- •4.8 Итоги
- •5. Визуальная разработка приложений баз данных
- •5.1 Организация доступа к базам данных
- •5.1.2.1 Страница Drivers
- •5.1.2.2 Страница Aliases
- •5.1.2.3 Страница System
- •5.1.2.4 Страница Date
- •5 .1.2.5 Страница Time
- •5.1.2.6 Страница Number
- •5*2 Использование визуальных компонент
- •5.2.1.1 Источники данных
- •6. Использование и создание визуальных компонент
- •6.1 Назначение и устройство vcl
- •6.2 Типы компонент
- •6.2.5.1 Право владения
- •6.2.5.2 Родительское право
- •6.2.5.3 Поточность
- •6.3 Свойства компонент
- •6.3.1 Зачем нужны свойства?
- •6.3.2.1 Доступ к внутренним данным свойств
- •6.3.2.2 Свойства обеспечивают доступ к членам данных
- •6.3.2.3 Методы записи и чтения свойств
- •6.3.3 Переопределение свойств
- •6.3.4.1 Свойства типа множество
- •6.3.4.2 Свойства типа массив
- •6.4 События
- •6.4.1 Зачем нужны события?
- •6.4.2 Определение событий
- •6.4.2.3 Стандартные события
- •6.4.2.4 Собственные события
- •6.4.2.5 События и сообщения Windows
- •6.4.3 Обработка событий
- •6.5 Методы
- •6.5.1 Вызовы статических методов
- •6.6.1 TObject
- •6.6.2 TPersistent
- •6.6.3 TComponent
- •6.6.4 TControl
- •6.6.5 TWinControl
- •6.6.6 TGraphicControl
- •6.7 Схема разработки компонент
- •6.7.1 Создание модуля компоненты
- •6.7.2 Наследование компоненты
- •6.7.2.1 Модификация существующих компонент
- •6.7.2.2 Создание оригинальных оконных компонент
- •6.7.2.3 Создание графических компонент
- •6.7.2.4 Создание невидимых компонент
- •6.7.3 Добавление свойств, событий и методов.
- •6.7.4 Регистрация компоненты
- •6.7.5 Отладка неинсталлированной компоненты
- •6.7.6 Инсталляция компоненты на Палитру
- •6.7.7 Сохранение файлов новой компоненты
- •6.8 Разработка простой компоненты
- •6.8.1 Форма тестового приложения
- •6.8.2 Модуль тестового приложения
- •6.8.3 Члены данных, свойства и методы
- •6.8.4 Испытание компоненты
- •6.8.5 Инсталляция компоненты
- •6.9 Итоги
- •7. Графические компоненты
- •7*2 Использование канвы
- •7.3 Работа с рисунками
- •7.3.1 Рисунок, графика или канва9
- •7.3.2 Графические файлы
- •7.3.3 Обслуживание палитр
- •7.4 Внеэкранные битовые образы
- •7.4.1 Копирование битовых образов.
- •7.4.2 Создание и обслуживание
- •7.4.3 Реакция на изменения
- •7.5 Разработка графического приложения
- •7.5.1 Проектирование формы
- •7.5.2 Программный модуль
3.6.1.5 Быстрый вызов функций
При объявлении функций, параметры которых передаются через процессорные регистры, используется модификатор _fastcall:
<возвращаемый тип> _fastcall <name>(<список параметров^
Это ключевое слово определяет, что первые три типизированных параметра функции с именем name (слева направо по списку) передаются не через стек, а через процессорные регистры AX, BX и DX. Регистры не используются, если значение параметра не умещается в регистр, т.е. при передаче через параметр чисел с плавающей точкой, структур и функций.
Строго говоря, быстрый вызов функций не является прерогативой компилятора C++Builder. В предыдущей главе я уже обращал внимание читателя на использование _fastcall в объявлениях функций обработки событий, которые C++Builder генерирует автоматически.
3.6.1.6 Расширенные типы данных Delphi
C++Builder не позволяет посредством известного ключевого слова typedef просто переопределить некоторые сложные типы данных Объектного Паскаля. C++Builder реализует такие расширенные типы в виде обычных или шаблонных классов (template class). Каждый такой класс содержит все необходимые конструкторы, деструкторы, свойства и объектные методы. Многие компоненты VCL используют реализацию расширенных типов, а кроме того, они требуются при разработке новых компонент на базе оригиналов из Delphi.
Ниже приводится сводная таблица встроенных типов Delphi и соответствующих им типов C++Builder:
Delphi |
Длина и значения |
C++Builder |
Реализация |
Shortint |
8-битовое целое |
char |
typedef |
Smallint |
16-битовое целое |
short |
typedef |
Longint |
32-битовое целое |
long |
typedef |
Byte |
8-битовое целое без знака |
unsigned char |
typedef |
Word |
16-битовое целое без знака |
unsigned short |
typedef |
Integer |
32-битовое целое |
int |
typedef |
Cardinal |
32-битовое целое без знака |
unsigned long |
typedef |
Boolean |
true/false |
bool |
typedef |
ByteBool |
true/false или 8-битовое целое без знака |
unsigned char |
typedef |
WordBool |
true/false или 16-битовое целое без знака |
unsigned short |
typedef |
LongBool |
true/false или 32-битовое целое без знака |
unsigned long |
typedef |
AnsiChar |
8-битовый символ без знака |
unsigned char |
typedef |
WideChar |
Слово - символ Unicode |
wchar t |
typedef |
Char |
8-битовый символ |
char |
typedef |
String |
Текстовая строка Delphi |
AnsiString |
typedef |
Single |
32-битовое плавающее число |
float |
typedef |
Double |
64-битовое плавающее число |
double |
typedef |
Extended |
80-битовое плавающее число |
long double |
typedef |
Real |
32-битовое плавающее число |
float |
typedef |
Comp |
64-битовое плавающее число |
double |
typedef |
Pointer |
32-битовый указатель |
void * |
typedef |
PChar |
32-битовый указатель на символы без знака |
unsigned char * |
typedef |
PansiChar |
32-битовый указатель на ANSI символы без знака |
unsigned char * |
typedef |
Set |
Множество 1..32 байт |
Set<type, minval, maxval> |
template class |
AnsiString |
Текстовая строка Delphi |
AnsiString |
class |
Variant |
Вариантное значение, 16 байт |
Variant |
class |
TdateTime |
Значение даты и времени, 64-битовое плавающее число |
TDateTime |
class |
Currency |
Валюта, 64-битовое плавающее число, 4 цифры после точки |
Currency |
class |
Set (множество) служит для спецификации типа параметров объектных методов VCL или типа значений, возвращаемых этими методами. C++Builder реализует этот встроенный тип Delphi с помощью одноименного шаблонного класса Set<type, minval, maxval> со следующими параметрами:
type тип элементов множества (обычно, int. char или enum):
minval минимальное (положительное) значение, которое могут принимать элементы множества;
maxval максимальное (не более 255) значение, которое могут принимать элементы множества.
Подстановка разных значений параметров приводит к созданию экземпляров шаблонного класса Set различных типов, поэтому оператор сравнения if (si == s 2) объектов, описанных как
Set<char, 'A', 'C'> si;
Set<char, 'X', 'Z'> s2;
вызовет ошибку компиляции. Для создания множественных экземпляров типа Set необходимо использовать ключевое слово typedef. Например, объявив typedef Set<char, 'A','Z'> UpperCaseSet; можно создать множества UpperCaseSet si; и UpperCaseSet s2; а затем инициализировать эти объекты:
s1 “ 'А' “ 'В' “ 'С' ;
s2 “ 'X' “ 'Y' “ '?.' ;
AnsiString используется для спецификации типа текстовых строк произвольной длины, имеющих следующую характерную внутреннюю структуру:
счетчик |
длина строки |
данные |
терминатор \0 |
C++Builder реализует этот встроенный тип Delphi как одноименный класс. Если при создании экземпляров данного класса не указано начальное значение строки, конструктор AnsiString автоматически присваивает всем переменным нулевые значения. Среди методов данного класса отметим наиболее часто вызываемый метод с str (), который возвращает указатель на символьный массив, оканчивающийся 0 и содержащий копию символов, заключенных в исходном объекте типа AnsiString. Листинг 3.18 иллюстрирует "применение методов чтения и записи значения члена данных FNames свойства Names типа AnsiString в экземпляре MyFamily объявленного компонентного класса Family". Предыдущее предложение кажется полной абракадаброй, если не проникнуться терминологией объектно-ориентированного программирования. Рассматривайте его как своеобразное словесное упражнение по краткому курсу ООП.
#include <vcl/dstring.h> #include <stdio.h> class Family // объявление класса
{
private:
AnsiString FNames[10]; // массив имен AnsiString GetName(int Index); // метод чтения void SetName(int, AnsiString); // метод записи public:
_property AnsiString Names[int Index] =
{read=GetName, write=SetName} ;
Family(){} // .конструктор -Family(){) // деструктор
};
AnsiString Family::GetName(int i)
{
return FNames[i]; // GetName возвращает значение }
void Family::SetName(int i, const AnsiString s) { FNames[i]=s; // SetName присваивает значение
}
void main()
{
Family My Family; // создание объекта MyFamily // Инициализация 4-х строк массива имен методом SetName() MyFamily.Names[0]="Иван" ;
MyFamily.Names[1]="Анна" ;
MyFamily.Names[2]="Марья";
MyFami ly. Names [ 3 ] = " Андрей " ;
// Вывод 4-х строк массива имен методом GetName() for (int i=0; i<=3; i++)
puts(MyFamily.Names[i].c_str()) ;
}
Листинг 3.18. Пример использования типа AnsiString в C++ программе с компонентным классом Family (Семья).
Variant служит для спецификации значений, меняющих тип динамически. Переменная вариантного типа, в отличие от обычных статически типизированных переменных, способна менять свой тип во время исполнения программы. C++Builder объявляет этот тип Delphi как class __declspec(delphireturn) Variant: public TVarData. Заметим, чтс синтаксис вариантов, принятый в Delphi, например:
V: Variant;
V := VarArrayCreate([0,Hi9hVal,0,HighVal],varlnteger) ;
отличается от способа записи вариантного массива в C++Builder:
Variant V(OPENARRAY(int,(0,HighVal,0,HighVal)),varlnteger);
Вариант может быть сконструирован из следующих типов данных: short, int, float, double. Currency, TDateTime, bool, WordBool, Byte, AnsiString&, char *, wchar_t * const. 01e2::lDispatch* const или 01e2::IUnknown* const. Компилятор автоматически выполнит необходимые преобразования типа. При создании вариантных переменных они всегда инициализируются специальным значением Unassigned (не определено). Специальное значение Null указывает, что данные отсутствуют.
Внимание: Варианты предоставляют ООП чрезвычайную гибкость, однако требуют большей памяти, нежели статически типизированные переменные, а операции над ними выполняются заметно медленнее.
TDateTime используется для спецификации переменных даты и времени. C++Builder реализует этот встроенный тип Delphi как одноименный класс, который инкапсулирует член данных типа double, содержащий значение даты в целой части числа, а значение времени в мантиссе (считая от полудня 30 декабря 1899 года). В следующей таблице приведены значения переменной типа TDateTime и их эквиваленты в выражениях даты и времени:
Значение |
Дата |
Время |
Примечания |
0 |
12/30/1899 |
12:00 |
+0 дней, +0 часов |
2.75 |
01/01/1900 |
18:00 |
+2 дня, +6 часов |
-1.25 |
12/29/1899 |
06:00 |
-1 день, -б часов |
35065 |
01/01/1996 |
12:00 |
+35065 дней, +0 часов |
Чтобы вычислить дробное число дней, прошедших между двумя датами, вычтите второе значение из первого. Чтобы перейти к следующему дню, сохранив время, просто добавьте 1 к текущему значению.
3.6.2 Расширения стандарта ANSI C++
Рассматриваемые расширения стандарта ANSI C++, в основном, представляют интерес для разработчиков новых классов и компонент, а также для программистов, которые работают в большом коллективе над созданием сложного проекта.
Вы можете прочитать остаток главы "по диагонали" или вовсе пропустить его, если не занимаетесь указанной деятельностью, и тонкости языка вас не интересуют.
