
- •Часть 2. Сборник рецептов по визуальному программированию Введение в объектно-ориентированное программирование
- •Создание проекта в VisualStudio
- •Файлы проекта
- •Сведения об объекте
- •Общие свойства всех объектов
- •Класс Form
- •Помещение компонента в форму и прочие действия с дизайнером форм
- •Свойства форм
- •События формы
- •Методы формы
- •Компоненты ввода и отображения текстовой информации Компонент Label
- •Некоторые свойства компонента Label
- •Компонент TextBox
- •Методы TextBox
- •Компонент RichTextBox
- •Ввод числовых значений в компонент TextBox
- •Проверка, введены ли значения
- •Компонент ListBox
- •Компонент ComboBox
- •Ввод данных из файла
- •Компонент MaskedTextBox
- •Кнопки, индикаторы и управляющие элементы Компонент Button
- •Компонент Panel
- •Компоненты RadioButtonиCheckBox
- •Компонент GroupBox
- •Пример. Комплектация автомобиля
- •Работа с меню Главное меню
- •Контекстное меню
- •Создание текстового редактора
- •Системные диалоги
- •Компонент OpenFileDialog
- •Компонент SaveFileDialog
- •Диалог выбора шрифта
- •Диалог выбора цвета
- •Компонент PrintDialog
- •Диалоговые окна в текстовом редакторе
- •Расширенные символы Unicode
- •Работа с графикой Использование графических файлов
- •Создание фотоальбома
- •Методы для рисования на форме и прочих компонентах
- •Работа с таймером
- •Работа с датой и временем
- •Добавление новых форм к проекту
- •Многостраничные панели
- •Способы задания страниц
- •Методы TabControl
Методы для рисования на форме и прочих компонентах
Вывод графики осуществляется на графическую поверхность объекта (графическая поверхность формы, компонента или заданная вручную поверхность). Для того чтобы на поверхности объекта появился графический элемент (линия, окружность, прямоугольник и т.д.) или изображение, необходимо применить к графической поверхности (объекту Graphics) соответствующий метод.
Методы выполняют прорисовку контура объекта или заполнение внутренней области объекта. Цвет закраски внутренних областей геометрических фигур определяется параметрами вызываемых методов.
Характеристики шрифта текста, выводимого методом DrawString, определяются параметрами вызова метода. Если они не указаны, используются характеристики шрифта (тип, цвет, размер), указанные для основной формы программы.
Основную работу по выводу графики на поверхность формы выполняет функция обработки события Paint.
Система координатдля вывода графики имеет начало в левом верхнем углу компонента. ОсьOXнаправлена направо по горизонтали, осьOY– вниз по вертикали. Координаты измеряются в пикселях.
Пиксель– наименьший элемент поверхности рисунка, с которым можно манипулировать.
Рассмотрим методы для работы с объектом Graphics.
DrawLine (Pen, x1,y1,x2,y2)– рисует отрезок. ПараметрPenопределяет цвет, толщину и стиль линии, аx1,y1,x2,y2 – координаты начала и конца отрезка.
DrawLine (Pen, p1,p2)– рисует отрезок. Параметрыp1 иp2 – структурыPoint, точки начала и конца отрезка.
DrawArc (Pen, x1,y1,w,h,sa,ea)– рисует дугу. Параметрыx1,y1 определяют координаты левого верхнего угла прямоугольника, в который вписан эллипс, содержащий дугу,w,h– ширину и высоту этого прямоугольника, аsaиea– углы, определяющие начало и конец дуги (угол отсчитывается от осиOXпо часовой стрелке).
DrawRectangle (Pen, x,y,w,h)– рисует контур прямоугольника. Параметрыxиy– координаты левого верхнего угла, а параметрыwиhзадают размер прямоугольника.
DrawRectangle (Pen, rect)– рисует контур прямоугольника. Параметрrect(структураRectangle) определяет область, граница которой определяет контур прямоугольника.
FillRectangle (Brush, x,y,w,h)– рисует закрашенный прямоугольник. ПараметрBrushопределяет цвет и стиль закраски прямоугольника; параметрыxиy– координаты левого верхнего угла, параметрыwиhзадают размер прямоугольника.
FillRectangle (Brush, rect)– рисует контур прямоугольника. Параметрrect(структураRectangle) определяет область, граница которой определяет контур прямоугольника.
DrawEllipse (Pen, x,y,w,h)– рисует контур эллипса, параметрыx,y,w,h– координаты левого верхнего угла и размер прямоугольника, внутри которого вычерчивается эллипс.
DrawEllipse (Pen, rect)– рисует контур эллипса, параметрrect– область, внутри которой рисуется эллипс.
FillEllipse (Pen, x,y,w,h)– рисует закрашенный эллипс, параметрыx,y,w,h– координаты левого верхнего угла и размер прямоугольника, внутри которого вычерчивается эллипс.
FillEllipse (Pen, rect)– рисует закрашенный эллипс, параметрrect– область, внутри которой рисуется эллипс.
FillPie (Pen, x1,y1,w,h,sa,ea)– рисует сектор. Параметрыx1,y1 определяют координаты левого верхнего угла прямоугольника, в который вписан эллипс, содержащий дугу,w,h– ширину и высоту этого прямоугольника, аsaиea– углы, определяющие начало и конец дуги (угол отсчитывается от осиOXпо часовой стрелке).
DrawPolygon (Pen, P)– рисует контур многоугольника, параметрP– массив типаPoint, содержащий координаты углов многоугольника, заданные против часовой стрелки.
FillPolygon (Pen, P) – рисует закрашенный многоугольник, параметрP– массив типаPoint, содержащий координаты углов многоугольника, заданные против часовой стрелки.
DrawString (str, Font, Brush, x,y)– выводит на графическую поверхность строку текста,xиy– точка, от которой будет выведен текст.
О прочих методах объекта Graphicsможно прочитать в справочной системе. Оставим это в качестве задания для самостоятельной работы.
Карандаш(Pen) определяет вид линии – цвет, толщину и стиль. В распоряжении программиста есть набор цветных карандашей, при помощи которых можно рисовать сплошные линии толщиной в один пиксель (Pens::Red,Orange,Yellow,Green,LightBlue,Blue,Purple,Black,LightGray,White, прозрачный –Transparent).
Программист может создать свой собственный карандащ, объект типа Penи, задав значения свойств, определить цвет, толщину и стиль линии, которую он будет рисовать.
Приведем свойстваобъектаPen.
Color– цвет линии, в качестве значения свойства следует использовать одну из константColor, определенных в пространстве именSystem::Drawing.
Width– толщина линии в пикселях.
DashStyle– вид линии. В качестве значения следует использовать одну из константDashStyle, определенных в пространстве именSystem::Drawing::Drawing2D:DashStyle.Solid, Dash, Dot, DashDot, DashDotDot, Custom. Custom– пунктирная линия, вид которой определяет значение свойстваDashPattern(длина штрихов и промежутков пунктирной линии).
Кистииспользуются для закраски внутренних областей геометрических фигур. В распоряжении программиста есть четыре типа кистей: стандартные (Brush), штриховые (HatchBrush), градиентные (LinearGradientBrush) и текстурные (TextureBrush).
Стандартная кистьзакрашивает область одним цветом (сплошная закраска).
Штриховая кистьзакрашивает область путем штриховки. Область может быть заштрихована горизонтальными, вертикальными и наклонными линиями разного стиля и толщины.
Градиентная кистьпредставляет собой прямоугольную область, цвет точек которой зависит от расстояния до границы. Обычно градиентные кисти двухцветные, т.е. цвет точек по мере удаления от границы постепенно меняется с одного на другой. Цвет может меняться вдоль горизонтальной или вертикальной границы области. Возможно также изменение цвета вдоль линии, образующей угол с горизонтальной градацией.
Текстурная кистьпредставляет собой рисунок, который обычно загружается во время работы программы из файла (bmp,jpgилиgif) или из ресурса. Закраска текстурной кистью выполняется путем дублирования рисунка внутри области (кафельная плитка).
Пример.Рисование графика
функции. Изобразим на форме график
функциис масштабной сеткой. Поля формы – 20
пикселей справа и слева, 25 пикселей –
сверху и снизу. Шаг масштабной сетки
задается в компонентеTextBoxи изменяется сразу при вводе соответствующего
значения. По умолчанию свойствоTextэтого компонента содержит значение,
равное 20.
Рисование на форме осуществляется при помощи события Paint, которое возникает всякий раз при изменении размеров формы, ее перекрытия другими окнами и, конечно же, при создании новой формы.
В первую очередь для работы с графикой необходимо создать сам графический объект.
System::Drawing::Graphics^ g=e->Graphics;
Далее определим размер и начертание шрифта для отображения подписи, содержание этой подписи и ее положение на форме. В данном случае подпись располагается по центру на высоте 20 пикселей от заголовка окна. Вывод строки осуществляется при помощи метода DrawString.
System::Drawing::Font ^hFont=gcnew
System::Drawing::Font("Tahoma",14,FontStyle::Regular);
String ^header="Синусоида";
int wh=(int)g->MeasureString(header, hFont).Width;
int x=(this->ClientSize.Width-wh)/2;
g->DrawString(header,hFont,Brushes::DarkGreen,x,20);
Определим и вычислим группу параметров, отвечающую за размеры области построения графика, шаг сетки и пр.
int sx=20,sy=100; //Зададим поля области
int W=this->ClientSize.Width; //Ширина формы
int H=this->ClientSize.Height-sy; //Высота формы с поправкой на поля
// Точка, из которой начинаем построение графика
int prev_x=0;
int prev_y=H/2;
//Шаг сетки
int s=Convert::ToInt32(textBox1->Text);
Далее изобразим прямоугольник и сетку в области, где будет выведен график. Фон области – белый, линии сетки – зеленые.
g->FillRectangle(System::Drawing::Brushes::White, sx,sy/2,W-2*sx,H);
//Горизонтальные линии
for (int i=0;i<H;i+=s)
g->DrawLine(Pens::LightGreen,sx,i+sy/2,W-sx,i+sy/2);
//Вертикальные линии
for (int j=0;j<W-2*sx;j+=s)
g->DrawLine(Pens::LightGreen,sx+j,sy/2,sx+j,H+sy/2);
Перейдем к построению самого графика
функции. Его будем строить крошечными
отрезками с шагом в один пиксель.
Координаты следующей точки сначала
рассчитываются как функция
,
построенная на отрезке
.
Затем полученные значения масштабируются
и сдвигаются в зависимости от размеров
формы. Значения в предыдущей точке
сохраняются в переменныхprev_xиprev_y.
for (int px=0;px<=W-2*sx;px++){
double X=px*4*M_PI/(W-2*sx);
double Y=sin(X);
int py=H-(Y+1)*H/2;
g->DrawLine(Pens::Black,prev_x+sx,sy/2+prev_y,sx+px,sy/2+py);
prev_x=px;prev_y=py;
}
Еще один метод, необходимый для работы формы – Resize, возникающий при любых изменениях размера формы (в т.ч. и ее максимизация). Событие находится в группеLayout. Этот же метод будет вызываться и при изменении шага сетки, вводимого в компонентTextBox(компонент располагается в левом верхнем углу). Поэтому в тексте данной функции осуществим проверку – не введено ли нулевое значение и не содержит ли компонентTextBoxпустую строку.
if (textBox1->Text->Length!=0)
if (Convert::ToInt32(textBox1->Text)!=0)
this->Refresh();
При любых изменениях размера формы или шага сетки будет вызван метод формы Refresh, осуществляющий перерисовку формы.
Несомненно, для компонента TextBoxдолжен обеспечивать ввод верных данных (пользователь не может вводить символьные значения), а в его свойствеTextChangeдолжно быть указано событиеResize.
Создать изображение, имеющее жесткую привязку к пикселям формы, не составляет большого труда. Для этого достаточно лишь аккуратно просчитать координаты всех точек и воспользоваться всеми необходимыми для рисования методами. Такой способ работы с графикой не представляется целесообразным, потому что при его реализации невозможно масштабировать полученное изображение и осуществлять его параллельный сдвиг.
Приведем теперь алгоритм рисования изображения на форме, обеспечивающий гибкое редактирование.
1. Определить координаты точки привязки. Это должна быть одна из узловых точек изображения (вершина крыши домика, центр сердцевины цветка, начало отсчета и т.д.).
2. Для облегчения рисования и вычисления узловых точек рекомендуется разбить изображение на несколько слоев (задний план, общий план, передний план) и затем рисовать эти слои последовательно (сначала объекты заднего плана, затем все объекты среднего, и, наконец, все объекты переднего плана). Это целесообразно, потому что при рисовании объекты передних планов накладываются как аппликация на объекты задних планов.
3. Рассчитать координаты всех остальных узловых точек изображения в зависимости от координат точки привязки. Все габариты изображаемых объектов желательно либо задавать с помощью компонентов TextBox, либо вычислять пропорционально в зависимости от размеров уже созданных объектов.
4. Определить способ задания цветов объектов: либо цвета выбираются по умолчанию, либо некоторые цвета выбирает пользователь с помощью соответствующего диалога.
5. Рассчитать значения координат всех узловых точек с учетом сдвига и коэффициента масштабирования (определяется в зависимости от размера компонента, в рабочей области которого выводится изображение).
6. Написать обработчик события Paint.