Languages - DevSource
DevSource: Microsoft Developer Resource DevSource Home Sponsored by Microsoft Home Add Ons Architecture Languages Techniques Using VS Forums
Home arrow Languages arrow Page 2 - Getting Started with GDI+ in C# Applications
Getting Started with GDI+ in C# Applications
By Rick Leinecker

Rate This Article: Add This Article To:

Getting Started with GDI+ in C# Applications - ' Graphics Objects and Mice '
( Page 2 of 2 )

Getting and Using a Graphics Object

The OnPaint method is fired when your application must redraw in response to events from other applications. And as we've talked about, your own code can trigger OnPaint. But that isn't always the best way to redraw your graphics. Sometimes it's best to have all of your drawing code in a separate method that takes a Graphics object as a parameter. In this way, the OnPaint method can call the draw method when it needs to, but your code can also directly call the draw method without having to trigger the OnPaint method with the Invalidate and Update method pair.

ADVERTISEMENT

When you invalidate the entire application, other things besides the client region such as user interface objects might redraw. Not invaliding the entire application and calling the method that draws the client region can make your application's redraw process appear smoother since the user interface objects don't redraw.

Let's first look at a program that forces a redraw using Invalidate and Update. Shortly thereafter we'll then make adjustments to this program that will follow the procedure of obtaining a Graphics object and calling the draw method directly instead of invalidating an entire application.

// Variable that determines the x coordinate of the left
//   endpoint of the line.
int m_nX = 0;

// The draw method. It takes a single Graphics object parameter
//   to which the drawing occurs.
public void Draw(Graphics g)
{
     // Draw three slightly different lines.
     g.DrawLine(new Pen(Color.Black), m_nX, 0, 250, 250);
     g.DrawLine(new Pen(Color.Red), m_nX, 0, 250, 270);
     g.DrawLine(new Pen(Color.Green), m_nX, 0, 250, 290);
}

// Here's OnPaint. Notice that it calls Draw and
//   passes e.Graphics.
private void OnPaint(object sender, PaintEventArgs e)
{
     Draw(e.Graphics);
}

// This method responds to a mouse up event and adds 10
//   to the x coordinate of the line left endpoint.
private void OnMouseUp(object sender, MouseEventArgs e)
{
     m_nX += 10;
     // Force a redraw.
     Invalidate();
     Update();
}

We'll change the OnMouseUp method's code. After the variable is incremented, we'll obtain a Graphics object to the client region of the application window and call the Draw method. First, though, you must obtain a Graphics object that you can pass to the draw method. The following code shows how to obtain the Graphics object that you need.

Graphics g = Graphics.FromHwnd(this.Handle);

Now the revised OnMouseUp method will be as follows:

// This method responds to a mouse up event and adds 10
//   to the x coordinate of the line left endpoint.
private void OnMouseUp(object sender, MouseEventArgs e)
{
     m_nX += 10;
     // Get the Graphics object.
     Graphics g = Graphics.FromHwnd(this.Handle);
     // Call the Draw method.
     Draw(g);
}

There is still one problem. The background doesn't redraw now. The framework draws the background before your OnPaint method is called. You can see in the following figure that after a few mouse clicks there are a lot of lines on the window.

The following code redraws the client region background. The ClientRectangle object is a member of the Form class. The BackColor property is also a member of the Form class.

// Draw the background rectangle
g.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);

The updated OnMouseUp method is as follows:

// This method responds to a mouse up event and adds 10
//   to the x coordinate of the line left endpoint.
private void OnMouseUp(object sender, MouseEventArgs e)
{
     m_nX += 10;
     // Get the Graphics object.
     Graphics g = Graphics.FromHwnd(this.Handle);
     // Draw the background rectangle
     g.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);
     // Call the Draw method
     Draw(g);
}

You can download the sample project named GraphicsClass here.

Drawing When the Mouse Moves

There's one more good example to show how to redraw in response to something, but without triggering the OnPaint method. The code from a program named MouseMoveDrawDemo is below. When the mouse moves, the Draw method is called.

// x and y variables for drawing.
int m_nX = 50, m_nY = 50;

// The Draw method.
private void Draw(Graphics g)
{
     // Draw the ellipse.
     g.FillEllipse(new SolidBrush(Color.Green), m_nX, m_nY, 30, 30);
}

// This is fired when the mouse moves.
private void OnMouseMove(object sender, MouseEventArgs e)
{
     // Set our x and y variables to the mouse x and y.
     m_nX = e.X;
     m_nY = e.Y;
     // Get the graphics object for the applciation client region.
     Graphics g = Graphics.FromHwnd(this.Handle);
     // Draw the background.
     g.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);
     // Call the Draw method.
     Draw(g);
}

// This is fired when the application needs to be redrawn.
private void OnPaint(object sender, PaintEventArgs e)
{
     // Call the Draw method.
     Draw(e.Graphics);
}

You can download the sample project named MouseMoveDrawDemo here.

Next week

Next week we'll continue with a discussion of how to draw various shapes such as rectangles and ellipses. Don't miss it!



 
 
>>> More Languages Articles          >>> More By Rick Leinecker
 



Microsoft's Future: A Chat With Their CTO, Barry Briggs

Play Video >

All Videos >

Julia explores the Robotics Studio!

Read now >

Messages to Bill Gates!

Read now >

View Now
DevSource RSS FEEDS
XML Want an easy way to keep up with breaking tech news? And the Get DevSource headlines delivered to your desktop with RSS.