Студопедия

КАТЕГОРИИ:


Архитектура-(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; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.015 сек.