Лабораторная работа 5
Тема: Создание и вывод графический изображений на форму.
Анимация.
Цель работы: Изучить приемы рисования, вывода изображений и анимации в Visual .
Теоретические сведения.
Система координат, принятая по умолчанию, использует в качестве единицы измерения пиксели, а в качестве исходной точки — верхний левый угол. Координата X определяет смещение вправо, а координата Y — смещение вниз.

Рисунок 1. Система координат, используемая по умолчанию.
Для того чтобы вывести графическое изображение в окне формы необходимо в созданном средствами Visual Studio приложении WindowsApplication вставить в класс формы строку this->Paint += gcnew System::Windows::Forms::PaintEventHandler(Form1_Paint);
где Form1 – имя формы, например:
public: Form1() {
InitializeComponent();
this->Paint += gcnew System::Windows::Forms::PaintEventHandler(Form1_Paint);
}
private: void Form1_Paint(Object^ sender, PaintEventArgs^ e) {
Graphics^ g = e->Graphics;
...
}
Методы, определенные в классе Graphic, требуют, указания положения или область для вывода графического объекта. Для передачи методам подобной информации в пространстве имен System::Drawing предусмотрены типы Point, Rectangle, Region и Size.
· Point используется для передачи координат (х, у).
· Rectangle определяет координаты двух точек, которые будут восприняты как верхний левый и нижний правый углы прямоугольника.
· Тип Size определяет размер прямоугольной области в каком-либо измерении (то есть используется для указания высоты или ширины).
· Тип Region необходим для работы с непрямоугольными областями.
Внутренние переменные, используемые для хранения данных в Point, Rectangle и Size, являются целочисленными (то есть относятся к типу int). Если же возникла необходимость указывать координаты или размеры при помощи значений с плавающей запятой (тип float), то можно использовать типы PointF, RectangleF и SizeF.
Таблица 1. Члены типа Point (PointF)
Член | Назначение |
X, У | Эти свойства позволяют получать и устанавливать значения координат х и у |
IsEmpty | Это свойство возвращает true, если значения х и у равны нулю |
Offset( ) | Этот метод позволяет произвести смещение точки относительно исходной позиции |
Например, создадим объект типа Point, и координатам X иY присвоим числовые значения.
Point^ pt = gcnew Point (100, 72);
//Смещаем точку
pt->Offset(20, 20); // в результате координаты точки будут (120, 92)
// Меняем значение координаты X для pt
pt->X = 40; // в результате координаты точки будут (40, 92)
Таблица 2. Члены классов Rectangle и RectangleF
Член | Назначение |
!=, = = | Перегруженные операторы, позволяющие сравнивать два прямоугольника |
Inflate( ), Intersect( ), Union( ) | Эти статические методы позволяют увеличивать размеры прямоугольника и создавать новые прямоугольники путем разделения или объединения существующих. |
Тор, Left, Bottom, Right, | Эти свойства устанавливают измерения прямоугольника |
Height, Width | Эти свойства определяют высоту и ширину прямоугольника |
Contains() | Этот метод позволяет определить, попадает ли точка с указанными координатами (или другой прямоугольник) внутрь области, занимаемой прямоугольником |
X, Y | Определяют координаты x и у верхнего левого угла прямоугольника |
Класс Region
Этот класс представляет собой внутреннюю область, занятую геометрической фигурой. Чтобы создать объект этого класса, необходимо передать его конструктору некоторый объект, представляющий собой геометрическую фигуру. Например, есть прямоугольник размером 100 на 100 пикселов. Чтобы получить объект класса Region, соответствующий внутренней области этого прямоугольника, код может быть таким:
// Получаем объект Region для прямоугольника
Rectangle^ г = gcnew Rectangle(0, 0, 100, 100);
Region^ rgn = gcnew Region(r);
После того как объект класса Region создан, можно использовать многочисленные члены этого класса. Наиболее важные из них представлены в таблице:
Таблица 3. Члены класса Region
Член | Назначение |
Complement() | Дополняет объект Region другими графическими объектами, которые не пересекаются с исходным объектом Region |
Exclude() | Исключает область, занимаемую другим графическим объектом, из области объекта Region |
Intersect() | Перегружен. Уменьшает область, занимаемую исходным объектом Region, до области наложения друг на друга исходного и указанного пользователем объектов Region |
GetBounds() | Возвращает объект класса RectangleF, представляющий прямоугольник, в который точно вписана область, занимаемая объектом Region |
IsEmpty(), MakeEmpty() | Позволяют определить, имеет ли область, занимаемая данным объектом Region, нулевой размер, или установить нулевой размер для области Region |
IsInfinite(),MakeInfinite() | Позволяют определить, является ли область, занимаемая объектом Region, бесконечной, или установить бесконечный размер для данной области |
Translate() | Сдвигает координаты объекта Region на указанную пользователем величину |
Union() | Объединяет указанный объект Region с другим графическим объектом |
Хог() | Объединяет указанный объект Region с другим графическим объектом, исключая при этом область пересечения этих двух объектов |
Вывод графических объектов без события Paint
Бывает так, что вывод графического объекта необходимо произвести не в стандартных ситуациях, то есть не когда возникает событие Paint, а в ответ на другие события. Например, предположим, что наша задача — вывести маленький кружок в том месте, где на форме был сделан щелчок мышью. Первое, необходимо получить объект Graphics, а затем выполнить с этим объектом необходимые манипуляции. Объект Graphics можно получить при помощи метода Graphics::FromHwnd(). Обратите внимание, что единственный параметр, передаваемый этому методу, — это значение свойства Handle. Свойство Handle, определено в классе Control и наследуется всеми классами, производными от Control. Работа с объектом Graphics может выглядеть например так:
private: void Form1_MouseDown( Object^ sender, MouseEventArgs^ e) {
// Получаем объект Graphics
Graphics^ g = Graphics::FromHwnd(this->Handle);
// Теперь в месте щелчка мышью рисуем кружок диаметром 10 пикселов
g->DrawEllipse(gcnew Pen(Color::Green), e -> X, e->Y, 10, 10);
}
При любой перерисовке формы все кружки, выведенные на форме после щелчков мышью, исчезнут. Поскольку, вывод графических объектов (кружков) происходит только в результате щелчка мышью, но не при выводе формы на экран.
Чтобы информация о графических объектах сохранялась и использовалась при перерисовке формы. Самый простой способ — создать внутреннюю коллекцию (например, при помощи класса ArrayList) и помещать туда нужные объекты. Затем к этой коллекции будет обращаться метод OnPaint().
Возможности класса Graphics
Наиболее часто используемые методы этого класса представлены в таблице.
Таблица 4. Некоторые методы класса Graphics
Метод | Назначение |
FromHdc(), FromHwnd(), FromImage() | Эти статические методы обеспечивают возможность получения объекта Graphics из элемента управления или изображения |
Clear() | Заполняет объект Graphics выбранным пользователем цветом, удаляя его предыдущее содержимое |
DrawArc() | Этот метод предназначен для вывода дуги. |
DrawEllipse() | Рисует эллипс |
DrawLine() | Рисует линию |
DrawPie() | Рисует сектор |
DrawPolygon( ) | Рисует замкнутую произвольную область |
DrawRectange() | Рисует прямоугольник |
DrawString() | Выводит строку |
FillElllpse() | Рисует закрашенный эллипс |
FillPie() | Рисует закрашенный сектор |
FillPolygon() | Рисует закрашенную криволинейную замкнутую область |
FillRectangle() | Рисует закрашенный прямоугольник |
Класс Pen
Pen - класс пера, имеющий два основных атрибута: цвет и ширину.
Пример использования, в проекте типа Windows Application внутри любой функции (например OnPaint или функции – обработчике события нажатия кнопки) введите следующий текст:
System::Drawing::Graphics^ gr = this->CreateGraphics();
System::Drawing::Pen^ blue = gcnew Pen(Color::Blue); // синее, ширина: 1
System::Drawing::Pen^ red = gcnew Pen(Color::Red, 2); // красное, ширина: 2
System::Drawing::Pen^ green = Pens::Green; // зелёное, ширина: 1
gr->DrawRectangle(blue, 20,20,20,20); // рисуем прямоугольники
gr->DrawRectangle(red, 40,20,20,20);
gr->DrawRectangle(green, 60,20,20,20);
Общий вид функций создания графических примитивов:
DrawRectangle(устройство вывода(класса Pen или Brush), х1,y1, x2, y2);
где х1,y1 – координаты верхнего левого угла, x2, y2 – координаты правого нижнего угла.
DrawLine(устройство вывода(класса Pen или Brush), х1,y1, x2, y2);
где х1,y1 – координаты начала линии, x2, y2 – координаты конца линии
DrawEllipse(устройство вывода(класса Pen или Brush),x , y , высота, ширина);
где х1,y1 – координаты центра.
DrawPie(устройство вывода(класса Pen или Brush),x , y , высота, ширина, начальный угол, насколько градусов повернуть почасовой стрелке);

