Метафайлом называется хранящийся в памяти объект, поддерживающий собственный контекст устройства. Любые операции с контекстом следует продублировать в метафайле. Если позже потребуется повторить эти действия (при обновлении изображения) достаточно воспроизвести этот метафайл. В результате все графические операции повторяются, что приводит к автоматическому созданию нужных изображений.
Есть класс CMetaFileDC. Его конструктор CMetaFileDC() конструирует объект этого класса.
Метод Create() создает контекст устройства Windows для метафайла и связывает его с объектом CMetaFileDC. После создания контекста устройства для метафайла в нем можно рисовать, дублируя графические операции в окне. Когда требуется обновить изображение, просто нужно воспроизвести этот метафайл.
Метод Close() закрывает контекст устройства и (что очень важно!)создает логический номер метафайла.
Метод PlayMetaFile( логический_номер_метафайла) воспроизводит метафайл по его логическому номеру.
Итак, для обновления изображения в окне нужно:
а) Включить в заголовочный файл документа указатель pMetaFileDC на контекст устройства метафайла, который будет использоваться в программе.
Для этого выделить класс Cgraf_painterDoc, вызвать контекстное меню, Add Variable. Указать тип переменной CMetaFileDC* и ввести имя указателя.
б) В конструктор Cgraf_painterDoc() добавить выделение памяти и вызов метода Create() для создания нового объекта.
Cgraf_painterDoc::Cgraf_painterDoc()
: pMetaFileDC(NULL)
{
pMetaFileDC=new CMetaFileDC();
pMetaFileDC->Create();
// TODO: add one-time construction code here
}
В результате создан контекст устройства для метафайла,в котором будут дублироваться все действия пользователя.
в) Добавить в обработчики событий нажатия кнопки мыши и её перемещения
дублирование графических операций в метафайле. Все, что пользователь рисует на экране, должно дублироваться в метафайле. Это означает, что при каждом вызове метода для контекста устройства вида необходимо вызвать аналогичный метод для контекста метафайла.
В результате обработчик отпускания левой кнопки мыши имеет вид:
void Cgraf_painterView::OnLButtonUp(UINT nFlags, CPoint point)
{
Cgraf_painterDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
DrawTo.x=point.x;
DrawTo.y=point.y;
CClientDC*pDC=new CClientDC(this);
if(bLineFlag)
{
pDC->MoveTo(Anchor.x,Anchor.y);
pDC->LineTo(DrawTo.x,DrawTo.y);
pDoc->pMetaFileDC->MoveTo(Anchor.x,Anchor.y);
pDoc->pMetaFileDC->LineTo(DrawTo.x,DrawTo.y);
}
if(bRectangleFlag)
{
pDC->MoveTo(Anchor.x,Anchor.y);
pDC->Rectangle(Anchor.x,Anchor.y,DrawTo.x,DrawTo.y);
pDoc->pMetaFileDC->MoveTo(Anchor.x,Anchor.y);
pDoc->pMetaFileDC->Rectangle(Anchor.x,Anchor.y,DrawTo.x,DrawTo.y);
}
if(bEllipseFlag)
{
pDC->MoveTo(Anchor.x,Anchor.y);
pDC->Ellipse(Anchor.x,Anchor.y,DrawTo.x,DrawTo.y);
pDoc->pMetaFileDC->MoveTo(Anchor.x,Anchor.y);
pDoc->pMetaFileDC->Ellipse(Anchor.x,Anchor.y,DrawTo.x,DrawTo.y);
}
if(bFillFlag)
{
pDC->SelectStockObject(BLACK_BRUSH);
pDC->FloodFill(Anchor.x,Anchor.y,RGB(0,0,0));
pDoc->pMetaFileDC->SelectStockObject(BLACK_BRUSH);
pDoc->pMetaFileDC->FloodFill(Anchor.x,Anchor.y,RGB(0,0,0));
}
delete pDC;//Удаляем указатель на текущий вид
// TODO: Add your message handler code here and/or call default
CView::OnLButtonUp(nFlags, point);
}
Следует обратить внимание на то, что указатель pMetaFileDC является элементом данных класса Cgraf_painterDoc. Поэтому, чтобы с его помощью вызывать методы класса CMetaFileDC, аналогичные методам для контекста устройства вида, описан указатель Cgraf_painterDoc*pDoc=GetDocument();
Произвольная фигура рисуется при перемещении мыши. Поэтому аналогичное дублирование нужно добавить в соответствующем обработчике.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.