Skip to main content
C++.NET
Windows Forms Course
L09- GDI Part 2

Mohammad Shaker
mohammadshakergtr.wordpress.com
C++.NET Windows Forms Course
@ZGTRShaker
GDI
- Part 1 Quick Revision -
What do u need to draw sth?
• Pen(stroke width, color, etc)
• Paper
• Brush to filling your drawing
Drawing::Graphic
• Encapsulates a GDI* + drawing surface.
• This class cannot be inherited.

___________________
• GDI* : Graphical Device Interface
Drawing::Graphics

private: System::Void button1_Click_5(System::Object^
sender, System::EventArgs^ e)
{
Drawing::Graphics ^MyGraphics;
MyGraphics = pictureBox1->CreateGraphics();
}
Drawing::Graphics
private void DrawImagePointF(PaintEventArgs e)
{
// Create image.
Image newImage = Image.FromFile("SampImag.jpg");
// Create point for upper-left corner of image.
PointF ulCorner = new PointF(100.0F, 100.0F);
// Draw image to screen.
e.Graphics.DrawImage(newImage, ulCorner);
}
System::Drawing
Drawing::Point
• What does this even mean? -_private: System::Void button1_Click(System::Object^
sender, System::EventArgs^ e)
{
button1->Location = 30,120;
}
Drawing::Point
Drawing::Point
• What will happen now?
private: System::Void button1_Click(System::Object^ sender,
System::EventArgs^ e)
{
Drawing::Point P;
P.X = 2;
P.Y = 23;
button1->Location = P;
}
Drawing::Point
System::Drawing::Pen
private: System::Void button1_Click_5(System::Object^ sender,
System::EventArgs^ e)
{
System::Drawing::Pen ^ MyPen = gcnew Pen(Color::Red);
}
Graphics.DrawLine Method
•
•
•
•

public: void DrawLine(Pen*, Point, Point);
public: void DrawLine(Pen*, PointF, PointF);
public: void DrawLine(Pen*, int, int, int, int);
public: void DrawLine(Pen*, float, float, float, float);
System::Drawing::Pen
private: System::Void button1_Click_5(System::Object^ sender,
System::EventArgs^ e)
{
System::Drawing::Pen ^ MyPen = gcnew Pen(Color::Red);
Drawing::Graphics::DrawLine( MyPen, 2, 3, 4, 5);
}
System::Drawing
System::Drawing
• What will happen now?
private: System::Void button1_Click_5(System::Object^ sender,
System::EventArgs^ e)
{
System::Drawing::Pen ^ MyPen = gcnew Pen(Color::Red);
Drawing::Graphics::DrawLine( MyPen, 2, 3, 4,5 );
}

Compiler error
System::Drawing
• What will happen now?
private: System::Void button1_Click_5(System::Object^ sender,
System::EventArgs^ e)
{
System::Drawing::Pen ^ MyPen = gcnew Pen(Color::Red);
Drawing::Graphics ^MyGraphics;
MyGraphics->DrawLine( MyPen, 2, 3, 4,5 );
}

No compiler error but Runtime error when clicking button1
System::Drawing
• What will happen now?
private: System::Void button1_Click_5(System::Object^ sender, System::EventArgs^
e)
{
System::Drawing::Pen ^ MyPen = gcnew Pen(Color::Red);
Drawing::Graphics ^MyGraphics;
MyGraphics = pictureBox1->CreateGraphics();
MyGraphics->DrawLine( MyPen, 2, 3, 50,105 );
}
A line will be drawn!
System::Drawing
• After clicking the button
System::Drawing
• Can we do this?
private: System::Void button1_Click_5(System::Object^ sender,
System::EventArgs^ e)
{
Drawing::Graphics ^MyGraphics;
MyGraphics = pictureBox1->CreateGraphics();
MyGraphics->DrawLine(System::Drawing::Pen(Color::Red),2,3,50,105);
}
Compiler error
System::Drawing
• But remember we can just do this
private: System::Void button1_Click_5(System::Object^ sender, System::EventArgs^
e)
{
System::Drawing::Pen ^ MyPen = gcnew Pen(Color::Red);
Drawing::Graphics ^MyGraphics;
MyGraphics = pictureBox1->CreateGraphics();
MyGraphics->DrawLine( MyPen, 2, 3, 50,105 );
}
System::Drawing
• What will happen now?
private: System::Void button1_Click_5(System::Object^ sender,
System::EventArgs^ e)
{
System::Drawing::Pen ^ MyPen = gcnew Pen(Color::Red);
Drawing::Graphics ^MyGraphics;
MyGraphics = pictureBox1->CreateGraphics();
Drawing::Point P1, P2;
P1.X = 50; P1.Y = 60;
P2.X = 150; P2.Y = 160;
MyGraphics->DrawLine( MyPen, P1, P2 );
P1.X = 50; P1.Y = 60;
P2.X = 510; P2.Y = 610;
MyGraphics->DrawLine( MyPen, P1, P2 );
}
System::Drawing
• What’s missing? Now we’ll find out!
System::Drawing
• Now, let’s have the following
private: System::Void button1_Click_5(System::Object^ sender,
System::EventArgs^ e)
{
System::Drawing::Pen ^ MyPen = gcnew Pen(Color::Red);
Drawing::Graphics ^MyGraphics;
MyGraphics = pictureBox1->CreateGraphics();
Drawing::Point P1, P2;
P1.X = 50; P1.Y = 60;
P2.X = 150; P2.Y = 160;
MyGraphics->DrawLine( MyPen, P1, P2 );
P1.X = 50; P1.Y = 60;
P2.X = 510; P2.Y = 30;
MyGraphics->DrawLine( MyPen, P1, P2 );
}
System::Drawing
System::Drawing
• Now, when scrolling the line should be appeared, right?
System::Drawing
• Now moving the scroll forward