Чтобы получить сектор изображенный на рисунке необходимо задать значение начального угла 180, значение насколько градусов повернуть – 90
DrawArc(устройство вывода(класса Pen или Brush),x , y , высота, ширина, начальный угол, насколько градусов повернуть почасовой стрелке);
DrawString(строка или строковая переменная, шрифт, кисть, x,y, [формат вывода текста]);
x, y - координаты верхнего левого угла текста
DrawPolygon (устройство вывода (класса Pen или Brush), массив точек типа Point [ ]);
Таблица 5. Свойства класса Реn
Свойство | Назначение |
Color | Определяет цвет создаваемых объектом Реn линий |
CustomStartCap, CustomEndCap | Позволяют получить или установить стиль «наконечника» пера, который будет показан в начале линии (StartCap) и в конце линии (EndCap) |
DashCap | Позволяет получить или установить стиль «наконечника» для перьев, рисующих пунктирные линии |
DashOffset | Устанавливает смещение начала пунктира относительно исходной точки пунктирной линии |
DashStyle | Позволяет получить или установить стиль для пунктирных линий, создаваемых при помощи данного объекта Реn |
LineJoin | Позволяет получить или установить стиль объединения при пересечении двух линий, выводимых данным объектом Реn |
Width | Позволяет получить или установить ширину данного пера |
Кроме класса Реn в GDI+ также можно использовать коллекцию заранее определенных перьев (коллекция Pens). При помощи статических свойств коллекции Pens можно мгновенно получить уже готовое перо, без необходимости создавать его вручную. Однако все типы Реn, которые создаются при помощи коллекции Pens, имеют одну и ту же одинаковую ширину, равную 1. Чтобы установить перо для вывода линий определенного стиля необходимо подключить в начале кода
using namespace System::Drawing::Drawing2D;
затем создавая перо
Pen^ A->DashStyle = DashStyle:: тип линии;
Таблица 6. Значения перечисления DashStyle
Значение | Перечисление |
Custom | Пользовательский стиль |
Dash | Штриховая линия |
DashDot | Штрихпунктирная линия |
DashDotDot | Штрихпунктирная линия: штрих — точка — точка — штрих |
Dot | Пунктир из одних точек |
Solid | Сплошная линия |
Для того чтобы проиллюстрировать приведенную выше информацию, создайте приложение вставьте в класс Form1 следующий текст программы.
public: Form1() {
InitializeComponent();
this->Paint += gcnew System::Windows::Forms::PaintEventHandler(Form1_Paint);
}
private: void Form1_Paint(Object^ sender, PaintEventArgs^ e) {
Graphics^ g = e->Graphics;
// Создаем большое перо синего цвета
Pen^ bluePen = gcnew Pen(Color::Blue,20);
// Создаем еще одно перо при помощи заготовок из коллекции Pens
Pen^ pen2=Pens::Firebrick;
// Выводим при помощи созданных нами перьев геометрические фигуры
g->DrawEllipse(bluePen, 10, 10, 100, 100);
g->DrawLine(pen2, 10, 130, 110, 130);
g->DrawPie(Pens::Black, 150, 10, 120, 150, 0,90);
//Выводим многоугольник пурпурного цвета
Pen^ pen3=gcnew Pen(Color::Purple, 5);
pen3->DashStyle = DashStyle::DashDot;
g->DrawPolygon(pen3, gcnew array <Point> { Point(30, 140), Point(265, 200), Point(300, 225), Point(190, 190), Point(80, 330), Point(20, 180)});
// Добавляем прямоугольник со вписанным текстом
Rectangle^ r = gcnew Rectangle(150, 10, 230,60);
g->DrawRectangle(Pens::Blue,*r);
g->DrawString("Геометрические фигуры",(this->Font), Brushes::Black, Point(150,10));
}
Вывод изображений
Тип System::Drawing::Image используется для вывода изображений. Класс Image определяет множество свойств и методов, которые можно использовать для настройки параметров выводимого изображения. К примеру, при помощи свойств Width, Height и Size можно получить или установить размеры изображения. Кроме того, в пространстве имен System:: Drawing::Imaging определено множество типов для проведения сложных преобразований изображений.
Наиболее важные члены класса Image представлены в табл.7. Многие из этих членов являются статическими, а некоторые — абстрактными.
Таблица 7. Члены класса Image
Член | Назначение |
FromFile() | Этот статический метод предназначен для создания объекта Image из файла |
FromHbitmap() | Создает объект Bitmap на основе идентификатора окна (Window handle) |
FromStream() | Позволяет создать объект Image, используя в качестве источника поток данных |
Height Width Size Physical Dimensions Horizontal Dimensions Vertical Resolution | Все эти свойства предназначены для работы с размерами (измерениями) изображения |
GetBounds() | Возвращает прямоугольник, представляющий текущую область, занятую изображением |
Save() | Позволяет сохранить изображение в файл |
Класс Image является абстрактным, и создавать объекты этого класса нельзя. Обычно объявленные переменные Image присваиваются объектам класса Bitmap. Кроме того, можно создавать объекты класса Bitmap напрямую. Например, предположим, что необходимо вывести на форму три изображения. Можем объявить три переменные Image, а затем использовать для каждой из них объекты Вitmap;
public ref class Form1 : Form {
// Объявляем переменные типа Image
private: Image^ bMapImageA;
Вывод полученных изображений производится с помощью специального метода, который называется — DrawImage(). Этот метод многократно перегружен, поэтому есть множество вариантов того, как поместить изображение в нужное место на форме. Кроме того, для настройки параметров выводимого изображения можно использовать с этим методом значения перечислений ImageAttributes и GraphicsUnit. Координаты вывода изображения можно указать при помощи объектов Point, Rectangle, целочисленными значениями или значениями с плавающей запятой. Например:
private: void Form1_Paint(Object^ sender, PaintEventArgs^ e) {
Graphics^ g = e->Graphics;
// Используем объекты класса Bitmap
bMapImageA = gcnew Bitmap("D:\\1.png");
// Выводим изображения при помощи Graphics::DrawImage()
g->DrawImage(bMapImageA, 10, 10)
}
Класс Bitmap позволяет выводить изображения, которые хранятся в файлах самого разного формата. Например:
// Тип Bitmap поддерживает все распространенные форматы!
Bitmap^ myBMP = gcnew Bitmap(“CoffeeCup. bmp"};
Bitmap^ myGIF = gcnew Bitmap(“Candy. gif");
Bitmap^ ntyJPEG = gcnew Bitmap(“Clock. jpg");
Bitmap^ myPNG = gcnew Bitmap("Speakers. png");
// Выводим изображения при помощи Graphics::DrawImage()
g->DrawImage(myBmp, 10, 10);
g->DrawImage(myGIF, 220, 10);
g->DrawImage(myJPEG, 280, 10);
g->DrawImage(myPNG, 150, 200);
Перетаскивание, проверка попадания в область, занимаемую изображением.
Элемент управления PictureBox
PictureBox — это класс, производный от Control, поэтому можно использовать множество событий, всплывающую подсказку, контекстное меню и прочие возможности элемента управления. Проиллюстрируем применение PictureBox на примере.
Создадим приложение, которое будет захватывать события MouseUp, MouseDown и MouseMove для области, занятой на форме изображением (которое помещено в PictureBox). Добавим код для работы с перетаскиванием (drag-and-drop). Пользователь сможет перетаскивать одно из изображений по всей форме. Кроме того, будем осуществлять проверку того, где оказалось перетаскиваемое изображение после того, как пользователь его отпустит. Если оно попало в область, занимаемую заданным прямоугольником, будет выводиться специальное сообщение. Таким образом, реализуем механизм, называемый «проверкой попадания» — hit testing.
Назначение объекту PictureBox изображения, которое будет в нем содержаться, выглядит следующим образом:

Свойство PictureBox, —SizeMode, для него используются значения из перечисления PictureBoxSizeMode. Это свойство позволяет определить, как именно будет выводиться изображение внутри PictureBox. В нашем случае было использовано значение StretchImage, которое означает, что изображение должно быть сжато или растянуто таким образом, чтобы полностью соответствовать размерам PictureBoх. Другие возможные значения представлены в таблице 8
Таблица 8. Значения перечисления PictureBoxSizeMode
Значение | Описание |
AutoSize | Значения PictureBox будут изменены таким образом, чтобы полностью соответствовать размерам изображения |
CenterImage | Если размеры PictureBox будут больше, чем размеры изображения, изображение будет позиционировано точно по центру PictureBox, Если же размеры изображения будут превышать размеры PictureBox, то выступающие края будут обрезаны |
Normal | Изображение будет расположено в верхнем левом углу PictureBox. Если размеры изображения превысят размеры PictureBox, выступающие края будут обрезаны |
Выберите Choose Image для выбора изображения для отображения в PictureBox.
После того как создали PictureBox и настроили его свойства, следующая задача — обеспечить обработчики для событий MouseMove, MouseUp и MouseDown. Поскольку PictureBox — это класс, производный от Control, работа с этими событиями производится точно так же, как и в случае других элементов управления:
// Добавляем обработчики для следующих событий
pictureBox1->MouseDown +=gcnew MouseEventHandler(pictureBox1_MouseDown);
pictureBox1->MouseUp +=gcnew MouseEventHandler(pictureBox1_MouseUp);
pictureBox1->MouseMove +=gcnew MouseEventHandler(pictureBox1_MouseMove);
this->Paint +=gcnew PaintEventHandler(Form1_Paint);
В обработчике события MouseDown, во-первых, устанавливается значение true для переменной isDragging (это будет означать, что началась операция перетаскивания), а во-вторых, фиксируются координаты указателя мыши при наступлении этого события:
// Обработчик события MouseDown для объекта PictureBox
private: void pictureBox1_MouseDown(Object^ sender, MouseEventArgs^ e) {
isDragging = true;
oldX = e->X;
oldY = e->Y ;
}
Обработчик события MouseMove обеспечивает перемещение PictureBox по форме (изменяя значения свойств Тор и Left). Для расчета нового положения PictureBox используется смещение указателя мыши относительно исходной позиции:
Если пользователь производит щелчок на изображении и, не отпуская кнопку, перемещает мышь. PictureBox вместе с изображением будет перерисовываться в новой месте
private: void pictureBox1_MouseMove(Object^ sender, MouseEventArgs^ e) {
if(isDragging) {
// Определяем новое значение координаты Y для PictureBox по разности между
// старым и новым положением указателя мыши
pictureBox1->Top =pictureBox1->Top + (e->Y - oldY);
// То же самое для координаты X
pictureBox1->Left = pictureBox1->Left + (e->X - oldX);
}
}
Далее обработчик события MouseUp должен установить значение переменной isDragging равным false — это будет индикатор окончания операции перетаскивания. Кроме того, по условиям задачи должна производиться проверка: если перемещаемый PictureBox отпущен внутри определенной области формы (ограниченной размерами объекта Rectangle — прямоугольника), то будем считать, что пользователь добился успеха.
Таким образом, весь оставшийся необходимый код выглядит следующим образом:
// Когда пользователь отпустит кнопку мыши, операция перетаскивания завершится.
// Проверяем, не оказалось ли при этом перетаскиваемое изображение внутри заданного // прямоугольника
private: void pictureBox1_MouseUp(Object^ sender, MouseEventArgs^ e) {
Rectangle^ dropRect = gcnew Rectangle(200, 100, 350, 250);
isDragging = false;
if(dropRect->Contains(pictureBox1->Bounds))
MessageBox::Show("Вы победили!", "Проверка попадания");
}
private: void Form1_Paint(Object^ sender, PaintEventArgs^ e) {
// Выводим "прямоугольник сбрасывания"
Graphics^ g = e->Graphics;
Rectangle^ dropRect = gcnew Rectangle(200, 100, 350, 250);
g->FillRectangle(Brushes::Blue, *dropRect);
g->DrawString("Перетащите картинку в эту область.", this->Font, Brushes::Red, 200, 100);
}
Не забудьте объявить переменные перед классом формы, например,
bool isDragging;
int oldX, oldY;
public: Form1() { ….}
Главную роль в проверке попадания играет метод Rectangle->Contains( ). Этот метод перегружен и может принимать другой прямоугольник (объект Rectangle), точку (объект Point) или два значения типа int в качестве координат. Этот метод удобен в ситуации, когда необходимо проверить, попал ли пользователь щелчком мыши в прямоугольную область на форме или нет.
Рассмотрим следующую задачу:
Если щелчок пришелся на какое-либо из изображений, заключить это изображение в красную рамку и изменить заголовок формы (это делается при помощи свойства Form->Text).
Первое, необходимо обеспечить перехват события MouseDown для самой формы. После этого осуществлять проверку — попадает или нет указатель мыши в область, занимаемую одним из изображений. Если ответ положительный, то значения двух переменных изменятся: переменной IsImageClicked (типа bool) будет присвоено значение true, а переменной imag (типа int) - значение, соответствующее номеру выбранного пользователем изображения. Пример кода может быть таким:
public ref class Form1 : Form {
private:
bool isImageclicked;
int imag;
Rectangle^ rectA;
Rectangle^ rectB;
Rectangle^ rectC;
public:
Form1() {
InitializeComponent();
rectA= gcnew Rectangle(15, 15, 125, 75);
rectB = gcnew Rectangle(15, 95, 125, 75);
rectC = gcnew Rectangle(15, 175, 125, 75);
isImageclicked = false;
this->MouseDown+=gcnew MouseEventHandler(Form1_MouseDown);
this->Paint +=gcnew PaintEventHandler(Form1_Paint);
}
private: void Form1_Paint(Object^ sender, PaintEventArgs^ e) {
Graphics ^ g= e-> Graphics;
Pen^ outline = gcnew Pen(Color::Red, 5);
// Выводим все три изображения
g->FillRectangle(Brushes::Blue,20,20,120,70);
g->FillRectangle(Brushes::Aqua,20,100,120,70);
g->FillRectangle(Brushes::BlueViolet,20,180,120,70);
// Выводим рамку (по щелчку пользователя)
if(isImageclicked == true){
if (imag==0)
g->DrawRectangle(outline, *rectA);
if (imag==1)
g->DrawRectangle(outline, *rectB);
if (imag==2)
g->DrawRectangle(outline, *rectC);
}
}
private: void Form1_MouseDown(Object^ sender, MouseEventArgs^ e) {
// Получаем координаты указателя мыши в момент щелчка
Point^ mousePt = gcnew Point(e->X, e->Y);
// Проверяем, не попадает ли указатель мыши в одну из трех областей,
// занимаемых изображениями.
if (rectA->Contains(*mousePt)) {
isImageclicked = true;
imag = 0;
this->Text = "Вы кликнули изображение A";
}
else {
if (rectB->Contains(*mousePt)) {
isImageclicked = true;
imag = 1;
this->Text = " Вы кликнули изображение B";
}
else if (rectC->Contains(*mousePt)) {
isImageclicked = true;
imag = 2;
this->Text = " Вы кликнули изображение C";
}
else {
isImageclicked = false;
this->Text = "Изображения";
}
}
// Перерисовываем форму
Invalidate();
}
Обратите внимание, что в приложение добавлена еще одна проверка: для щелчка мыши, который не попадает ни в одно из трех изображений. Эта проверка нужна для удаления рамки с выбранного перед этим изображения.
После того как все нужные нам значения переменных установлены, мы перерисовываем клиентскую область формы.
Вывод изображений и двойная буферизация.
В объекте Graphics для вывода растров предназначен метод DrawImage.
Часто встречающейся проблемой при создании динамично меняющейся графики (и, в частности, анимации) является мерцание. Для его устранения традиционно использовался закадровый буфер, и эта возможность также имеется в GDI+. Объект Graphics можно создать "теневым", используя в качестве основы готовый экземпляр Bitmap.
Способ уменьшения мерцания – использовать двойную буферизацию вывода – когда изображение сначала готовится "за кадром", а затем переносится на экран, устраняя мерцание при анимации:
Рассмотрим пример вывода с двойной буферизацией в GDI+ :
using System::Threading; //добавляем для использования задержки
using System::Collections; //для использования методов вывода изображений
Добавьте метод Paint
private: void Form1_Paint(Object^ sender, PaintEventArgs^ e) {
//Graphics^ g = e->Graphics;
Graphics^ displayGraphics = e->Graphics;
int k=0;
while(k <500) {
Pen^ p = gcnew Pen(Color::Red);
SolidBrush^ b= gcnew SolidBrush(Color::Yellow);
SolidBrush^ b1= gcnew SolidBrush(Color::Green);
//создаем объект - изображение, которое будет включать все, что нарисовано на форме
Image^ i = gcnew Bitmap(Control::Height, Control::Width);
Graphics^ g = Graphics::FromImage(i);
g->Clear(Color::Aqua);
Thread::Sleep(200);//задержка на 300 миллисекунд
g->FillEllipse(b, k,150,30,45);
g->FillEllipse(b1,k+5,165,5,5);
g->FillEllipse(b1,k+20,165,5,5);
g->DrawArc(p, k+5,175,20,10,0,180);
g->FillRectangle(b1,0,190,500,100);
k=k+10;
//выводим на форму, созданное изображение
displayGraphics->DrawImage(i, ClientRectangle);
}
}
Для сравнения закомментируйте строки выделенные красным цветом и снимите комментарий со строки : Graphics^ g = e->Graphics;
Задания к лабораторной работе.
1. Разобрать предложенные фрагменты программ.
2. Выполнить задание преподавателя. Нарисовать рисунок, используя графические примитивы, раскрасить и выполнить анимацию. Использовать двойную буферизацию.
1) Нарисовать домик. Из трубы идет дым. По нажатию на заданную клавишу реализовать анимацию.
2) Нарисовать машинку, двигающуюся по дороге. Движение и останов машинки реализовать по нажатию на клавиши клавиатуры.
3) Нарисовать небо и движущиеся облака и солнце. Если облако закрывает солнце, идет дождь. Движение запускается и останавливается по щелчку мыши.
4) Нарисовать летающий в пространстве мяч. Движение и останов реализовать по нажатию на клавиши клавиатуры.
5) Нарисовать замкнутый прямоугольник, внутри которого двигается мячик и отталкивается от стенок прямоугольника. Начало и конец движения по щелчку мыши.
6) Реализовать фрагмент игры в «Настольный теннис». Ракетка двигается и отбивает летящий шарик. Движение ракетки по нажатию клавиш управлением курсора.
7) Нарисовать рисунок запуск ракеты. Движение начинать по щелчку мыши.
8) Нарисовать рисунок – закипание жидкости в стакане. Температура увеличивается по нажатию клавиш управлением курсора.
9) Нарисовать рисунок движение змейки по экрану. Направление движения задается нажатием на заданные клавиши клавиатуры.
10) Нарисовать летающий в пространстве куб. Движение и останов реализовать по нажатию на клавиши клавиатуры.
Вопросы к защите лабораторной работы.
1. Как вывести изображение в форму?
2. Класс Graphics и его методы.
3. Как создать объект Graphics без события Paint?
4. Как вывести изображение?
5. Методы для настройки параметров изображения?
6. Как проверить условие попадания курсора мыши в прямоугольную область, непрямоугольную область?
7. Как организовать перетаскивание мышью графического объекта по форме?
8. Как создать объект PictureBox?
9. Для чего используют двойную буферизацию?
10. Методы, которые используются при двойной буферизации, как вывести изображение, как создать изображение?


