Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Win32_f.doc
Скачиваний:
2
Добавлен:
03.05.2019
Размер:
899.07 Кб
Скачать

232 Глава 26

/*Класс приложения, производный от TApplication (ради InitMainWindow)*/

class MyApp:public TApplication{ public:

void InitMainWindow();//Замещаем функцию InitMainWindow };

/*Класс главного окна, производный от TFrameWindov (ряди Paint) */ class MyWindow:public TFrameWindow{ public:

MyWindow(TWindow*parent,char far*title):TFrameWindow(parent,title){ Attr.X=0;Attr.Y=0; Attr.W=245;Attr.H=200; }

void Paint(TDC&,bool,TRect&);//Переопределяем функцию Paint };

/*Замещенная функция InitMainWindow()*/ void MyApp::InitMainWindow(void){

SetMainWindow(new MyWindow(0,"Программа 26-2")); }

/*Замещенная функция Paint ()*/ void MyWindow::Paint(TDC&dc,bool,TRect&){ int i;//Переменная циклов

char ticks[10][2];//Массив цифр под осью X TPoint р; //Текущая координата для рисования рисок dc.Rectangle(border);//Рисуем рамку for(i=0;i<=9;i++){//В цикле по 10 точкам

p=graph.BottomLeft()+=i*dx;//Текущая координата верхних концов рисок dc.MoveTo(p); / / В цикле перемещаемся по верхним концам рисок dc.LineTo(p.OffsetBy(0,margins));//и рисуем риски вниз до рамки wsprintf(ticks[i],"%d",i);//Преобразуем цифры в символы dc.TextOut(p.OffsetBy(-3,margins+3),ticks[i]);//Выводим цифры под осью }

dc.MoveTo(graph.TopLeft());//Рисуем верхнюю

dc.LineTo(graph.TopLeft().OffsetBy(-margins,0));//горизонтальную риску dc.MoveTo(graph.BottomLeft ());//Рисуем нижнуюю

dc.LineTo(graph.BottomLeft().OffsetBy(-margins,0));//горизонтальную риску . dc.TextOut(graph.TopLeft().OffsetBy(-margins-25,-7),"100");//Выводим цифры dc.TextOut(graph.BottomLeftО.OffsetBy(-margins-10,-7),"0");/1'масштаба TPen pen1(TColor::LtBlue,2);//Создаем синее перо толщиной 2 пиксела dc.SelectObject(pen1);//и выбираем его в контекст устройства

dc.MoveTo(graph.BottomLeft().OffsetBy(0,-data[0]));//Перемещаемся к первой точке for(i=1;i<=9;i++)//В цикле по 9 точкам соединияем линиями точки графика

dc.LineTo(graph.BottomLeft().OffsetBy(i*dx,-data[i])); TPen pen2(TColor::LtMagenta);//Создаем фиолетовое перо dc.SelectObject(pen2);//и выбираем его в контекст устройства TBrush brush(TColor::LtMagenta);//Создаем фиолетовую кисть dc.SelectObject(brush);//и выбираем ее в контекст устройства for(i=0; i<=9;i++)//Рисуем залитые точки графика

dc.Ellipse(graph.BottomLeft().OffsetBy(i*dx-radius,-data[i]-radius),size); }

/*Главная функция приложения OwlMain*/ int OwlMain(int,char*[]){ return MyApp().Run(); }

В примере 26-2 в главное окно приложения выводится график значений, записанных в массиве целых чисел data. Для упрощения программы эти числа не считываются из файла данных на диске, как это было бы более естественно, а описаны непосредственно в программе; кроме того, не предусмотрено ни мас­штабирования чисел (считается, что они расположены в диапазоне от 0 до 100), ни изменения их количе­ства. Точки графика соединены прямыми линиями и, кроме того, каждая точка отображается в виде за­литого кружка.

Программа по своей структуре аналогична уже рассмотренным, если не считать вид функции InitMainWindow, в которой создается объект класса MyWindow и созданное окно объявляется главным окном приложения. Поскольку указатель на этот объект (в предыдущих примерах он назывался myWin) нигде больше в программе не используется, нет необходимости его создавать отдельным предложением программы. В варианте, использованном в данном примере

SetMainWindow(new MyWindow(0,"Программа 26-2"));

оператор new, выступающий в качестве аргумента функции SetMainWindow(), возвращает значение ука­зателя на создаваемый объект класса MyWindow, и все работает правильно, хотя этот указатель и не при­сутствует в программе в явном виде.

Обработка сообщения WM_PAINT u интерфейс GDI 233

Для упрощения разработки программы геометрические характеристики изображения записаны в ви­де символических констант (для целочисленных констант описатель int можно опускать), смысл которых показан на рис. 26.4.

Рис. 26.4. Обозначения точек, линий и прямоугольников для программы 26-2.

В программе 26-2, в частности, демонстрируется использование классов OWL 5.0, служащих для оп­ределения размеров и координат точек, линий и прямоугольных областей. Объекты этих классов сами по себе не производят никаких видимых эффектов, однако их удобно использовать в функциях GDI, тре­бующих задания геометрических характеристик. Класс TPoint задает координаты точки, класс TRect -координаты прямоугольника, а класс TSize включает в себя пару чисел int, которые можно использовать для задания каких-либо размеров или смещений. В настоящем примере с помощью объекта класса TSize описаны размеры квадрата, служащего для вывода на экран круглых точек.

Объекты классов положения и размеров описаны в примере 26-2 в начале программы, в области гло­бальных переменных. С таким же успехом их можно было описать непосредственно в функции Paint(), где только они и используются.

Функция Paint() в принципе выглядит точно так же, как и в традиционных программах и состоит из последовательности вызовов функций GDI, осуществляющих рисование элементов изображения - рам­ки, рисок, надписей, кружков и т.д. Все эти функции вызываются для объекта контекста устройства dc, созданного конструктором класса TPaintDC, как это было описано в предыдущем разделе. Использован­ные в программе функции (Rectangle(), MoveTo(), LineTo() и др.) являются инкапсулированными функ­циями API Windows и не нуждаются в пояснениях. В качестве аргументов этих функций можно указы­вать обычные координаты точек, как и в API Windows, однако использование объекты классов положе­ния и размеров предоставляет более широкие возможности. При этом функции GDI позволяют указывать геометрические характеристики рисуемых фигур в разных вариантах. Так, для рисования прямоугольной рамки в программе использован вызов

dc.Rectangle(border); //Рисуем рамку

где border - объект класса TRect. С таким же успехом можно было указать координаты прямоугольника в виде двух объектов класса TPoint

dc.Rectangle(X0Y0,XmYm);

или четырьмя целыми числами.

Имея объект класса TRect, можно с. помощью функций-членов этого класса выполнять различные операции над прямоугольником: извлекать его геометрические характеристики (площадь, высоту и ши­рину, координаты сторон и углов), перемещать его в заданную точку, увеличивать или уменьшать, опре­делять вхождение в него точки с заданными координатами и т.д. Например, использованные в программе функции BottomLeft() и TopLeft() возвращают координаты нижнего левого и верхнего левого углов рам­ки графика, а функция InflateBy() с отрицательными аргументами позволяет получить из прямоугольни­ка-рамки border прямоугольник graph меньшего размера, описывающий область собственно графика (см. секцию описания объектов классов в начале программы)

С помощью функций-членов класса TPoint можно найти расстояние данной точки от начала коорди­нат окна, а также переместить точку в другое место или определить координаты точки, отстоящей от данной на заданное смещение по осям. Именно последняя функция (носящая имя OffsetBy()) несколько раз используется в настоящем примере. Например, в паре предложений

dc.MoveTo(graph.TopLeft()); //Рисуем верхнюю

dc.LineTo(graph.TopLeft().OffsetBy(-margins,0)); //горизонтальную риску