Лекция №
Вид материала | Лекция |
- «Социальная стратификация и социальная мобильность», 46.19kb.
- Первая лекция. Введение 6 Вторая лекция, 30.95kb.
- Лекция Сионизм в оценке Торы Лекция Государство Израиль испытание на прочность, 2876.59kb.
- Текст лекций н. О. Воскресенская Оглавление Лекция 1: Введение в дисциплину. Предмет, 1185.25kb.
- Собрание 8-511 13. 20 Лекция 2ч режимы работы эл оборудования Пушков ап 8-511 (ррэо), 73.36kb.
- Концепция тренажера уровня установки. Требования к тренажеру (лекция 3, стр. 2-5), 34.9kb.
- Лекция по физической культуре (15. 02.; 22. 02; 01. 03), Лекция по современным технологиям, 31.38kb.
- Тема Лекция, 34.13kb.
- Лекция посвящена определению термина «транскриптом», 219.05kb.
- А. И. Мицкевич Догматика Оглавление Введение Лекция, 2083.65kb.
CPoint(p.X() + 30, p.Y() + 30),
CPoint(p.X() - 30, p.Y() + 30),
CPoint(p.X() - 30, p.Y() - 30)
};
static CPolyline pl(sizeof(coords) / sizeof(coords[0]), coords); // и ломаную
FixedSet = p, c, e, pl; // помещаем в множество фигур FixedSet.
// Статически определяем 4 окружности, и
static CCircle cs[4] = {
CCircle(coords[0], 5),
CCircle(coords[1], 5),
CCircle(coords[2], 5),
CCircle(coords[3], 5)
};
// Добавляем их к множеству FixedSet.
FixedSet += cs[0], cs[1], cs[2], cs[3];
}
//---------------------------------------------------------------------------
// Закрытые функции
//---------------------------------------------------------------------------
void TfrmOOPExample::CreateFigures(CFigureSet &s, TTreeNode *node, bool recursive)
{
// Массив возмножных цветов фигур.
static const TColor Colors[] = {
clRed, clBlue, clGreen, clLime, clAqua, clWhite, clYellow, clOlive
};
// Число возможных цветов (элементов в массиве цветов).
const NColors = sizeof(Colors) / sizeof(Colors[0]);
// Перечисление типов фигур.
enum { Point, Circle, Ellipse, Polyline, Set, NFigures };
// Массив имен фигур, соответсвующий перечислению.
static const char *Names[NFigures] = {
"Точка", "Окружность", "Эллипс", "Ломаная", "Множество фигур"
};
int n, c, x, y, N;
CFigure *f; // адрес генерируемой фигуры
TTreeNode *nn; // ветка дерева, соответсвующая генерируемой фигуре
c = random(11) + 10; // число генерируемых фигур
x = PB->ClientWidth; // ширина и
y = PB->ClientHeight; // высота области, внутри которой генерируются фигуры
N = NFigures - !recursive; // число генерируемых типов фигур
// (если recursive = true, то генерируются все типы фигур,
// иначе - все, кроме Set)
// Генерируем c фигур.
while (c--) {
// Выбираем тип фигуры.
n = random(N);
// Добавляем ветку дерева с заголовком, содеращим имя фигуры.
nn = TV->Items->AddChild(node, Names[n]);
// Генерируем случайным образом фигуру типа n.
switch (n) {
case Point:
f = new CPoint(random(x), random(y));
break;
case Circle:
f = new CCircle(random(x), random(y), random(25));
break;
case Ellipse:
f = new CEllipse(random(x), random(y), random(25), random(25));
break;
case Polyline:
{
// Для ломаной создаем случайным образом массив узлов:
// Число узлов 1..10.
PointArray coords(random(10) + 1);
// Первый узел - случайное положение.
coords[0] = CPoint(random(x), random(y));
// Остальные узлы - случайное положение в пределах +-25 пикселей по
// вертикали и горизонтали от предыдущего узла.
for (unsigned i = 1; i < coords.Count(); i++) {
coords[i].X(coords[i - 1].X() + (random(50) - 25));
coords[i].Y(coords[i - 1].Y() + (random(50) - 25));
}
// И саму ломаную.
f = new CPolyline(coords);
}
break;
case Set:
// Создаем объект класса множество фигур,
f = new CFigureSet();
// и рекурсивно вызываем CreateFigures для заполнения этого множества;
// дальнейшая рекурсия запрещена.
CreateFigures(*(CFigureSet *)f, nn, false);
break;
}
// Случайным образом выбираем цвет для созданной фигуры,
f->Color(Colors[random(NColors)]);
// и добаляем ее в заданное множество.
s.Add(*f);
// В ветку дерева с именем фигуры помещаем адрес самой фигуры.
nn->Data = f;
}
}
//---------------------------------------------------------------------------
void TfrmOOPExample::FreeFigures(CFigureSet &s)
{
CFigureSet::Iterator i;
// Для всех фигур множества s:
for (i = s.First(); i != s.End(); i++) {
// Берем адрес фигуры.
CFigure *f = *i;
// Механизм Runtime Type Identifiaction (RTTI) - определение типа во время выполнения,
// позволяет определить реальный тип объекта, на который указывает некоторый указатель
// на полиморфный класс.
// В данном случае используется операция typeid, которая возвращает константную ссылку на
// объект типа type_info, описывающий тип аргумента. Аргументом может быть либо тип данных,
// либо разыменованный указатель, либо ссылка.
// Для класса type_info определены операции равенства и неравентсва, что позволяет проверить,
// является ли данный объект объектом данного типа, что мы и делаем:
// Если f указывает на множество фигур, то (до удаления самого множества) удаляем фигуры,
// содержащиеся в нем при помощи FreeFigures.
if (typeid(*f) == typeid(CFigureSet))
FreeFigures(*(CFigureSet *)f);
// Удаляем фигуру.
// Операция delete вызывает деструктор. Поскольку деструктор виртуальный, то
// для каждого класса-фигуры будет вызван свой деструктор, несмотря то, что
// f имеет тип CFigure*. В противном случае всегда вызывался бы деструктор класса CFigure.
delete f;
}
}
//---------------------------------------------------------------------------
void TfrmOOPExample::DrawFigure(CFigure &f)
{
TCanvas *c = PB->Canvas;
// Если переключатель Color включен, то
if (Color->Checked) {
// устанавливаем цвет пера на канве PB равным выбранному в ColorBox,
c->Pen->Color = ColorBox->Selected;
// и рисуем фигуру этим цветом.
f.Draw(c);
}
// Иначе
else
// изображаем фигуру ее собственным цветом.
f.ColorDraw(c);
}
//---------------------------------------------------------------------------
// События
//---------------------------------------------------------------------------
void __fastcall TfrmOOPExample::FormCreate(TObject *Sender)
{
// При создании формы создаем фигуры.
Create->Click();
}
//---------------------------------------------------------------------------
void __fastcall TfrmOOPExample::FormDestroy(TObject *Sender)
{
// При уничтожении формы удаляем созданные фигуры.
FreeFigures(RandomSet);
}
//---------------------------------------------------------------------------
void __fastcall TfrmOOPExample::PBPaint(TObject *Sender)
{
// Изображаем случайный и заданный наборы фигур.
DrawFigure(RandomSet);
FixedSet.ColorDraw(PB->Canvas);
}
//---------------------------------------------------------------------------
void __fastcall TfrmOOPExample::CreateClick(TObject *Sender)
{
// Отключаем мигание (см. ниже) выбранной фигуры (если включено).
FlashTimer->Enabled = false;
// Удаляем динамически созданные фигуры, которые помещены в множество RandomSet.
FreeFigures(RandomSet);
// Опустошаем это множество (удалаем указатели на уже несуществующие фигуры).
RandomSet.Clear();
// Очищаем дерево фигур,
TV->Items->Clear();
// добавляем в него корневую ветку,
TTreeNode *root = TV->Items->Add(NULL, "Случайные фигуры");
// соответствующую множеству фигур RandomSet.
root->Data = &RandomSet;
// Создаем фигуры.
CreateFigures(RandomSet, root, true);
// Раскрываем корневую ветку.
root->Expand(false);
// И рисуем созданные фигуры.
PB->Repaint();
}
//---------------------------------------------------------------------------
void __fastcall TfrmOOPExample::ColorClick(TObject *Sender)
{
// При переключении переключателя Color:
// Задаем видимость ColorBox-а и
ColorBox->Visible = Color->Checked;
// перерисовываем фигуры.
PB->Repaint();
}
//---------------------------------------------------------------------------
void __fastcall TfrmOOPExample::ColorBoxClick(TObject *Sender)
{
// При изменении цвета перерисовываем фигуры.
PB->Repaint();
}
//---------------------------------------------------------------------------
void __fastcall TfrmOOPExample::TVClick(TObject *Sender)
{
// При щелчке по дереву:
// Если какая-либо ветка дерева выбрана, то:
if (TV->Selected) {
// Берем адрес фигуры, которой соответствует ветка.
CFigure *f = (CFigure *)TV->Selected->Data;
// Если ветка действительно соответсвует некоторой фигуре, то:
if (f) {
// Если какя-то фигура уже мигает и стерта, то
if (FlashTimer->Enabled && !(Flashs % 2))
// изображаем ее.
DrawFigure(*Flash);
// Устанавливаем число счетчик мигания.
Flashs = 11;
// Устанваливаем фигуру, которая мигает.
Flash = f;
// Включаем таймер мигания.
FlashTimer->Enabled = true;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TfrmOOPExample::FlashTimerTimer(TObject *Sender)
{
// Если уменьшенное значение счетчика мигания делится на 2, то
if (--Flashs % 2) {
// стираем фигуру.
PB->Canvas->Pen->Color = clBlack;
Flash->Draw(PB->Canvas);
}
// Иначе рисуем ее заново.
else
DrawFigure(*Flash);
// Если счетчик обнулился, выключаем мигание.
if (!Flashs)
FlashTimer->Enabled = false;
}
//---------------------------------------------------------------------------