Nothing!
System::Drawing
• Now moving the scroll backward

Nothing!
Control.Paint() Event
• Control.Paint Event
– Occurs when the control is redrawn
Control.Paint() Event
Control.Paint() Event

private: System::Void pictureBox1_Paint(System::Object^
sender, System::Windows::Forms::PaintEventArgs^ e)
{

}
System::Drawing
• How to solve this?!
– Storing the lines* we have in ??
• Linked list / List for example

– Then, when re-painting the pictureBox
• Re-drawing the hole line all over again!

____________________________________________________
* Note that we don’t have sth called “line” so we need to wrap it oursleves
System::Drawing
• Header of class Line
#pragma once
ref class Line
{
public:
System::Drawing::Point P1;
System::Drawing::Point P2;
Line();
Line(System::Drawing::Point p1, System::Drawing::Point p2);
};
System::Drawing
• cpp of class Line
#include "StdAfx.h"
#include "Line.h"
Line::Line()
{
P1 = System::Drawing::Point(0, 0);
P2 = System::Drawing::Point(0, 0);
}
Line::Line(System::Drawing::Point p1, System::Drawing::Point p2)
{
P1 = p1;
P2 = p2;
}
System::Drawing
• Back to Form1
private: Drawing::Graphics ^MyGraphics;
private: Pen ^MyPen;
private: System::Collections::Generic::LinkedList <Line^>
^ MyLinesList;

private: System::Void Form1_Load(System::Object^ sender,
System::EventArgs^ e)
{
MyGraphics = pictureBox1->CreateGraphics();
MyPen = gcnew Pen(Color::Red);
MyLinesList = gcnew
System::Collections::Generic::LinkedList <Line^>;
}
System::Drawing
private: System::Void button1_Click_6(System::Object^ sender,
System::EventArgs^ e)
{
Drawing::Point P1(3,5);
Drawing::Point P2(200,50);
Line^ L1 = gcnew Line(P1, P2);
MyLinesList->AddLast(L1);
Drawing::Point P3(30,50);
Drawing::Point P4(500,20);
Line^ L2 = gcnew Line(P3, P4);
MyLinesList->AddLast(L2);
}
System::Drawing
• Form1
private: System::Void pictureBox1_Paint(System::Object^
sender, System::Windows::Forms::PaintEventArgs^ e)
{
for each(Line ^MyLine in MyLinesList)
{
Drawing::Point P1 = MyLine->P1;
Drawing::Point P2 = MyLine->P2;
MyGraphics->DrawLine(MyPen,P1, P2 );
}
}
System::Drawing
• Before clicking anything
System::Drawing
• After clicking button6 “filling the linkedList with values”
System::Drawing
• After starting to scroll which means start painting “repainting”
the pictureBox
System::Drawing
•

