- •Лабораторные работы по курсу «Инструментальные средства визуального программирования»
- •1. Программирование односвязного списка
- •1.1.Задание
- •1.2.Описание вариантов заданий
- •2.Перегрузка векторных и матричных операций
- •2.1.Задание
- •2.2.Бесценные методические указания
- •2.3.Некоторые особенности перегрузки операций
- •3.Классная работа
- •3.1.Постановка задачи
- •2.4.Варианты заданий
- •3.2.Задания
- •3.3.Методические наказания к первой части работы
- •3.4.Методические наказания ко второй части работы
- •4.Алгоритмы
- •Задание
- •Варианты классов и их обработки
- •5.Приложение WinForms (cli)
- •5.1.Задание
- •5.2.Бесценные методические предписания
- •Int nRec;//Число записей файла, оно же будет числом элементов массивов
- •6.Графика в WinForms (cli)
- •6.1.Задание
- •6.2.Бесценные методические предписания
- •6.3.Индивидуальные задания
- •7.1.Задание
- •7.2.Бесценные методические наставления
- •8.Квикли файдингуем рутсы
- •8.1.Дармовые методические рекомендации
- •8.2.Задание
- •Варианты индивидуальных заданий
- •9.Приложение, основанное на модальном диалоговом окне
- •9.1.Нудные методические указания Модальные и немодальные диалоговые окна
- •Ресурсы и элементы управления
- •Сценарий создания приложения
- •Разбор приложения
- •Усовершенствование приложения
- •10.Разработка графического редактора
- •Задание.
- •10.1.Проектирование программы
- •10.2.Разработка интерфейса
- •Установка флагов
- •Создание меню и панели инструментов
- •Обработка сообщений о нажатии кнопки мыши
- •10.3.Рисование
- •10.4.Растягивание фигур
- •10.5.Обновление изображения
- •10.6.Сохранение метафайла на диске и его загрузка
- •Список ссылок
- •Работы, выполненные в осеннем семестре 2016/2017 по курсу ооп
10.6.Сохранение метафайла на диске и его загрузка
Шаг 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() должен выглядеть примерно так:
|
Соберите приложение и проверьте, по крайней мере, то, что оно не потеряло работоспособность. Проверить корректность сохранения файла можно только путем его загрузки. Если Вы выполните команду FileSave приложения, то в каталоге проекта Вы должны обнаружить файл 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, то мы ее должны освободить. Где это сделать? И коню ясно, что в деструкторе:
|
Шаг 24. Самостоятельная работа по дальнейшему усовершенствованию гениального приложения.
1. Добавьте в приложение код, который позволит пользователю выбирать имя сохраняемого или открываемого файла с помощью стандартного диалога (класс CFileDialog) Windows. Пример использования класса CFileDialog имеется в разделе «Диалоги по выбору имени файла и каталога» конспекта лекций [3].
2. Добавьте вывод имени текущего файла в строку заголовка окна приложения с помощью функции AfxGetApp()->m_pMainWnd->SetWindowText("Имя_файла").
3. Добавьте к перечню фигур, обрабатываемых программой, свою фигуру в соответствии с номером вашего задания:
-
Номер задания
Фигура
1
Окружность
2
Равносторонний треугольник
3
Правильный пятиугольник
4
Куб
5
Цилиндр
6
Трапеция
7
Параллелограмм
8
Сектор круга
9
Конус
10
Квадрат с закругленными углами
11
Ромб
12
Правильный шестиугольник
