GDI+ from a GDI Perspective

This section is for GDI programmers. To build on your existing knowledge, we will compare and contrast GDI and GDI+. If you've never worked with GDI, we recommend that you skip this section.

We have already mentioned the first and major difference between the two versions: Whereas GDI+ exposes its functionality as both unmanaged and managed classes (through the System.Drawing namespace), GDI is unmanaged only. Besides this major difference, some of the important changes in GDI+ are as follows:

  • No handles or device contexts
  • Object-oriented approach
  • Graphics object independence
  • Method overloading
  • Separate methods for draw and fill
  • Regions and their styles

1.3.1 Elimination of Handles and Device Contexts

As a GDI programmer, you must be familiar with the device context. A device context is a structure that stores information about a particular display device, such as a printer or monitor. This structure specifies how the graphics objects will be drawn on the output device. The device context also stores information about the properties of graphics objects, such as the quality of rendering and so on. To draw an object on a device, first an application needs to get a handle to the device context (HDC), which is used by GDI to send information to the device.

In GDI+, the concept of device context and handle to the device context is replaced by the Graphics object. The Graphics class provides methods and properties to draw various graphics objects; these methods and properties are very easy to use compared to the earlier device contextbased programming model.

Suppose that you need to draw a line from point (20, 20) to point (200, 200). In GDI, first an application creates an HDC using the BeginPaint function, which takes a window handle and a PAINTSTRUCT structure. Alternatively, you can call the GetDC function. To draw a line, the application must create a pen object and draw a line using this pen. An application can obtain a pen object by making a call to the CreatePen function, which returns a handle to the pen.

Before starting to draw, the application needs to call the SelectObject function, which takes the device context and pen handle as arguments. Now the application can draw any graphics object. The application calls the EndPaint function to end the drawing process. For example, the code snippet in Listing 1.1 draws a line using the MoveToEx and LineTo functions.

Listing 1.1 C++ code to draw a line

LRESULT APIENTRY MainWndProc(
 HWND hwnd, UINT message, WPARAM wParam,
 LPARAM lParam)
{
 PAINTSTRUCT ps;
 switch (message)
 {
 case WM_PAINT:
 HDC handle;
 PAINTSTRUCT pstruct;
 HPEN hPen;
 ...
 ....
 handle = BeginPaint(hWnd, &pstruct);
 hPen = CreatePen(PS_SOLID, 5,
 RGB(255, 255, 0));
 SelectObject(handle, hPen);
 MoveToEx(handle, 20, 20, NULL);
 LineTo(handle, 200, 200);
 EndPaint(hWnd, &pstruct);
 ..................
 .....................
 }
}

Now let's see the same example in GDI+: First you need a Graphics object associated with a form, which is usually available on the form's Form_Paint event or OnPaint method. Once you've got the Graphics object associated with a form, you can call its draw and fill methods to draw and fill various graphics objects, such as lines, rectangles, and curves. For example, the code written in Listing 1.2 is the form's paint method. As this code shows, first we get a Graphics object associated with the form by using PaintEventArgs.Graphics. After that we create a Pen object and pass it as an argument to the DrawLine method. The DrawLine method takes a Pen object and the starting and ending points of a line, and draws a line on the form. Notice also in Listing 1.2 that there is no MoveTo call.

Listing 1.2 GDI+ code in C# to draw a line

private void Form1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Pen pn = new Pen(Color.Red, 3);
g.DrawLine(pn, 20, 20, 200, 200);
}

Note

There are other ways to get a Graphics object in your application. We will look at these options in more detail in Chapter 3.

 

1.3.2 Object-Oriented Approach

If you compare Listings 1.1 and 1.2, it's easy to see that the GDI+ model is more flexible, easier to use, and more object-oriented. GDI provides functions to draw graphics objects; GDI+ provides objects. Each graphics primitive is an object. For example, in GDI+, a pen is represented by a Pen object, as opposed to the HPEN structure in GDI.