What should happen now after continuing to scroll?
System::Drawing
• Scroll Forward
System::Drawing
• Now, when re-scrolling back it’s there!
Clear Method
• Clears the entire drawing surface and fills it with the
specified background color.
Clear Method
• What happens now?
private: System::Void button1_Click_5(System::Object^ sender,
System::EventArgs^ e)
{
MyGraphics->Clear(Color::SkyBlue);
}
Clear Method
Refresh Method
• What will happen now?
private: System::Void button1_Click_5(System::Object^ sender,
System::EventArgs^ e)
{
pictureBox1->Refresh();
}
Refresh Method
Refresh Method
• Now, when pressing “TRY” <<Refresh method caller>> button
Refresh Method
• When scrolling again!
Refresh Method
• Now, when pressing TRY again
Refresh Method
• When scrolling again!
Refresh Method
• We usually use Refresh method with timers to refresh the
data we have in the pictureBox
• But note!
– Refresh Method :
• Forces the control to invalidate its client area and immediately redraw
itself and any child controls.
– So that, now, when we refresh the pictureBox all the lines will be cleared!!!
– So we should store them and redraw them all over again in each paint!!!
private:
Rectangle RcDraw;
void Form1_MouseDown( Object^ /*sender*/, System::Windows::Forms::MouseEventArgs^ e )
{ // Determine the initial rectangle coordinates.
RcDraw.X = e->X; RcDraw.Y = e->Y; }
void Form1_MouseUp( Object^ /*sender*/, System::Windows::Forms::MouseEventArgs^ e )
{
// Determine the width and height of the rectangle.
if( e->X < RcDraw.X )
{ RcDraw.Width = RcDraw.X - e->X; RcDraw.X = e->X; }
else
{ RcDraw.Width = e->X - RcDraw.X; }
if( e->Y < RcDraw.Y )
{ RcDraw.Height = RcDraw.Y - e->Y; RcDraw.Y = e->Y; }
else
{ RcDraw.Height = e->Y - RcDraw.Y; }
// Force a repaint of the region occupied by the rectangle.
this->Invalidate( RcDraw );
}
void Form1_Paint( Object^ /*sender*/, System::Windows::Forms::PaintEventArgs^ e )
{ // Draw the rectangle.
float PenWidth = 5;
e->Graphics->DrawRectangle( gcnew Pen( Color::Blue,PenWidth ), RcDraw ); }
Graphics::Draw
• You can draw whatever you want!
Example : Graphics::DrawString
public:
void DrawStringRectangleF( PaintEventArgs^ e )
{
// Create string to draw.
String^ drawString = "Sample Text";
// Create font and brush.
System::Drawing::Font^ drawFont = gcnew System::Drawing::Font( "Arial",16 );
SolidBrush^ drawBrush = gcnew SolidBrush( Color::Black );
// Create rectangle for drawing.(FLOATING POINT NUMBERS)
float x = 150.0F;
float y = 150.0F;
float width = 200.0F;
float height = 50.0F;
RectangleF drawRect = RectangleF(x,y,width,height);

// Draw rectangle to screen.
Pen^ blackPen = gcnew Pen( Color::Black );
e->Graphics->DrawRectangle( blackPen, x, y, width, height );
// Draw string to screen.
e->Graphics->DrawString( drawString, drawFont, drawBrush, drawRect );
}
Drawing with timer
private: System::Void timer1_Tick(System::Object^ sender,
System::EventArgs^ e)
{
static int x1 = 0, x2 = 10;
static int y1 = 0, y2 = 10;
srand(time(0));
x2+= rand()%30; y2+=rand()%30;
MyGraphics->DrawLine(MyPen, x1, y1, x2, y2 );
x1 = x2; y1 = y2;
}
// We can use.

