Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP_Lab_16_17.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
14.46 Mб
Скачать

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 час.).

Задание.

  1. Внимательно изучите материал разделов «Каркас приложений MFC» и «Класс вид библиотеки MFC (версия MVS 2005)» в файле VC_Lect.doc. В данной части используемые нами свойства и возможности MVS 2010 практически ничем не отличаются от MVS 2005.

  2. Разработайте приложение в соответствии с рекомендациями, приведенными в разделе «Класс вид библиотеки MFC (версия MVS 2005)». Тестируйте приложение, добейтесь его работоспособности.

  3. Добавьте в разработанное приложение программный код, который будет читать из файла данные о положении и размерах нескольких геометрических фигур и изображать эти фигуры в окне вида. Для получения представления о том, как можно выводить графические изображения в Windows, проработайте раздел конспекта «Интерфейс графического устройства, цвет и шрифт».

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

Методические указания.

Шаг 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. Окно добавления функции обработчика команды меню FileOpen

Начальные значения для собственных член-данных следует задавать в конструкторе, который определен в файле реализации DRWView.cpp и выглядит так:

CDRWView::CDRWView()

{

// TODO: add construction code here

}

Присваивание данным начальных значений выполняется обычным образом, например:

CDRWView::CDRWView()

{

MyVar=123;

}

Удобнее добавлять в класс член-данные с помощью мастера ИС. Для этого в окне решений выберите вкладку ClassView (если Вы не видите эту вкладку – перекреститесь, если вы православный, и вызовите ее с помощью команды ViewClass View), выделите с помощью мыши класс CDRWView, вызовите с помощью ПКМ контекстное меню и выберите в нем команду AddAdd 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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]