- •Овсянник в.Н. Лабораторные работы по курсу «Объектно-ориентированное программирование»
- •1.Интегрированная среда mvs-2010
- •1.1.Методические указания
- •2.Массивушки и подпрограммочки
- •Прочитайте это задание и методические указания до конца, прежде чем терзать клавиатуру, соседа, преподавателя и пр. Сущности
- •Попробуйте сдать работу, предварительно тщательно протестировав ее на предмет отсутствия хомутов
- •2.1.Методические указания
- •3.Поиск экстремумов с ограничениями или «Брачное агенство»
- •Постановка задачи
- •Задание
- •Листинг файла mAgency.Cpp (с главной функцией)
- •Листинг файла Lib.H
- •Листинг файла Lib.Cpp
- •4.Задача «куча камней»
- •4.1.Постановка задачи.
- •4.2.Методические указания.
- •Некоторые примеры разделения камней на две кучи, которые должна решать ваша программа
- •5.Разработка простого класса
- •5.1.Задание
- •5.2.Описание вариантов заданий
- •5.3.Драгоценные методические указания
- •6.Класс вектор
- •6.1.Пример класса tVector
- •6.2.Класс tVector с перегруженными операциями
- •7.Наследование классов
- •7.1.Задание
- •7.2.Методическая помощь
- •7.3.Описание самых легких вариантов заданий
- •7.4.Контроль качества выполненной работы
- •8.Приложение с окном вида
- •9.Абстрактные классы и виртуальные функции
- •9.1.Задание
- •9.2.Методические указания
- •Void PrintClassNamе1(cBasе *pb) // параметр-указатель
- •Void PrintClassNamе2(cBasе &b) // параметр-ссылка
- •Void PrintClassNamе3(cFirst f) // параметр-значение
- •9.3.Варианты заданий
- •10.Разработка класса контейнера
- •10.1.Задание
- •10.2.Описание вариантов заданий
- •10.3.Методические указания
- •12.Перегрузка векторных и матричных операций
- •12.1.Задание
- •12.2.Бесценные методические указания
- •12.3.Некоторые особенности перегрузки операций
- •12.4.Варианты заданий
- •13.Программирование односвязного списка
- •13.1.Задание
- •13.2.Описание вариантов заданий
- •14.Приложение, основанное на модальном диалоговом окне
- •14.1.Нудные методические указания Модальные и немодальные диалоговые окна
- •Ресурсы и элементы управления
- •Сценарий создания приложения
- •Разбор приложения
- •Усовершенствование приложения
- •15.Приложения
- •15.1.Виды сортировок
- •Классификация сортировок
- •Сортировка массивов
- •15.2.Алгоритм сортировки включением
- •Пример сортировки с помощью прямого включения
- •15.3.Сортировка Шелла
- •Список литературы
7.4.Контроль качества выполненной работы
В программе количество «магических» чисел должно быть сведено к минимуму. Это значит, что программный код вида
int Mas[100];
//...
for(int i=0; i<100; i++) Mas[i]=0;
допустим только для программистов с сильно ограниченными умственными способностями, а все другие программисты должны поступать так (или еще изящнее)
const int Max=100;
int Mas[Max];
//...
for(int i=0; i<Max; i++) Mas[i]=0;
Все функции (и хвункции тоже) все необходимые данные должны получать в качестве параметров. Это значит, что фрагмент программы
const int Max=100;
int i;
int Mas[Max];
void BadFunc()
{
for(i=0; i<Max; i++) Mas[i]=0;
//...
}
//...
BadFunc();
следует считать дебильным и он должен быть переписан примерно так
const int Max=100;
int i;
int Mas[Max];
bool GoodFunc( int Mas[], int NMax)
{
if(NMax<1) return false;
for(int i=0; i<NMax; i++) Mas[i]=0;
//...
}
//...
if(GoodFunc(SomeVec,N)) //...
//...
8.Приложение с окном вида
Плохо спроектированная программа требует в три раза больше времени, чем предполагалось; тщательно спроектированная - только в два раза
Закон Мерфи
Цель работы – освоить разработку приложения с графическим интерфейсом, основанного на классе «вид» библиотеки MFC (4 час.).
Задание.
Внимательно изучите материал разделов «Каркас приложений MFC» и «Класс вид библиотеки MFC (версия MVS 2005)» в файле VC_Lect.doc. В данной части используемые нами свойства и возможности MVS 2010 практически ничем не отличаются от MVS 2005.
Разработайте приложение в соответствии с рекомендациями, приведенными в разделе «Класс вид библиотеки MFC (версия MVS 2005)». Тестируйте приложение, добейтесь его работоспособности.
Добавьте в разработанное приложение программный код, который будет читать из файла данные о положении и размерах нескольких геометрических фигур и изображать эти фигуры в окне вида. Для получения представления о том, как можно выводить графические изображения в Windows, проработайте раздел конспекта «Интерфейс графического устройства, цвет и шрифт».
Выполните отладку приложения, проанализируйте его работу при изменении размеров окна приложения.
Методические указания.
Шаг 1. Создание приложения с окном представления.
Выполните два первых пункта задания, добейтесь работоспособности приложения DRW.
Кстати, если вы хотите задать собственное название окна приложения и/или установить размер и положение окна приложения, см. в [3] подраздел 24.4 «Установка размеров и положения главного окна-рамки приложения».
Шаг 2. Рисование в окне вида.
Рисование в программах на C++ в ОС Windows с использованием стандартных GDI-объектов может показаться несколько непростым делом, но и с ним можно разобраться. В этом может помочь, например, работа [1].
В качестве примера и прототипа приведем текст функции OnDraw(), которая выводит изображение, приведенное на рис. 1. Для примера см. приложение DRW.exe.
|
Рисунок 1. Пример рисования объектов в окне программы
Некоторые комментарии к приведенному ниже тексту функции CDRWView::OnDraw().
Класс CRect предназначен для хранения координат прямоугольной области и выполнения над ними часто употребляемых операций. Основными член-данными этого класса являются координаты углов прямоугольника: left, top, right и bottom.
Обратите внимание на то, что размер и положение круга, а также диагональной линии «привязаны» к размеру окна: изменение размеров окна приводит к изменению диаметра круга, а его центр всегда совпадает с центром окна. Так как координаты всех фигур, кроме круга и прямой линии, не привязаны к размеру окна, то при изменении этих размеров изменяется взаимное размещение фигур.
Кисть NULL_BRUSH не закрашивает внутреннюю область замкнутой фигуры, а кисть WHITE_BRUSH – закрашивает белым цветом. Использование кисти NULL_BRUSH позволяет накладывать фигуры друг на друга и при этом они «не затирают» друг друга. Попробуйте раскомментировать, по одной, строки с выбором этих кистей, запустите программу на выполнение, «потаскайте» окно за правый нижний угол и посмотрите, что происходит при наложении фигур.
Макрос RGB позволяет “сочинить” свой цвет, указав три его составляющие (Red, Green, Blue), каждая из которых должна находиться, естественно, в диапазоне от 0 до 255.
|
Наберите текст функции OnDraw() и поэкспериментируйте с программой.
Шаг 3. Создание обработчика команды File→Open.
Где открывать и читать файл?
В данном приложении код рисования размещается в функции OnDraw() класса «вид». А где целесообразно открывать файл, читать из него данные и на их основе выполнять рисование фигур? Если все эти действия поместить в функцию OnDraw(), то тогда всякий раз при перерисовке окна программы файл будет повторно открываться, повторно читаться и т.д., что, естественно, нецелесообразно. В принципе, в соответствии с принятой в MFC архитектурой «документ-вид», файл надо было бы открывать и читать из него данные в классе «документ», а уже оттуда передавать эти данные в класс «вид». Это несколько сложновато, как для начала. Поэтому в данной работе мы не будем следовать этой методике и поступим проще.
Мастер внедрил в каркас нашего приложения меню File, в котором, в частности, имеется команда Open. Поэтому предлагается создать в приложении обработчик этой команды, в котором и выполнить чтение данных из файла.
Замечание. Так как при работе в среде Visual C++ довольно проблематично выполнять «откаты», то, по крайней мере на первых порах, я рекомендую время от времени выполнять резервное копирование файлов проекта с тем, чтобы легче было исправить ошибку.
Обработчик команды меню приложения File→Open проще всего создать следующим образом:
вызовите или выберите окно Class View из меню View;
в списке классов выберите CDRWView (предполагается, что приложение Вы назвали DRW);
вызовите окно свойств (Properties) с помощью команды Alt+Enter (эту команду можно найти, если постараться, в меню View);
в окне Properties выберите вкладку Events (рис. 2) с помощью кнопаря
и на этой вкладке выберите идентификатор
ресурса ID_FILE_OPEN и в поле ввода COMMAND
выберите имя функции OnFileOpen().
В результате этих воистину героических усилий мастер должен создать заготовку функции CDRWView::OnFileOpen(), не содержащей, пока, никакого кода.
Шаг 4. Выбор объектов для рисования.
Для рисования выберите себе минимум 3 объекта из доступных в классе CDC и не использованных в приведенной выше функции OnDraw(). Перечень член-функций класса CDC можно (и нужно) найти в MSDN.
Шаг 5. Открытие и чтение файла.
Добавьте в функцию OnFileOpen() открытие файла и чтение из него данных. Вы можете использовать простой текстовый файл (как в работе «Обработка текстового файла») или программно (с помощью этой же или другой программы) создать двоичный файл и читать данные из него или, в конце концов, использовать ini-файл (см. подраздел конспекта «Использование ini-файла»), что полезно с точки зрения не такой уж и далекой перспективы выполнения ДЗ.
Шаг 6. Описание и инициализация член-данных в классе.
Где разместить прочитанные данные, т.е. где надо описать соответствующие переменные, чтобы они были видимы не только в функции OnFileOpen(), но и в функции OnDraw()? Надо сделать их член-данными класса CDRWView, для чего нужно описать их в заголовочном файле DRWView.h, а именно в описании класса CDRWView. При описании данных постарайтесь не модифицировать уже имеющиеся в файле описания, с таким трудом сгенерированные мастерами MVS. Описания своих данных разместите после строк:
class CDRWView : public CView
{
protected: // create from serialization only
CDRWView();
DECLARE_DYNCREATE(CDRWView)
//////////////здесь должны быть описания ваших данных//////////////
|
Рис. 2. Окно добавления функции обработчика команды меню FileOpen
Начальные значения для собственных член-данных следует задавать в конструкторе, который определен в файле реализации DRWView.cpp и выглядит так:
CDRWView::CDRWView()
{
// TODO: add construction code here
}
Присваивание данным начальных значений выполняется обычным образом, например:
CDRWView::CDRWView()
{
MyVar=123;
}
Удобнее добавлять в класс член-данные с помощью мастера ИС. Для этого в окне решений выберите вкладку ClassView (если Вы не видите эту вкладку – перекреститесь, если вы православный, и вызовите ее с помощью команды ViewClass View), выделите с помощью мыши класс CDRWView, вызовите с помощью ПКМ контекстное меню и выберите в нем команду AddAdd variable. В появившемся диалоговом окне задайте имя член-данного, выберите тип и спецификатор доступа (public, protected, private) и завершите диалог натискиванием кнопки Finish. Мастер добавит член-данное в заголовочный файл (.h) и добавит код инициализации в конструктор, например:
CDRWView::CDRWView()
:MyVar(0)
{
// TODO: add construction code here
}
Если добавить еще одно член-данное, то код конструктора станет таким:
CDRWView::CDRWView()
:MyVar(0)
, MyVar2(0)
{
// TODO: add construction code here
}
Само собой разумеется, что Вы можете изменить начальные значения член-данных, предложенные конструктором.
Шаг 7. Рисование фигур.
Код рисования проще всего разместить в функции CDRWView::OnDraw(), которая вызывается автоматически (это так называемая функция обратного вызова – callback function) всякий раз, когда изображение в окне должно быть обновлено, а именно при свертывании и развертывании окна, при изменении его размеров, при перекрытии окна другим окном и т.д. Если мы поместим код рисования фигур, данные для которых читаются из файла, в функцию OnDraw(), то возникнет такая проблема: функция OnDraw() вызывается каркасом приложения уже при первом отображении содержимого окна, т.е. еще до того, как мы прочтем файл и собственно получим данные. Как быть? Можно поступить так: ввести специальную переменную (член-данное) булевского типа, например, bool FirstRun, в конструкторе присвоить ей значение true и проверять это значение в функции OnDraw(). После того как будут прочитаны данные из файла, этой переменной нужно присвоить значение false и «заставить выполниться» функцию OnDraw(). Функцию OnDraw() вызывают на выполнение не явно, а косвенным образом, с помощью функции Invalidate(). С учетом сказанного функция CDRWView::OnFileOpen() может быть реализована так:
CDRWView::OnFileOpen()
{
// ввод имени файла
// чтение данных из файла
Invalidate();
}
Каждая уважающая себя бригада должна выбрать оригинальный набор таких фигур, которых нет в приведенной реализации функции OnDraw(), и этот джентльменский набор должен включать не менее двух фигур (см. функции класса CDC в MSDN).
Варианты заданий
№ п/п |
Реализуемые функции |
1,12 |
Draw3dRect, Arc |
2,13 |
DrawEdge, ArcTo |
3,13 |
DrawFrameControl, PolyBezierTo |
4,14 |
DrawIcon (используйте функцию LoadIcon для загрузки одной из стандартных иконок), PolyDraw |
5,15 |
FrameRect, Polyline |
6,16 |
InvertRect (интересно наложить частично прямоугольник, указанный в качестве параметра функции InvertRect, на другую фигуру), ExtTextOut |
7,17 |
Chord, PolylineTo |
8,18 |
Pie, PolyPolyline |
9,19 |
PolyPolygon, DrawText |
10,20 |
RoundRect, PolyBezier |
11,21 |
AngleArc, DrawTextEx |
С помощью Draw3dRect, приложив совсем немного сообразительности, можно изобразить фигуру, представленную на рис.3.
|
Рисунок 3. Творческий подход к Draw3dRect
