CRect m _ EnclosingRect ;//прямоугольник, описывающий элемент
public:
CElement();
virtual ~CElement();
virtual void Draw(CDC* pDC){}// виртуальная операция рисования
CRect GetBoundRect() const;// получить ограничивающий прямоугольник
};
5. Каждый элемент будет хранить информацию об описывающем прямоугольнике в переменной m_EnclosingRect базового класса. Для определения ограничивающего прямоугольника с учетом толщины пера реализуйте метод GetBoundRect в файле Element . cpp:
CRect CElement::GetBoundRect() const
{
CRect boundingRect(m_EnclosingRect);// переменная для хранения ограничивающего прямоугольника
boundingRect.InflateRect(m_PenWidth,m_PenWidth);//расширить прямоугольник на ширину пера
return boundingRect;
}
6. Выделите приложение mfc2 в окне классов и нажатием ПК мыши вызовите контекстное меню. В меню выберите пункт «Добавить|Класс». В появившемся окне выберите шаблон «Класс C++». Нажмите кнопку «Добавить».
7. Введите имя класса CLine, в поле базовый класс – CElement.В поля Файл.h и Файл.cpp выберите соответственно Element. h и Element. cpp.
8. В описание класса CLine добавьте следующий код:
class CLine : public CElement
{
public:
CLine(void);
~CLine(void);
virtual void Draw(CDC* pDC);// Функция отображения линии
CLine (const CPoint& start,const CPoint& end,COLORREF aColor);// конструктор объекта линии
protected :
CPoint m_StartPoint;
CPoint m_EndPoint;
};
9. В файле Element. cpp реализуйте конструктор класс CLine:
CLine::CLine(const CPoint& start,const CPoint& end,COLORREF aColor):m_StartPoint(start),m_EndPoint(end)
{
m_PenWidth=1;
m_Color=aColor;
//Определение описывающего прямоугольника
m_EnclosingRect=CRect(start,end);
m_EnclosingRect.NormalizeRect(); }
10. Реализуйте метод Draw класса CLine. Ниже приведен программный код:
|
|
void CLine::Draw(CDC* pDC)
{
CPen aPen;
if (!aPen.CreatePen(PS_SOLID,m_PenWidth,m_Color))
{
AfxMessageBox(_T("Не удалось создать перо!"),MB_OK);
AfxAbort();
}
CPen* pOldPen=pDC->SelectObject(&aPen);
pDC->MoveTo(m_StartPoint);
pDC->LineTo(m_EndPoint);
pDC->SelectObject(pOldPen);
}
11. Добавьте в проект класс CRectangle аналогично, как CLine. Описание класса представлено ниже:
class CRectangle :
public CElement
{
public:
CRectangle(void);
~CRectangle(void);
virtual void Draw(CDC* pDC);//Функция отображения линии
CRectangle (const CPoint& start,const CPoint& end,COLORREF aColor);//конструктор объекта прямоугольник
};
12. Реализуйте конструктор класса CRectangle:
CRectangle::CRectangle(const CPoint& start,const CPoint& end,COLORREF aColor)
{
m_PenWidth=1;
m_Color=aColor;
//Определение описывающего прямоугольника
m_EnclosingRect=CRect(start,end);
m_EnclosingRect.NormalizeRect();
}
13. Напишите программный код метода Draw() класса CRectangle. Будем рисовать только контур прямоугольника, поэтому в качестве кисти будем использовать стандартную кисть NULL_ BRUSH. Ниже представлен код:
void CRectangle::Draw(CDC* pDC)
{
CPen aPen;
if (!aPen.CreatePen(PS_SOLID,m_PenWidth,m_Color))
{
AfxMessageBox(_T("Не удалось создать перо!"),MB_OK);
AfxAbort();
}
CPen* pOldPen=pDC->SelectObject(&aPen);
CBrush* pOldBrush=(CBrush*)pDC->SelectStockObject(NULL_BRUSH);
pDC->Rectangle(m_EnclosingRect);
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
|
|
}
14. Добавьте в проект класс CCircle, аналогично, как класс CRectangle в пункте 11.
15. Напишите конструктор класса CCircle, как приведено ниже:
CCircle::CCircle (const CPoint& start,const CPoint& end,COLORREF aColor)
{
long radius=static_cast<long>(sqrt(static_cast<double>((end.x-start.x)*(end.x-start.x)+(end.y-start.y)*(end.y-start.y))));
m_EnclosingRect=CRect(start.x-radius,start.y-radius,start.x+radius,start.y+radius);
m_EnclosingRect.NormalizeRect();
m_Color=aColor;
m_PenWidth=1;
}
16. Для использования функции sqrt() необходимо в файл Element. cpp библиотеку cmath.
17. Реализуйте код рисования окружности для класса CCircle:
void CCircle::Draw(CDC* pDC)
{
CPen aPen;
if (!aPen.CreatePen(PS_SOLID,m_PenWidth,m_Color))
{
AfxMessageBox(_T("Не удалось создать перо!"),MB_OK);
AfxAbort();
}
CPen* pOldPen=pDC->SelectObject(&aPen);
CBrush* pOldBrush=(CBrush*)pDC->SelectStockObject(NULL_BRUSH);
pDC->Ellipse(m_EnclosingRect);//рисование окружности
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
}
18. Добавьте в проект класс CCurve:
class CCurve : public CElement
{
public:
CCurve(void);
~CCurve(void);
virtual void Draw(CDC* pDC);//Функция отображения кривой
CCurve (const CPoint& first,const CPoint& second,COLORREF aColor);//конструктор объекта кривой
void AddSegment(const CPoint& point);//добавить сегмент кривой
protected:
std::vector<CPoint> m_Points;//множество точек, определяющих кривую
};
19. Подключите к файлу Element. h библиотеку vector.
20. Добавьте определение конструктора класса CCurve:
|
|
CCurve::CCurve (const CPoint& first,const CPoint& second,COLORREF aColor)
{
m_Points.push_back(first);
m_Points.push_back(second);
m_EnclosingRect=CRect(min(first.x,second.x),
min(first.y,second.y),
max(first.x,second.x),
max(first.y,second.y));
m_Color=aColor;
m_PenWidth=1;
}
21. Напишите метод прорисовки кривой класса CCurve:
void CCurve::Draw(CDC* pDC)
{
CPen aPen;
if (!aPen.CreatePen(PS_SOLID,m_PenWidth,m_Color))
{
AfxMessageBox(_T("Не удалось создать перо!"),MB_OK);
AfxAbort();
}
CPen* pOldPen=pDC->SelectObject(&aPen);
pDC->MoveTo(m_Points[0]);
for (size_t i=1;i<m_Points.size();++i)
pDC->LineTo(m_Points[i]);
pDC->SelectObject(pOldPen);
}
22. Добавьте метод добавления новой точки к кривой:
void CCurve::AddSegment(const CPoint& point)
{
m_Points.push_back(point);
m_EnclosingRect=CRect(min(point.x,m_EnclosingRect.left),
min(point.y,m_EnclosingRect.top),
max(point.x,m_EnclosingRect.right),
min(point.y,m_EnclosingRect.bottom));
}
23. Добавьте в класс документа методы, которые позволяют получить тип выбранного пользователем элемент и цвет пера, которые были определены в работе №4:
unsigned int Cmfc2Doc::GetElementType(void)
{
return m_Element;
}
COLORREF Cmfc2Doc::GetColorElement(void)
{
return m_Color;
}
24. Добавьте метод CreateElement в класс представления:
|
|
CElement* Cmfc2View::CreateElement(void) const
{
Cmfc2Doc* pDoc=GetDocument();
ASSERT_VALID(pDoc);
switch (pDoc->GetElementType()){
case RECTANGLE:
return new CRectangle(m_FirstPoint,m_SecondPoint,pDoc->GetColorElement);
case LINE:
return new CLine(m_FirstPoint,m_SecondPoint,pDoc->GetColorElement());
case CIRCLE:
return new CCircle(m_FirstPoint,m_SecondPoint,pDoc->GetColorElement());
case CURVE:
return new CCurve(m_FirstPoint,m_SecondPoint,pDoc->GetColorElement());
default:
AfxMessageBox(_T("Неверный код элемента"),MB_OK);
AfxAbort();
return nullptr;
}
return NULL;
}
25. В файл Cmfc2View.h включите библиотеку Element.h.
26. Добавьте в класс представления переменную m_FirstPoint и m_SecondPoint типа CPoint и инициализируйте их в конструкторе класса значением CPoint(0,0).
27. Добавьте в класс представления указатель m_ pTempElement и инициализируйте его в конструкторе класса значением nullptr.
28. Создайте обработчик сообщения нажатия левой кнопки мыши в классе представления. Для этого в обозревателе классов выделите Cmfc2 View и в окне свойств нажмите кнопку «Сообщения». Найдите сообщение WM_ LBUTTON_ DOWN, нажмите на стрелку и выберите пункт «Add».
Рисунок 6.3 –Создание обработчика события мыши
29. В обработчике события нажатия ЛК мыши сохраните координаты:
void Cmfc2View::OnLButtonDown(UINT nFlags, CPoint point)
{
m_FirstPoint=point;
}
30. Добавьте обработчик события перемещения мыши в классе представления:
void Cmfc2View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: добавьте свой код обработчика сообщений или вызов стандартного
CClientDC aDC(this);//контекст устройства для данного представления
if (nFlags&&MK_LBUTTON)//проверить, что нажата левая кнопка
{
m_SecondPoint=point;//сохранить координаты мыши
if (m_pTempElement)
{
if (CURVE==GetDocument()->GetElementType())//если это кривая
{
static_cast<CCurve*>(m_pTempElement)->AddSegment(m_SecondPoint);
m_pTempElement->Draw(&aDC);
return;
}
//перерисовываем старый элемент, чтобы он исчез
aDC.SetROP2(R2_NOTXORPEN);
m_pTempElement->Draw(&aDC);
delete m_pTempElement;
m_pTempElement=nullptr;
}
m_pTempElement=CreateElement();//создать новый элемент
m_pTempElement->Draw(&aDC);//нарисовать элемент
}
}
31. Создайте обработчик события отпускания кнопки мыши в классе представления:
void Cmfc2View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: добавьте свой код обработчика сообщений или вызов стандартного
if (m_pTempElement)
{
delete m_pTempElement;
m_pTempElement=nullptr;
}
32. Для того чтобы обрабатывать сообщения мыши при выходе за пределы клиентской области добавьте в обработчике следующие строчки:
void Cmfc2View::OnLButtonDown(UINT nFlags, CPoint point)
{
m_FirstPoint=point;
SetCapture();//перехватывать все последующие сообщения мыши
}
void Cmfc2View::OnLButtonUp(UINT nFlags, CPoint point)
{
if (this==GetCapture())
Дата добавления: 2019-09-13; просмотров: 337; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!