Иллюстрированный самоучитель по Visual Studio .NET

Конструкторы и операции

Метод GetRect получает на входе ссылки на две характерные точки прямоугольника, обрамляющего весь полигон, вычисляет координаты этих точек и возвращает их с помощью механизма передачи ссылкой:

void CPolygon::GetRect(CDPointS ptLT, CDPointi ptRB)
{
m_ptLT = m_ptRB = CDPoint(0., 0.);
//====== Если полигон содержит точки контура
UINT n = ra_Points.size();
if (n > 0)
{
//====== Пробег по всем его точкам
for (UINT 1=0; i<n; i++)
{
//====== Поиск и запоминание экстремумов
double х = m_Points[i].x,
у = m_Points[i].у;
if (x < m_ptLT.x) m_ptLT.x = x;
else if (x > m_ptRB.x)
m_ptRB.x = m_Points[i].x; if (y > m_ptLT.y) ra_ptLT.y = y;
else if (y < m_ptRB.y)
m_ptRB.y = y;
}
}
//====== Возвращаем найденные координаты (ссылками)
ptLT = m_ptLT; ptRB = m_ptRB;
}

Метод сериализации данных полигона, приведенный ниже, мог бы быть более компактным, если бы для хранения точек полигона мы воспользовались бы одним из шаблонов семейства классов Collection библиотеки MFC. В эти классы уже встроена возможность сериализации. Но у нас на вооружении шаблон классов vector из другой библиотеки STL, так как он обладает рядом других привлекательных черт. За это приходится платить несколькими лишними строками кода, в котором все точки контейнера либо помещаются в архив, либо выбираются из него:

void CPolygon::Serialize (CArchiveS ar) {
//====== Если идет запись в архив,
if (ar. IsStoring() }
{
//=== то последовательно переносим туда все данные
m << m_nPenWidth << m_PenColor << m_BrushColor << m_Points .size ()
<< m_ptLT.x << m_ptLT.y << m_ptRB.x << m_ptRB.y;
for (UINT i=0; i <m_Points .size 0;
m << m_Points [i].x << m_Points [i] .y;
}
else
{
//=== При чтении из архива меняем направление обмена
UINT size;
m >> m_nPenWidth >> m_PenColor >> m_BrushColor
>> size >> m_ptLT.x >> m_ptLT.y
>> m_ptRB.x >> m_ptRB.y;
//====== Заново создаем контейнер точек полигона
m_Points .clear ();
while (size--)
{
double x, y;
m >> x >> y;
m_Points .oush back (CDPoint (x, v));
}
}
}

Ниже приведена функция рисования полигона в переданный ей в качестве параметра контекст устройства. Второй параметр является флагом, который задает способ заливки полигона. В операциях визуального редактирования, которое мы введем позже, полигон должен временно терять свой цвет, для того чтобы не было мелькания при частых перерисовках.

Напомним, что полигон хранит World-координаты всех своих точек в контейнере m_Points. Переход к Page-координатам производится с помощью функции MapToLogPt, которую мы еще должны разработать и поместить в класс документа. Двигаясь далее по коду функции Draw, мы видим, как объект настраивает контекст устройства с помощью своих личных атрибутов и изображает себя в этом контексте:

void CPolygon::Draw (CDC *pDC, bool bContour)
{
//====== Размер контейнера World-координат точек
UINT nPoints = m_Points.size();
if (!nPoints) return;
//====== Временный массив логических координат точек
CPoint *pts = new CPoint[nPoints];
//====== Преобразование координат
for (UINT i=0; KnPoints; i++)
pts[i] = m_pDoc › MapToLogPt(m_Points[i]);
pDC › SaveDC();
CPen pen (PS_SOLID,m_nPenWidth,m_PenColor);
pDC › SelectObject(Spen);
CBrush brush (bContour? GetSysColor(COLOR_WINDOW): m_BrushColor);
pDC › SelectObject(ibrush);
//====== Полигон изображается в предварительно
//====== подготовленном контексте устройства
pDC › Polygon(pts, nPoints);
//====== Освобождаем массив
delete [] pts;
pDC › RestoreDC(-1);
}
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.