Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C# ПІДРУЧНИКИ / c# / Hungry Minds - C# Bible

.pdf
Скачиваний:
226
Добавлен:
12.02.2016
Размер:
4.21 Mб
Скачать

class FileTestClass

{

private

BinaryWriter

Writer;

private

FileStream

BinaryFile;

public FileTestClass()

{

BinaryFile = new FileStream("test.dat", FileMode.Create, FileAccess.ReadWrite);

Writer = new BinaryWriter(BinaryFile);

}

public void WriteBinaryData()

{

Writer.Write('a');

Writer.Write(123);

Writer.Write(456.789); Writer.Write("test string");

}

}

class MainClass

{

static public void Main()

{

FileTestClass FileTest = new FileTestClass();

FileTest.WriteBinaryData();

}

}

The code in Listing 25-4 is structured with a class design similar to the design in Listing 25-3. The code contains a MainClass and a FileTestClass. The constructor of the FileTestClass class in Listing 25-4 creates a file stream and then creates a BinaryWriter object. A reference to the file stream is passed to the constructor of the BinaryWriter object, which sets up the relationship between the binary writer and the stream to which it writes its data. In Listing 25- 4, all data written to the binary writer eventually makes its way to the file stream set up in the constructor.

The WriteBinaryData() method writes a character, an integer, a double, and a string to the underlying stream. The BinaryWriter class implements several overloads of a method named Write(). The Write() method overloads support the writing of the following data types to the writer class:

Booleans

Bytes

Arrays of bytes

Characters

Arrays of characters

Decimal values

Double values

Signed and unsigned short integer values

Signed and unsigned integer values

Signed and unsigned long integer values

Sbytes

Floating-point values

Strings

If you compile and execute the code in Listing 25-4, a file called test.dat is created. You can examine the contents of the new file in a hex editor to verify that binary representations of values were written to the file.

Reading from streams with BinaryReader

Listing 25-5 adds the BinaryReader class to the code in Listing 25-5. This class reassembles stream bytes back into their constituent data types and returns the values to the caller.

Listing 25-5: Working with the BinaryReader Class

using System; using System.IO;

class FileTestClass

 

{

Reader;

private BinaryReader

private BinaryWriter

Writer;

private FileStream

BinaryFile;

public FileTestClass()

{

BinaryFile = new FileStream("test.dat", FileMode.Create, FileAccess.ReadWrite);

Writer = new BinaryWriter(BinaryFile); Reader = new BinaryReader(BinaryFile);

}

public void ReadBinaryData()

{

char ReadCharacter; double ReadDouble; int ReadInteger; string ReadString;

BinaryFile.Seek(0, SeekOrigin.Begin);

ReadCharacter = Reader.ReadChar();

ReadInteger = Reader.ReadInt32();

ReadDouble = Reader.ReadDouble();

ReadString = Reader.ReadString();

Console.WriteLine("Character: {0}", ReadCharacter); Console.WriteLine("Integer: {0}", ReadInteger); Console.WriteLine("Double: {0}", ReadDouble); Console.WriteLine("String: {0}", ReadString);

}

public void WriteBinaryData()

{

Writer.Write('a');

Writer.Write(123);

Writer.Write(456.789); Writer.Write("test string");

}

}

class MainClass

{

static public void Main()

{

FileTestClass FileTest = new FileTestClass();

FileTest.WriteBinaryData();

FileTest.ReadBinaryData();

}

}

Unlike the BinaryWriter class, which contained one overloaded method for all operations, the BinaryReader class contains separate read methods for each data type. The code in Listing 25- 5 uses some of these read methods, such as ReadChar() and ReadInt32(), to read values from the stream written in the WriteBinaryData() method. The values read from the stream are sent to the console. Executing Listing 25-5 should produce the following output on the console:

Character: a

Integer: 123

Double: 456.789

String: test string

Writing Well-Formed XML Using the XmlWriter Stream

Streams can do more than simply read from and write to various data streams. They can also add value to the data being sent through the stream. A good example of this technology is the XmlWriter class, which encapsulates data sent to a stream within well-formed XML elements. The result is a well-formed XML document that can be processed by any XML document processor, as shown in Listing 25-6.

Listing 25-6: Writing XML with the XmlWriter Class

using System; using System.IO; using System.Xml;

class XMLStreamWriterClass

{

private XmlTextWriter XmlWriter;

public void WriteXML()

{

XmlWriter = new XmlTextWriter(Console.Out);

XmlWriter.WriteStartDocument(); XmlWriter.WriteComment("This XML document was automatically

generated by C# code.");

XmlWriter.WriteStartElement("BOOK"); XmlWriter.WriteElementString("TITLE", "C# Bible"); XmlWriter.WriteElementString("AUTHOR", "Jeff Ferguson"); XmlWriter.WriteElementString("PUBLISHER", "Wiley");

XmlWriter.WriteEndElement();

XmlWriter.WriteEndDocument();

}

}

class MainClass

{

static public void Main()

{

XMLStreamWriterClass XMLStreamWriter = new XMLStreamWriterClass();

XMLStreamWriter.WriteXML();

}

}

The code in Listing 25-6 creates a new instance of the XmlWriter class and associates it with the console's output stream, which sends the stream's output to the application console. The code simply calls various methods in the XmlWriter class to output data, and the methods surround the data with XML elements names that are specified when the method is called. Take a look at the following line from Listing 25-6:

XmlWriter.WriteElementString("AUTHOR", "Jeff Ferguson");

This call instructs the XmlWriter class to write an XML element called <AUTHOR>, which has a value of Brian Patterson, to the stream output device. The method's implementation supplies the XML end tag automatically.

Compiling and executing the code in Listing 25-6 sends the following well-formed XML document to the application console:

<?xml version="1.0" encoding="IBM437"?>

<!--This XML document was automatically generated by C# code.--> <BOOK>

<TITLE>C# Bible</TITLE> <AUTHOR>Jeff Ferguson</AUTHOR> <PUBLISHER>Wiley</PUBLISHER> </BOOK>

Summary

Streams provide powerful support for both synchronous and asynchronous I/O for your C# applications. Streams operate at the byte level and require you to read and write blocks of bytes. Readers and writers encapsulate streams and provide access to data at a higher level.

You can use readers and writers to work with standard C# data types, enabling the readers and writers to translate between the data type values and their byte representations.

Your C# code will most likely work with readers and writers, as they provide support for working with the standard data types without forcing you to be concerned about translating between a data type value and its binary representation. Streams are available, however, should you feel the need to work with them directly. You might also want to work with streams if the data that you are reading is in a proprietary format that is not supported by the standard reader and writer classes shipped with the .NET Framework. You might also

consider developing your own reader class, derived from the base TextReader or StreamReader classes, and use your class to read from the proprietary format stream.

Chapter 26: Drawing with GDI+

In This Chapter

In Windows, programmatic access to the graphics subsystem was first accomplished using the GDI APIs available since Windows 3.1. GDI offered developers the capability to control any type of user interface element, and this capability has been reworked from the ground up in the .NET Framework. GDI+ has replaced GDI as the API that is used to access the graphics subsystems of Windows. With GDI+, you can access fonts, manipulate any type of image, and work with shapes in your C# applications. To get a complete picture of how to use GDI+ in your applications, you need to understand how to use the Graphics, Pen, Brush, and Color objects. With these four objects, you can accomplish nearly anything you need to do with the GUI and images in .NET. This chapter explores these objects, and familiarizes you with using GDI+ in C#. The available classes in GDI+ could cover their own thousand-page book, so you should still use the SDK as a reference to the more complex and less frequently used graphics functionality not covered in this chapter.

Working with Graphics

When working with GDI+ in .NET, the main object that you need to work with is the Graphics object. The Graphics object is the actual surface that you use to paint shapes, work with images, or display text. Visual Basic 6 and earlier offered limited built-in support for working with graphics, making it difficult for VB developers to write custom graphics applications. The one thing that VB did do was keep track of how forms and the objects on forms were painted on the screen. The AutoRedraw property enabled your forms to let Windows keep track of what was on top of other windows and, if necessary, automatically repaint a form if another form was on top of it for any period of time. You were hidden from having to deal with the actual painting process of the form. In .NET, the exact opposite is true. The Graphics object has no memory of when it was painted or what was painted with it. Therefore, you need to redraw objects as necessary if other windows end up on top of your window. This may seem like a pain, but the PaintEventArgs variable in the Paint event of a form can handle this nicely. If your painting code is kept there, then each time Windows paints the actual form, your objects will be painted correctly.

The following code snippet receives a reference to a Graphics object through the PaintEventArgs variable in the Paint event of a form:

private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs p)

{

Graphics g = p.Graphics;

}

You can also create a Graphics object using the CreateGraphics method of a control or form. The following code demonstrates the CreateGraphics method:

private void createManually()

{

Graphics g;

g = this.CreateGraphics;

}

The third and final method of creating a Graphics object is to pass an image file directly to the object when you instantiate it, as the following code demonstrates by grabbing a bitmap image from the file system:

private void createFromFile()

{

Graphics g; Bitmap b;

b = new Bitmap(@"C:\Enterprise.bmp"); g = Graphics.FromImage(b);

}

If you have been adding these snippets to a WindowsForm, it is clear that nothing happens when any of the code executes. To actually implement some functionality, you need to use members of the Graphics class to make things happen.

Note If you create a Graphics object using the CreateGraphics method, you should call Dispose on that object after you finish using it. This ensures that the Graphics object is released from memory.

Table 26-1 lists the properties of the Graphics class, and Table 26-2 lists the available methods of the Graphics class. The Graphics class is located in the System.Drawing namespace, which is added as the default reference when you create a new Windows Forms application. This does not mean that you cannot use Graphics objects in ASP .NET; in fact, you can write extremely optimized image processing applications in ASP .NET using Graphics objects.

 

 

Table 26-1: Graphics Class Properties

Property

 

Description

 

 

 

Clip

 

Gets or sets a Region object that limits the drawing region of this

 

 

Graphics object

 

 

 

ClipBounds

 

Gets the RectangleF structure that bounds the clipping region of

 

 

this Graphics object

 

 

 

CompositingMode

 

Gets a value that specifies how composited images are drawn to

 

 

this Graphics object

 

 

 

CompositingQuality

 

Gets or sets the rendering quality of composited images drawn to

 

 

this Graphics object

 

 

 

DpiX

 

Gets the horizontal resolution of this Graphics object

 

 

 

DpiY

 

Gets the vertical resolution of this Graphics object

 

 

 

InterpolationMode

 

Gets or sets the interpolation mode associated with this Graphics

 

 

object

 

 

 

IsClipEmpty

 

Gets a value indicating whether the clipping region of this

 

 

Graphics object is empty

 

 

 

 

 

Table 26-1: Graphics Class Properties

 

 

 

 

 

Property

 

Description

 

 

 

 

 

IsVisibleClipEmpty

 

Gets a value indicating whether the visible clipping region of this

 

 

Graphics object is empty

 

 

 

 

 

PageScale

 

Gets or sets the scaling between world units and page units for

 

 

this Graphics object

 

 

 

 

 

PageUnit

 

Gets or sets the unit of measure used for page coordinates in this

 

 

Graphics object

 

 

 

 

 

PixelOffsetMode

 

Gets or sets a value specifying how pixels are offset during

 

 

rendering of this Graphics object

 

 

 

 

 

RenderingOrigin

 

Gets or sets the rendering origin of this Graphics object for

 

 

dithering and for hatch brushes

 

 

 

 

 

SmoothingMode

 

Gets or sets the rendering quality for this Graphics object

 

 

 

 

 

TextContrast

 

Gets or sets the gamma correction value for rendering text

 

 

 

 

 

TextRenderingHint

 

Gets or sets the rendering mode for text associated with this

 

 

Graphics object

 

 

 

 

 

Transform

 

Gets or sets the world transformation for this Graphics object

 

 

 

 

 

VisibleClipBounds

 

Gets or sets the bounding rectangle of the visible clipping region

 

 

of this Graphics object

 

 

 

 

 

 

 

Table 26-2: Graphics Class Methods

 

 

 

 

 

Method

 

 

 

Description

 

 

 

 

 

AddMetafileComment

 

 

 

Adds a comment to the current Metafile object

 

 

 

 

 

BeginContainer

 

 

 

Saves a Graphics container with the current state of this

 

 

 

 

Graphics object and opens and uses a new graphics container

 

 

 

 

 

Clear

 

 

 

Clears the entire drawing surface and fills it with the

 

 

 

 

specified background color

 

 

 

 

 

DrawArc

 

 

 

Draws an arc representing a portion of an ellipse specified by

 

 

 

 

a pair of coordinates, a width, and a height

 

 

 

 

 

DrawBezier

 

 

 

Draws a Bézier spline defined by four Point structures

 

 

 

 

 

DrawBeziers

 

 

 

Draws a series of Bézier splines from an array of Point

 

 

 

 

structures

 

 

 

 

 

DrawClosedCurve

 

 

 

Draws a closed cardinal spline defined by an array of Point

 

 

 

 

structures

 

 

 

 

 

DrawCurve

 

 

 

Draws a cardinal spline through a specified array of Point

 

 

 

 

structures

 

 

 

 

 

DrawEllipse

 

 

 

Draws an ellipse defined by a bounding rectangle specified

 

 

 

 

by a pair of coordinates, a height, and a width

 

 

 

 

 

DrawIcon

 

 

 

Draws the image represented by the specified Icon object at

 

 

 

 

the specified coordinates

 

 

 

 

 

DrawIconUnstretched

 

 

 

Draws the image represented by the specified Icon object

 

 

 

 

without scaling the image

 

 

 

 

 

DrawImage

 

 

 

Draws the specified Image object at the specified location

 

 

 

 

 

 

Table 26-2: Graphics Class Methods

Method

 

 

Description

 

 

 

 

 

 

 

and with the original size

 

 

 

 

DrawImageUnscaled

 

 

Draws the specified Image object with its original size at the

 

 

 

location specified by a coordinate pair

 

 

 

 

DrawLine

 

 

Draws a line connecting the two points specified by

 

 

 

coordinate pairs

 

 

 

 

DrawLines

 

 

Draws a series of line segments that connect an array of Point

 

 

 

structures

 

 

 

 

DrawPath

 

 

Draws a GraphicsPath object

 

 

 

 

DrawPie

 

 

Draws a pie shape defined by an ellipse specified by a

 

 

 

coordinate pair, a width, and a height and two radial lines

 

 

 

 

DrawPolygon

 

 

Draws a polygon defined by an array of Point structures

 

 

 

 

DrawRectangle

 

 

Draws a rectangle specified by a coordinate pair, a width,

 

 

 

and a height

 

 

 

 

DrawRectangles

 

 

Draws a series of rectangles specified by Rectangle

 

 

 

structures

 

 

 

 

DrawString

 

 

Draws the specified text string at the specified location with

 

 

 

the specified Brush and Font objects

EndContainer

Closes the current graphics container and restores the state of this Graphics object to the state saved by a call to the BeginContainer method

EnumerateMetafile

 

Sends the records in the specified Metafile object, one at a

 

 

time, to a callback method for display at a specified point

 

 

 

ExcludeClip

 

Updates the clip region of this Graphics object to exclude the

 

 

area specified by a Rectangle structure

 

 

 

FillClosedCurve

 

Fills the interior of a closed cardinal spline curve defined by

 

 

an array of Point structures

FillEllipse

Fills the interior of an ellipse defined by a bounding rectangle specified by a pair of coordinates, a width, and a height

FillPath

 

Fills the interior of a GraphicsPath object

 

 

 

FillPie

 

Fills the interior of a pie section defined by an ellipse

 

 

specified by a pair of coordinates, a width, and a height and

 

 

two radial lines

 

 

 

FillPolygon

 

Fills the interior of a polygon defined by an array of points

 

 

specified by Point structures

 

 

 

FillRectangle

 

Fills the interior of a rectangle specified by a pair of

 

 

coordinates, a width, and a height

 

 

 

FillRectangles

 

Fills the interiors of a series of rectangles specified by

 

 

Rectangle structures

 

 

 

FillRegion

 

Fills the interior of a Region object

 

Table 26-2: Graphics Class Methods

Method

 

 

Description

Flush

Forces execution of all pending graphics operations and returns immediately without waiting for the operations to finish

FromHdc

 

Creates a new Graphics object from the specified handle to a

 

 

device context

 

 

 

FromHwnd

 

Creates a new Graphics object from the specified handle to a

 

 

window

 

 

 

FromImage

 

Creates a new Graphics object from the specified Image

 

 

object

 

 

 

GetHalftonePalette

 

Gets a handle to the current Windows halftone palette

 

 

 

GetHdc

 

Gets the handle to the device context associated with this

 

 

Graphics object

 

 

 

GetNearestColor

 

Gets the nearest color to the specified Color structure

 

 

 

IntersectClip

 

Updates the clip region of this Graphics object to the

 

 

intersection of the current clip region and the specified

 

 

Rectangle structure

IsVisible

Indicates whether the point specified by a pair of coordinates is contained within the visible clip region of this Graphics object

MeasureCharacterRanges

MeasureString

MultiplyTransform

ReleaseHdc

ResetClip

ResetTransform

Restore

RotateTransform

Save

ScaleTransform

Gets an array of Region objects, each of which bounds a range of character positions within the specified string

Measures the specified string when drawn with the specified Font object

Multiplies the world transformation of this Graphics object and specified the Matrix object parameters

Releases a device context handle obtained by a previous call to the GetHdc method of this Graphics object

Resets the clip region of this Graphics object to an infinite region

Resets the world transformation matrix of this Graphics object to the identity matrix

Restores the state of this Graphics object to the state represented by a GraphicsState object

Applies the specified rotation to the transformation matrix of this Graphics object

Saves the current state of this Graphics object and identifies the saved state with a GraphicsState object

Applies the specified scaling operation to the transformation matrix of this Graphics object by prepending it to the object's transformation matrix

SetClip

 

Sets the clipping region of this Graphics object to the Clip

 

Table 26-2: Graphics Class Methods

 

 

 

 

Method

 

 

Description

 

 

 

 

 

 

 

property of the specified Graphics object

 

 

 

 

TransformPoints

 

 

Transforms an array of points from one coordinate space to

 

 

 

another using the current world and page transformations of

 

 

 

this Graphics object

 

 

 

 

TranslateClip

 

 

Translates the clipping region of this Graphics object by

 

 

 

specified amounts in the horizontal and vertical directions

 

 

 

 

TranslateTransform

 

 

Prepends the specified translation to the transformation

 

 

 

matrix of this Graphics object

 

 

 

 

As you can see, the Graphics class provides every possible method that you would ever want to use to work with any type of GUI element. Listing 26-1 uses several of the methods in the Graphics class to produce the output displayed in Figure 26-1.

Figure 26-1: Output from using members of the Graphics class

Note As there is no AutoRedraw property, you still need a way to redraw a form if it is resized. Using the SetStyles method and passing the ControlStyles. ResizeRedraw stylecorrectly calls the Paint method of a form. After the call the InitializeComponent; in your form, you should type SetStyle- (ControlStyles.ResizeRedraw, true) to guarantee that the Paint event will be called when your form is resized. Look up SetStyle in the

.NET Framework SDK to learn more about what you can do with the SetStyle method. Listing 26-1: Using Methods from the Graphics Class

private void drawLine()

{

/* create a Graphics object that can be resued * for each of the samples */

Graphics g;

g = this.CreateGraphics();

// Use the Pen object to create a line

Pen p;

p = new Pen(Color.Red, 50);

/* DrawLine is an overloaded method,

* pass the x1, y1, x2, y2 coordinates */

g.DrawLine(p, 100F, 100F, 500F, 100F);

// draw an icon from the file system

Icon i;

i = new Icon(@"C:\Desktop.ico");

Соседние файлы в папке c#