Random R;
int x2 = R.Next(150); // No seed
Drawing with timer
Drawing with timer
• What will happen now?
private: System::Void timer1_Tick(System::Object^ sender,
System::EventArgs^ e)
{
static int x1 = 0, x2 = 10;
static int y1 = 0, y2 = 10;
srand(time(0));
x2+= rand(); y2+=rand(); // no %30
MyGraphics->DrawLine(MyPen, x1, y1, x2, y2 );
x1 = x2; y1 = y2;
}
Drawing with timer
Drawing with timer
• What will happen now?
private: System::Void timer1_Tick(System::Object^ sender,
System::EventArgs^ e)
{
static int x1 = 0, x2 = 10;
static int y1 = 0, y2 = 10;
x2+= 30; y2+=10;
MyGraphics->DrawLine(MyPen, x1, y1, x2, y2 );
x1 = x2; y1 = y2;
}
Drawing with timer
Drawing with sleep
private: System::Void button1_Click_6(System::Object^ sender,
System::EventArgs^ e)
{
for(int i = 0; i < 10; i++)
{
static int x1 = 0, x2 = 10;
static int y1 = 0, y2 = 10;
srand(time(0));
x2+= rand()%40; y2+= rand()%30;
MyGraphics->DrawLine(MyPen, x1, y1, x2, y2 );
Threading::Thread::Sleep(1000);
x1 = x2; y1 = y2;
}
}
Drawing with sleep
Drawing with sleep –
Refresh methods
• What will happens? :D
private: System::Void button1_Click_6(System::Object^ sender,
System::EventArgs^ e)
{
for(int i = 0; i < 10; i++)
{
static int x1 = 0, x2 = 10;
static int y1 = 0, y2 = 10;
srand(time(0));
x2+= rand()%40; y2+= rand()%30;
MyGraphics->DrawLine(MyPen, x1, y1, x2, y2 );
Threading::Thread::Sleep(1000);
x1 = x2; y1 = y2;
pictureBox1->Refresh();
}
}
Drawing with sleep –
Refresh methods
Refresh Method
• Remember :
– Refresh Method :
• Forces the control to invalidate its client area and immediately redraw
itself and any child controls.
– So that, now, when we refresh the pictureBox all the lines will be cleared!!!
– So we should store them and redraw them all over again in each paint!!!
Drawing with sleep and timer!
• What is that?!
private: System::Void timer1_Tick(System::Object^ sender,
System::EventArgs^ e)
{
static int x1 = 0, x2 = 10;
static int y1 = 0, y2 = 10;
srand(time(0));
x2+= rand()%30; y2+=rand()%30;
MyGraphics->DrawLine(MyPen, x1, y1, x2, y2 );
x1 = x2; y1 = y2;
Threading::Thread::Sleep(1000);
}
Drawing with sleep and timer!
Drawing with sleep and timer!
• What is that?!
private: System::Void timer1_Tick(System::Object^ sender,
System::EventArgs^ e)
{
static int x1 = 0, x2 = 10;
static int y1 = 0, y2 = 10;
srand(time(0));
x2+= rand()%30; y2+=rand()%30;
MyGraphics->DrawLine(MyPen, x1, y1, x2, y2 );
x1 = x2; y1 = y2;
Threading::Thread::Sleep(1000);
pictureBox1->Refresh();
}
Drawing with sleep and timer!
Now, every two
seconds a line will
be drawn and
cleared for another
one to be shown
Drawing with angles?
private: System::Void timer1_Tick(System::Object^ sender,
System::EventArgs^ e)
{
static int x1 = 0, x2 = 10;
static int y1 = 0, y2 = 10;
srand(time(0));
x2+= Math::Cos(rand())*20;
y2+= Math::Cos(rand())*20;
MyGraphics->DrawLine(MyPen, x1, y1, x2, y2 );
x1 = x2; y1 = y2;
}
Drawing with angles?
Drawing with angles?
public : Drawing::Pen ^MyPen;
private: System::Void timer1_Tick(System::Object^ sender,
System::EventArgs^ e)
{
static int x1 = 0, x2 = 10;
static int y1 = 0, y2 = 10;
srand(time(0));
x2+= Math::Cos(rand())*(rand()%30);
y2+= Math::Cos(rand())*(rand()%30);
MyGraphics->DrawLine(MyPen, x1, y1, x2, y2 );
x1 = x2;
y1 = y2;
}
};
Drawing with angles?
Drawing with angles?
Drawing with angles?
• Precedence?
public : Drawing::Pen ^MyPen;
private: System::Void timer1_Tick(System::Object^ sender,
System::EventArgs^ e)
{
static int x1 = 0, x2 = 10;
static int y1 = 0, y2 = 10;
srand(time(0));
x2+= Math::Cos(rand())*rand()%30;
y2+= Math::Cos(rand())*rand()%30;
MyGraphics->DrawLine(MyPen, x1, y1, x2, y2 );
x1 = x2;
y1 = y2;
}
};
•Also remember that we can use for sincos
• Math::PI
Drawing And filling
• Brush :
– Defines objects used to fill the interiors of graphical shapes such as
rectangles, ellipses, pies, polygons, and paths.
Drawing And filling
Drawing And filling
• What will happen now?
private: System::Void button1_Click_6(System::Object^ sender,
System::EventArgs^ e)
{
Drawing::Rectangle MyRect(50,30,60,100);
Drawing::Brush ^MyBrush;
MyGraphics->FillEllipse(MyBrush, MyRect );
}
Compiler error
Drawing And filling
private: System::Void button1_Click_6(System::Object^ sender,
System::EventArgs^ e)
{
Drawing::Rectangle MyRect(50,30,60,100);
Drawing::Brush ^MyBrush;
MyBrush = gcnew Drawing::Brush;
MyGraphics->FillEllipse(MyBrush, MyRect );
}
Compiler error
Drawing And filling
private: System::Void button1_Click_6(System::Object^ sender,
System::EventArgs^ e)
{
Drawing::Rectangle MyRect(50,30,60,100);
Drawing::Brush ^MyBrush;
MyBrush = gcnew Drawing::SolidBrush(Color ::Yellow);
MyGraphics->FillEllipse(MyBrush, MyRect );
}
Drawing And filling
Drawing And filling
private: System::Void button1_Click_6(System::Object^ sender,
System::EventArgs^ e)
{
Drawing::Rectangle MyRect(50,30,60,100);
Drawing::Brush ^MyBrush;
MyBrush = gcnew Drawing::SolidBrush(Color ::Brown);
MyGraphics->FillEllipse(MyBrush, MyRect );
}
Drawing And filling
Drawing And filling