Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

CPainterDoc::CPainterDoc()




{

pMetaFileDC= new CMetaFileDC;

pMetaFileDC->Create();

}

 

Теперь мы подготовили указатель на контекст метафайла к работе и им можно пользоваться.

Шаг 19. Дублирование графических операций в метафайле.

Все, что пользователь рисует в окне, должно дублироваться в метафайле. Это означает, что при каждом вызове метода для контекста устройства вида необходимо вызвать аналогичный метод для контекста метафайла. (Естественно, что вызовы методов по «растягиванию» фигур дублировать смысла нет.) Например, в случае рисования линий и прямоугольников это делается так:

 
 

 

В приведенном фрагменте метода OnLButtonUp() добавления выделены комментарием /*!*/. Вы должны дополнить метод OnLButtonUp() операторами, обеспечивающими запись в метафайл кода заливки фигур по аналогии с записью линий и прямоугольников. Кроме того, Вы должны добавить код записи в метафайл фигуры произвольной формы, для чего надо модифицировать метод OnMouseMove() по аналогии с тем, как изображения записываются в метафайл в методе OnLButtonUp().

Так как указатель pMetaFileDC объявлен в классе документа, то для его использования надо иметь ссылку на объект документ типа CPainterDoc. Такую ссылку получают с помощью специально предназначенного для этой цели метода CPainterView:: GetDocument():

CPainterDoc *pDoc = GetDocument();

 

Обратите внимание на тот факт, что объект документ создавать не нужно и нельзя, так же как и уничтожать его: эту работу выполняет каркас приложения. Можно и нужно только получить указатель на этот объект. Реализацию метода CPainterView::GetDocument() Вы можете посмотреть в файле PainterView.h. А где находится еще одна реализация метода CPainterView::GetDocument()?

 

Вопрос. Существует объект класса вид, равно как и объект документ. Где они описаны?

 

Соберите программу и проверьте ее работу. Что-нибудь изменилось? Попробуйте что-нибудь нарисовать, свернуть окно и восстановить. Рисунок восстановился или нет? Если восстановился – позовите инженера: пусть он проверит компьютер.

Шаг 20. Воспроизведение метафайла.

За обновление изображения отвечает метод CPainterView::OnDraw(), который мы пока не модифицировали и он практически ничего не делает. А Вы еще не забыли, как тогда изображение появляется в окне вида. Если забыли – вновь просмотрите шаг 10.

Для того чтобы изображение в окне вида восстанавливалось, надо просто в методе CPainterView::OnDraw() воспроизвести метафайл.

 

Замечание. Вспомним, что метафайлом называют независимый от устройств формат графического файла, позволяющий сочетать растровое и векторное описание изображения. Существует несколько форматов метафайлов, например, Computer Graphics Metafile (файлы с расширением.CGM), Windows Metafile (файлы с расширением.WMF). Windows Metafile хранит не само изображение, а команды GDI, используемые для его создания.

 

Подобно любому другому файлу, метафайл надо открывать (или создавать) и закрывать. Очевидно, что сначала в методе OnDraw() метафайл надо закрыть, а затем воспроизвести его. Воспроизведение метафайла выполняет метод PlayMetaFile(), единственным параметром которого является дескриптор (логический номер) метафайла, который, в частности, возвращает метод закрытия метафайла Close().

Итак, для воспроизведения метафайла метод OnDraw() надо привести к следующему виду:

 
 

 

Код функции OnDraw() нуждается в некоторых комментариях.

Во-первых, «стандартным» приемом поиска ошибки является отладка, однако этот способ не годится для трассировки метода OnDraw(), так как он будет вызываться постоянно для перерисовки изображения. В этом случае удобно воспользоваться отладочной печатью, применив для этой цели макрос TRACE. Параметры у этого макроса такие же, как и у функции printf(). Ценным качеством TRACE является тот факт, что он работает только в отладочной версии программы (и игнорируется в окончательной сборке) и выводит сообщения на вкладку Debug окна вывода Output.

Во-вторых, когда Вы используете в своей программе указатели, то хорошим стилем программирования считается проверка корректности указателя перед его использованием: указатель не должен быть равен 0. Обратите внимание, например, на макрос ASSERT_VALID(pDoc), который имеется в методе OnDraw(). Что он делает? Да проверяет корректность указателя pDoc (только в отладочной версии приложения). Если указатель некорректен, выводится окно с сообщением об ошибке (рис. 7), текст в котором начинается с “Debug Assertion Failed”.

 
 

Рис. 7. Окно с сообщением об ошибке, инициированное макросом ASSERT_VALID

 

Если Вы внимательно посмотрите на код скелета приложения, сгенерированный ИС, то обнаружите там немалое число макросов ASSERT_VALID, ASSERT, методов AssertValid(), проверок типа if (!CDocument::OnNewDocument()) и т.п.

Сравнительно длинный код метода OnDraw() объясняется следующим. Для того чтобы можно было воспроизвести метафайл (т.е. восстановить изображение в окне) с помощью метода PlayMetaFile(), этот файл надо предварительно закрыть. Далее, класс CMetaFileDC не имеет метода открытия метафайла для дописывания в него новых изображений (точнее, команд генерации этих изображений). Выход такой: надо создать новый метафайл и воспроизвести в нем старый, для которого у нас есть логический номер MetaFileHandle. После этого можно подменить старый метафайл новым и удалить старый метафайл.

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

Итак, на этом этапе мы получили способ, с помощью которого можно сохранять изображение в окне вида.

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...