
- •Овсянник в.Н. Лабораторные работы по курсу «Объектно-ориентированное программирование»
- •13. Разработка приложения с архитектурой «документ-вид». Часть 2 120
- •14. Разработка приложения с архитектурой «документ-вид». Часть 3 135
- •1.Разработка типового консольного приложения
- •1.1.Методические указания
- •1. Запуск и настройка ис mvs-2008.
- •2.Поиск данных в массиве
- •3.Обработка текстового файла
- •4.Задача «куча камней»
- •5.Реализация алгоритма полного перебора
- •6. Исследование погрешностей вычислений
- •7.Поиск экстремумов с ограничениями или «Брачное агенство»
- •Постановка задачи
- •Задание
- •Листинг файла mAgency.Cpp (с главной функцией)
- •Листинг файла Lib.H
- •Листинг файла Lib.Cpp
- •8.Приложение с окном вида
- •9.Разработка графического редактора
- •Задание.
- •9.1.Проектирование программы
- •9.2.Разработка интерфейса
- •Установка флагов
- •Создание меню и панели инструментов
- •Обработка сообщений о нажатии кнопки мыши
- •9.3.Рисование
- •9.4.Растягивание фигур
- •9.5.Обновление изображения
- •9.6.Сохранение метафайла на диске и его загрузка
- •10.Приложение, основанное на модальном диалоговом окне
- •Методические указания Модальные и немодальные диалоговые окна
- •Ресурсы и элементы управления
- •Сценарий создания приложения
- •Разбор приложения
- •Усовершенствование приложения
- •11.Приложение с контекстным меню и строкой состояния
- •11.1.Методические указания к первой части работы
- •11.2.Сценарий выполнения первой части работы
- •11.3.Методические указания ко второй части работы Строка состояния
- •Определение секций в строке состояния
- •Строка сообщений
- •Индикатор состояния
- •Управление строкой состояния
- •11.4.Сценарий выполнения второй части работы
- •12.Разработка приложения с архитектурой «документ-вид». Часть 1
- •12.1.Сценарий создания приложения
- •13.Разработка приложения с архитектурой «документ-вид». Часть 2
- •13.1.Методические указания Класс коллекций cObList
- •13.2.Сценарий выполнения работы
- •14.Разработка приложения с архитектурой «документ-вид». Часть 3
- •14.1.Методические указания
- •15.Класс вектор
- •15.1.Пример класса tVector
- •15.2.Класс tVector с перегруженными операциями
- •16.Приложение с таблицей
- •16.1.Вариант 1 Сценарий выполнения работы
- •16.2.Вариант 2 Сценарий выполнения работы
11.2.Сценарий выполнения первой части работы
Шаг 1. Создайте приложение MFC с графическим интерфейсом (не консольное). Предполагается, что проекту присвоено имя CNTXMenu. Оставьте все свойства по умолчанию, кроме типа приложения: выберите, для разнообразия, приложение с единственным документом и без поддержки архитектуры документ/вид (рис. 1). Налягьте на Finish.
|
Рис. 1. Задание вида приложения
Сгенерированное мастером приложение имеет класс вида CChildView, класс окна-рамки CMainFrm и класс приложения CCNTXMenu – проверьте на всякий случай, все ли Вам выдали мастера ИС.
Шаг 2. Изменим начальный размер окна приложения, несколько уменьшив его по сравнению с размером по умолчанию. Для этого в конец функции CCNTXMenuApp::InitInstance() добавим следующий код:
|
Шаг 3. Добавьте в программу меню в соответствии с приведенными выше желанными методическими указаниями. Для этого создайте новый ресурс меню с такими командами и ресурсными идентификаторами:
Команда меню |
Идентификатор |
Загрузка файла с изображением |
ID_OPENIMAGE |
Сохранение изображения в файле |
ID_SAVEIMAGE |
Растянуть изображение на все окно |
ID_SIZE_FILL |
Масштаб 50% |
ID_SIZE_HALF |
Масштаб 100% |
ID_SIZE_ORIGINAL |
Масштаб 200% |
ID_SIZE_DOUBLE |
Для всего меню задайте идентификатор IDR_CNTXMENU.
Замечание. Конечно, на шаге 2 для изменения размеров окна при запуске можно было бы просто запустить программу на выполнение, изменить размеры окна программы и элементарно завершить ее работу: в следующий раз при запуске программа, как миленькая, имела бы заданный Вами мануально нужный размер окна. Но мы легких путей не ищем, не так ли? Ну и кроме того наш путь лучше – догадайтесь почему и поделитесь своей прозорливой догадкой с преподавателем.
Шаг 4. Добавьте в класс вида CChildView обработчик сообщения WM_CONTEXTMENU:
|
Запустите приложение на выполнение и проверьте вызов контекстного меню с помощью ПКМ. Если получилось – похвалите себя, пока не поздно. Прочтите в MSDN, для чего предназначена функция CMenu::TrackPopupMenu() и какие она имеет параметры, а то не сможете ответить на контрольно-убийственный вопрос преподавателя.
Шаг 5. Добавьте в файл ChildView.h подключение заголовочных файлов и описание перечисления (в глобальную область, перед описанием класса CChildView):
|
В тело класса CChildView (тот же файл ChildView.h) добавьте описание таких членов:
private:
CImage imgOriginal;
int m_nFilterLoad;
SizesEnum m_nImageSize;
MFC класс CImage мы будем использовать для работы с изображениями, а в переменной m_nFilterLoad будет храниться индекс текущего выбранного фильтра загруженного файла.
В конструкторе класса CChildView (файл ChildView.cpp) инициализируйте переменную:
m_nImageSize = SIZE_NONE;
Проверьте, что приложение компилируется и собирается без ошибок.
Шаг 6. Добавьте в класс вида обработчик команды меню ID_OPENIMAGE, с помощью которой пользователь будет выбирать файл с изображением:
|
|
|
Проверьте, что диалог по открытию файла с изображением вызывается. Однако изображение в окне вида пока не появится, так как мы не добавили требуемый код в функцию CChildView::OnPaint().
Внимательно изучите код функции CChildView::OnOpenimage(). Что означает описание CSimpleArray <GUID> aguidFileTypes, зачем оно нужно?
Шаг 7. Добавьте код отрисовки изображения в функцию CChildView::OnPaint():
|
|
Запустите приложение на выполнение, откройте какой-нибудь файл с поддерживаемым системой форматом. Изображение картинки должно появиться в окне программы в масштабе 1:1, что не очень удобно, особенно при отсутствии скроллинга окна.
Теперь осталось добавить пользователю возможность выбора как масштаба изображения, так и сохранения изображения в файле другого формата.
Шаг 8. Добавьте обработчик команды меню ID_SAVEIMAGE и добавьте в него приведенный ниже код. Обратите внимание, что при сохранении изображения пользователю предоставляется возможность изменения формата изображения, например, файл .bmp можно сохранить в формате jpg.
|
|
|
Шаг 9. Теперь нам надо добавить обработчики команд меню, масштабирующих изображение. Код масштабирования уже реализован в методе CChildView::OnPaint() и, посему, нам остается только присвоить корректное значение члену m_nImageSize перед вызовом функции OnPaint(). В связи с этим целесообразно создать один-единственный обработчик для всех команд масштабирования, так как они функционально подобны. И, о чудо!, такая возможность есть! При этом, однако, придется вручную добавлять такой «групповой» обработчик команд меню.
Модифицируем (ручками) карту сообщений, приведя ее к следующему виду (файл ChildView.cpp):
|
Обратите внимание на новый макрос ON_COMMAND_EX, с помощью которого разным командам ставится в соответствие один и тот же обработчик.
В тот же файл, опять-таки вручную, добавим обработчик команд масштабирования контекстного меню:
|
И, наконец, надо добавить прототип этого метода в заголовочный файл ChildView.h:
public:
afx_msg BOOL OnSize(UINT nID);
Как Вы уже догадались, каркас приложения передает методу OnSize() в качестве параметра nID идентификатор выбранной команды меню. Если бы у нас была уверенность в том, что идентификаторы имеют последовательные номера, то код метода можно было бы упростить.
Запустите приложение на выполнение и убедитесь в том, что команды контекстного меню выполняются ожидаемым образом.
Шаг 10. Видом команд контекстного меню и их состоянием можно управлять. Например, в нашем случае до загрузки файла с изображением все темы меню, кроме собственно загрузки файла, логично сделать недоступными. В частности, недурно метод CChildView::OnContextMenu() сделать таким:
|