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

Сохранение метафайла на диске и его загрузка




 

Шаг 21. Сохранение метафайла на диске.

В нашем приложении мы используем метафайл, который как таковой не является дисковым файлом и существует только в ОЗУ. Для сохранения метафайла на диске в классе CMetaFileDC имеется метод CopyMetaFile().

Замечание. Можно было бы сделать наш метафайл дисковым файлом, указав его имя в качестве параметра метода Create(), но для нашей цели это было бы неэффективное решение.

 

Сохранение метафайла разумно привязать к команде меню File→Save. Создайте с помощью мастера обработчик этой команды, имеющей идентификатор ID_FILE_SAVE. Не забудьте при этом выбрать создание обработчика именно в классе вида CPainterView. Примите имя OnFileSave() для обработчика команды сохранения файла. Имя файла пока просто «зашьем» в программу в виде константы, для чего надо добавить в заголовочный файл PainterDoc.h объявление член-данных HMETAFILE MetaFileHandle и CString MetaFileName (в то же место, что и объявление прежде описанного указателя pMetaFileDC), а в конструкторе класса CPainterDoc (файл PainterDoc.срр) задайте имя файла:

MetaFileName=”Painter.wmf”;

 

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

 
 

Соберите приложение и проверьте, по крайней мере, то, что оно не потеряло работоспособность. Проверить корректность сохранения файла можно только путем его загрузки. Если Вы выполните команду FileèSave приложения, то в каталоге проекта Вы должны обнаружить файл Painter.wmf и даже просмотреть его содержимое с помощью какого-нибудь подходящего средства.

Шаг 22. Загрузка метафайла с диска.

Создайте обработчик OnFileOpen() команды меню File→Open. Добавьте в него код загрузки метафайла:

 

Приведенный код позволяет создать только дескриптор файла, но еще, конечно не воспроизводит его и не делает собственно тем метафайлом, который мы используем в других методах программы. Опять-таки, как и в методе OnDraw(), надо создать новый метафайл, воспроизвести в нем загруженный с диска метафайл и заменить старый метафайл новым. Для обновления содержимого окна вида надо вызвать метод Invalidate(). Вот новая версия OnFileOpen():

 

Тестируйте программу, проверив ее работоспособность в различных режимах. Обратите внимание, что в функции OnFileOpen() мы объявляем локальный дескриптор MetaFileHandle, хотя могли бы воспользоваться и дескриптором с таким же именем, объявленным в классе документа.

Шаг 23. Создание нового метафайла.

Любое приложение, претендующее на роль полноценного приложения с удобным для пользователя интерфейсом, должно позволять создавать новые файлы. Сделаем это и мы. Для достижения этой благородной цели надо создать обработчик OnFileNew() команды меню File→New. Проделайте это.

В обработчике мы должны создать новый (пустой) метафайл, удалить текущий метафайл, установить новый метафайл в качестве текущего и обновить окно вида:

 

 
 

 

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

Теперь уже настало самое время посмотреть на содержимое окна Debug после (удачного?) завершения приложения. В нем Вы можете (и скорее всего уже смогли) обнаружить и такое сообщение примерно такого содержания (ключевая фраза «Detected memory leaks!»):

Detected memory leaks!

Dumping objects ->

D:\Workdir\ISVP\Projects\Painter\PainterView.cpp(86): {105} client block at 0x00325B58, subtype 0, 16 bytes long.

a CMetaFileDC object at $00325B58, 16 bytes long

 

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

CMetaFileDC * NewMetaFile = new CMetaFileDC();

 

Раз мы выделили память для объекта NewMetaFile, то мы ее должны освободить. Где это сделать? И коню ясно, что в деструкторе:

 

Поделиться:





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



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