КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Обновление изображения
Метафайлом называется хранящийся в памяти объект, поддерживающий собственный контекст устройства. Любые операции, выполняемые с контекстом устройства, можно продублировать в метафайле. Если в дальнейшем потребуется повторить действия, выполненные пользователем (например, при обновлении изображения), достаточно воспроизвести данный метафайл. В результате такого воспроизведения все графические операции повторяются и изображение восстанавливается. Шаг 18. Описание и инициализация класса метафайл. Указатель на контекст устройства для метафайла CMetaFileDC имеет смысл описать в классе документа СPainterDoc. Для этого в заголовочный файл PainterDoc.h добавьте описание указателя: // PainterDoc.h: interface of the CPainterDoc class // … class CPainterDoc: public CDocument { // … // Implementation public: virtual ~CPainterDoc(); CMetaFileDC *pMetaFileDC;
В конструкторе класса документа мы должны инициализировать указатель pMetaFileDC, создав объект класса CMetaFileDC: // PainterDoc.cpp: implementation of the CPainterDoc class // … 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. После этого можно подменить старый метафайл новым и удалить старый метафайл.
Соберите и тестируйте приложение. Проверьте, что однажды созданное изображение сохраняется при любых трансформациях окна: сворачивании, разворачивании, изменении размеров и т.д. Итак, на этом этапе мы получили способ, с помощью которого можно сохранять изображение в окне вида.
Дата добавления: 2014-12-26; Просмотров: 496; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |