Understanding the Graphics Object


At first, you might not come up with many reasons to draw to the screen, preferring to use the many advanced controls found within Visual C# to build your interfaces. However, as your applications grow in size and complexity, you'll find more and more occasion to draw your own interfaces directly to the screen; when you need this functionality, you really need this functionality. You might even choose to design your own controls (which you can do with Visual C#). In this hour, you'll learn the basics of drawing and printing to the screen. Using the skills you acquire in this hour, you'll be able to build incredibly detailed interfaces that look exactly the way you want them to look.

The code within the Windows operating system that handles drawing everything to the screen, including text, lines, and shapes, is called the Graphics Device Interface (GDI). The GDI processes all drawing instructions from applications as well as from Windows itself and generates the output for the current display. Because the GDI generates what you see onscreen, it has the responsibility of dealing with the particular display driver installed on the computer and the settings of the driver, such as resolution and color depth. That means applications (and their developers) don't have to worry about these details; you write code that tells the GDI what to output, and the GDI does whatever is necessary to produce that output. This behavior is called device independence because applications can instruct the GDI to display text and graphics using code that's independent of the particular display device.

Visual C# code communicates with the GDI primarily via the Graphics object. The basic process is as follows:

  • An object variable is created to hold a reference to a Graphics object.

  • The object variable is set to a valid Graphics object (new or existing).

  • To draw or print, you call methods of the Graphics object.

Creating a Graphics Object for a Form or Control

If you want to draw directly to a form or control, you can easily get a reference to the drawing surface by calling the CreateGraphics() method of the object in question. For example, to create a Graphics object that draws to a text box, you could use code such as this:

System.Drawing.Graphics objGraphics; objGraphics = this.textBox1.CreateGraphics();


When you call CreateGraphics(), you're setting the object variable to hold a reference to the Graphics object of the form or control's client area. The client area of a form is the gray area within the borders and title bar of the form, whereas the client area of a control is usually the entire control. All drawing and printing done using the Graphics object is sent to the client area. In the code shown previously, the Graphics object references the client area of a text box, so all drawing methods executed on the Graphics object would draw directly to the text box.

By the Way

When you draw directly to a form or control, the object in question doesn't persist what's drawn on it. If the form is obscured in any way, such as by a window covering it or by minimizing the form, the next time the form is painted, it won't contain anything that was drawn on it. Later in this hour, I'll teach you how to persist graphics on a form.


Creating a Graphics Object for a New Bitmap

You don't have to set a Graphics object to the client area of a form or control; you can also set a Graphics object to a bitmap that exists only in memory. For performance reasons, you might want to use a memory bitmap to store temporary images or as a place to build complex graphics before sending them to a visible element (such as a form or control). To do this, you first have to create a new bitmap.

To create a new bitmap, you dimension a variable to hold a reference to the new bitmap using the following syntax:

Bitmapvariable = new Bitmap(width, height, pixelformat);


The width and height arguments are exactly what they appear to be: the width and height of the new bitmap. The pixelformat argument, however, is less intuitive. This argument determines the color depth of the bitmap and might also specify whether the bitmap has an alpha layer (used for transparent portions of bitmaps). Table 18.1 lists a few of the common values for pixelformat (see Visual C#'s online Help for the complete list of values and their meanings).

Table 18.1. Common Values for pixelformat

Value

Description

Format16bppGrayScale

The pixel format is 16 bits per pixel. The color information specifies 65,536 shades of gray.

Format16bppRgb555

The pixel format is 16 bits per pixel. The color information specifies 32,768 shades of color, of which 5 bits are red, 5 bits are green, and 5 bits are blue.

Format24bppRgb

The pixel format is 24 bits per pixel. The color information specifies 16,777,216 shades of color, of which 8 bits are red, 8 bits are green, and 8 bits are blue.


To create a new bitmap that's 640 pixels wide by 480 pixels tall and has a pixel depth of 24 bits, for example, you could use this statement (assuming you had a variable named objMyBitMap declared):

objMyBitMap = new Bitmap(640, 480,         System.Drawing.Imaging.PixelFormat.Format24bppRgb);


After the bitmap is created, you can create a Graphics object that references the bitmap using the FromImage() method, like this:

objGraphics = Graphics.FromImage(objMyBitMap);


Now any drawing or printing done using objGraphics would be performed on the memory bitmap. For the user to see the bitmap, you'd have to send the bitmap to a form or control. You'll do this later in this hour in the section "Persisting Graphics on a Form."

Disposing of an Object When It Is No Longer Needed

When you're finished with a Graphics object, you should call its Dispose() method to ensure that all resources used by the Graphics object are freed. Simply letting an object variable go out of scope doesn't ensure that the resources used by the object are freed. Graphics objects can use considerable resources, so you should always call Dispose() when you're finished with any graphics object (including Pens and other types of objects).

Visual C# also supports a way of automatically disposing object resources. This can be accomplished utilizing Visual C# using statement. The using statement wraps a declared object or objects in a block and disposes of those objects after the block is done. As a result, after the code is executed in a block, the block is exited and the resources are disposed of on exit. Following is the syntax for the using statement and a small sample:

using (expression | type identifier = initializer) {    // Statements to execute }


Example:

using (MyClass objClass = new MyClass()) {    objClass.Method1();    objClass.Method2(); }


One thing to keep in mind is that the using statement acts as a wrapper for an object within a specified block of code; therefore, it is only useful for declaring objects that are used and scoped within a method (scope is discussed in Hour 11, "Using Constants, Data Types, Variables, and Arrays").

By the Way

Earlier in the book you learned how to use a using statement to include a name-space, such as System.Diagnostics. Note that the use of using in this case is different; the same keyword is used for multiple purposes.





Sams Teach Yourself Microsoft Visual C# 2005 in 24 Hours, Complete Starter Kit
Sams Teach Yourself Visual C# 2005 in 24 Hours, Complete Starter Kit
ISBN: 0672327406
EAN: 2147483647
Year: N/A
Pages: 248
Authors: James Foxall

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