Многооконный графический редактор
Доработаем приложение Multi так, чтобы оно обладало возможностями приложения Single, описанного в томе 24 серии “Библиотека системного программиста”. Приложение Single представляет собой простейший графический редактор, в котором можно рисовать изображения, содержащие маленькие квадраты, а также сохранять эти рисунки в файлах на диске.
Добавьте в определение класса CMultiDoc новый элемент pointFigCenter, который будет хранить графический документ. Как и в приложении Single, этот элемент сделан на основе шаблона CArray. Однако вместо разработанного нами класса CFigure, здесь мы используем стандартный класс CPoint, входящий в состав MFC. Тип фигуры запоминать не надо, так как приложение Multi будет рисовать фигуры только одного типа:
class CMultiDoc : public CDocument
{
// Attributes
public:
CArray<CPoint, CPoint&> pointFigCenter;
Шаблоны классов CArray, CMap и CList определены во включаемом файле afxtempl.h. Так как мы используем класс CArray, добавьте файл afxtempl.h в конце включаемого файла stdafx.h:
#include <afxtempl.h>
Добавьте обработчик сообщения от левой кнопки мыши. Для этого лучше всего воспользоваться средствами MFC ClassWizard:
//////////////////////////////////////////////////////////////
// CMultiView message handlers
void CMultiView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO:
// Получаем указатель на документ (объект класса CSingleDoc)
CMultiDoc* pDoc = GetDocument();
// Проверяем указатель pDoc
ASSERT_VALID(pDoc);
// Отображаем на экране квадрат
CClientDC dc(this);
dc.Rectangle(
point.x-10, point.y-10, point.x+10, point.y+10);
// Добавляем к массиву, определяющему документ, новый
// элемент
pDoc->pointFigCenter.Add(point);
// Устанавливаем флаг изменения документа
pDoc->SetModifiedFlag();
// Вызываем метод OnLButtonDown базового класса CView
CView::OnLButtonDown(nFlags, point);
}
Обработчик этого сообщения рисует квадрат. Для отображения квадрата используется метод Rectangle. Первые два параметра этого метода определяют расположение левого верхнего угла параллелепипеда. Третий и четвертый параметры задают размеры по горизонтали и вертикали.
Затем добавляем к документу новый элемент, определяющий координаты верхнего левого угла квадрата. В данном случае графический документ приложения представляется массивом pointFigCenter, содержащим объекты класса CPoint.
Так как метод OnLButtonDown изменяет документ, устанавливаем флаг модификации документа, для чего вызываем метод SetModifiedFlag. Затем вызываем метод OnLButtonDown базового класса CView. На этом обработка сообщения завершается.
Приложение должно отображать документ, когда в окно просмотра поступает сообщение WM_PAINT. Для этого следует изменить метод OnDraw окна просмотра документа. MFC AppWizard определяет шаблон этого метода, вам остается только “наполнить” готовый шаблон.
Метод OnDraw должен уметь отображать документ в любой момент времени. Так как документ записан в массиве pointFigCenter класса документа, сначала надо определить указатель на документ, а потом последовательно отобразить на экране все его элементы:
//////////////////////////////////////////////////////////////
// CMultiView drawing
void CMultiView::OnDraw(CDC* pDC)
{
CMultiDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
int i;
for (i=0; i<pDoc->pointFigCenter.GetSize(); i++)
pDC->Rectangle(
pDoc->pointFigCenter[i].x-10,
pDoc->pointFigCenter[i].y-10,
pDoc->pointFigCenter[i].x+10,
pDoc->pointFigCenter[i].y+10
);
}
Переопределите метод DeleteContents класса CMultiDoc так, чтобы он удалял содержимое документа. Для этого достаточно удалить все элементы массива pointFigCenter, воспользовавшись методом RemoveAll класса CArray. После очистки документа необходимо вызвать метод DeleteContents базового класса CDocument.
Чтобы вставить в класс CMultiDoc метод DeleteContents используйте MFC ClassWizard, а затем модифицируйте его в соответствии со следующим фрагментом кода:
//////////////////////////////////////////////////////////////
// CMultiDoc commands
void CMultiDoc::DeleteContents()
{
// Очищаем документ, удаляя все элементы массива arrayFig.
pointFigCenter.RemoveAll( );
// Вызываем метод DeleteContents базового класса CDocument
CDocument::DeleteContents();
}
Теперь, когда документ создан и приложение умеет отображать его на экране, остается доработать приложение, чтобы оно могло сохранять документ в файле на диске и загружать уже существующие документы из файлов. Для этого переопределите метод Serialize класса документа. Шаблон для этого метода уже определен в приложении:
//////////////////////////////////////////////////////////////
// CMultiDoc serialization
void CMultiDoc::Serialize(CArchive& ar)
{
pointFigCenter.Serialize(ar);
}
Постройте измененное приложение и запустите полученный выполнимый файл. У вас получился настоящий многооконный графический редактор. Вы можете одновременно открыть несколько окон с документами. Каждый документ можно сохранить в отдельном файле на диске и загрузить при следующем запуске приложения.