Сохранение метафайла на диске и его загрузка
⇐ ПредыдущаяСтр 19 из 19
Шаг 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 Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|