1.3.3 Graphics Object Independence

In GDI, first you select a brush, path, image, or font and pass this object a device context. Then you use the device context handle to draw a graphics object, which means all the objects drawn using that device context will have the same effects.

Unlike GDI, GDI+ provides an object-independent model, which means that pens, brushes, images, or fonts can be created and used independently and can be changed at any time. In addition, an application can even use different pens to draw different graphics objects on the same form, which is not true in the case of a device context.

1.3.4 Method Overloading

GDI+ methods provide many overloaded forms to provide more flexibility to developers. For example, the DrawRectangle method has three overloaded forms:

  1. public void DrawRectangle(Pen, Rectangle);
  2. public void DrawRectangle(Pen, int, int, int, int);
  3. public void DrawRectangle(Pen, float, float, float, float);

These forms allow developers to draw a rectangle from a rectangle object, four integer values, or floating point values. The DrawRectangle method draws a rectangle specified by a coordinate pair, a width, and a height. The DrawImage method, used to draw images, has no fewer than 30 overloaded forms. We will discuss these methods in more detail and see them in action in Chapter 3.

1.3.5 Draw and Fill Methods

Drawing and filling are analogous to writing and painting. When you write, you use a pen to "draw" symbols made up of lines and curves. Painting means you take a brush, dip it into a color, and fill in areas with the color.

In GDI, both actions (fill and draw) are done in one step. For example, consider drawing and filling a rectangle. First an application creates a pen and a brush and calls SelectObject to select that pen and brush. Then the application calls the Rectangle method, which draws and fills the rectangle. Listing 1.3 shows a code snippet that draws and fills a rectangle.

Listing 1.3 GDI code to draw and fill a rectangle

hBrush = CreateHatchBrush(HS_CROSS, RGB(255, 0, 0));
hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
SelectObject(hdc, hBrush);
SelectObject(hdc, hPen);
Rectangle(hdc, 20, 20, 200, 200);

In GDI+, the Graphics class provides separate draw and fill methods. For example, the DrawRectangle method takes a Pen object and draws an outline of a rectangle, and the FillRectangle method takes a Brush object and fills the rectangle with the specified brush, as Listing 1.4 shows.

Listing 1.4 GDI+ code to draw and fill a rectangle

Graphics g = e.Graphics;
Pen pn = new Pen(Color.Red, 3);
HatchBrush htchBrush = new HatchBrush(HatchStyle.Cross,
Color.Red, Color.Blue);
g.DrawRectangle(pn, 50, 50, 100, 100);
g.FillRectangle(htchBrush, 20, 20, 200, 200);

We will discuss the draw and fill methods in more detail in Chapter 4.

1.3.6 Regions and Their Styles

Regions are another area where a GDI developer may find minor changes in GDI+. GDI provides several functions for creating elliptical, round, and polygonal regions. As a GDI programmer, you are probably familiar with the CreateRectRgn, CreateEllipticRgn, CreateRoundRectRgn, CreatePolygonRgn, and CreatePolyPolygonRgn functions.

In GDI+, the Region class represents a region. The Region class constructor takes an argument of type GraphicsPath, which can have a polygon, a circle, or an ellipse to create a polygonal, round, or elliptical region, respectively. We will discuss regions in more depth in Chapter 6.

GDI+: The Next-Generation Graphics Interface

Your First GDI+ Application

The Graphics Class

Working with Brushes and Pens

Colors, Fonts, and Text

Rectangles and Regions

Working with Images

Advanced Imaging

Advanced 2D Graphics

Transformation

Printing

Developing GDI+ Web Applications

GDI+ Best Practices and Performance Techniques

GDI Interoperability

Miscellaneous GDI+ Examples

Appendix A. Exception Handling in .NET



GDI+ Programming with C#
GDI+ Programming with C#
ISBN: 073561265X
EAN: N/A
Year: 2003
Pages: 145

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net