Although it's exciting to be able to draw graphics on a printout, keep in mind that printers have limits. Never try to print at the extreme edges of the page because you cannot be sure that a printer will print in exactly the same place. You could have two printers of the same model and manufacturer, and yet when you print you may notice they print in different places. Some printers are more accurate than others, but usually a sheet of paper will move slightly as it moves through the printer. Laser printers tend to be able to print closer to the edges of the paper than inkjet printers because of the mechanism that is used to transport the sheet of paper through the printer.
To see a marginal-printing sample, let's create a Windows application. We add two buttons to the form. The final form is shown in Figure 11.27.
Figure 11.27. Marginal-printing test application
Now we add code for the Normal Printing and Marginal Printing button click event handlers, as in Listing 11.47. Each handler creates a PrintDocument object, adds a PrintPage event handler, and calls the Print method. The PrintPage event handlers for Normal Printing and Marginal Printing are NormalPrinting and MarginPrinting, respectively.
Listing 11.47 The Normal Printing and Marginal Printing button event handlers
private void NormalBtn_Click(object sender, System.EventArgs e) { // Create a PrintDocument object PrintDocument pd = new PrintDocument(); // Add PrintPage event handler pd.PrintPage += new PrintPageEventHandler(NormalPrinting); // Print pd.Print(); } private void MarginalBtn_Click(object sender, System.EventArgs e) { // Create a PrintDocument object PrintDocument pd = new PrintDocument(); // Add PrintPage event handler pd.PrintPage += new PrintPageEventHandler(MarginPrinting); // Print pd.Print(); }
Now let's look at the NormalPrinting handler (see Listing 11.48). We start with the top location of the text as unit 1. Then we calculate the next line's position using the height of the font and draw four lines with the values of the top, left, bottom, and right margins. In the end we draw a rectangle with the default bounds of the page.
Listing 11.48 The NormalPrinting event handler
public void NormalPrinting(object sender, PrintPageEventArgs ev) { // Set the top position as 1 float ypos = 1; // Get the default left margin float leftMargin = ev.MarginBounds.Left; // Create a font Font font = new Font("Arial",16); // Get the font's height float fontheight = font.GetHeight(ev.Graphics); // Draw four strings ev.Graphics.DrawString("Top Margin = " + ev.MarginBounds.Top.ToString(), font, Brushes.Black, leftMargin, ypos); ypos = ypos + fontheight; ev.Graphics.DrawString("Bottom Margin = " + ev.MarginBounds.Bottom.ToString(), font, Brushes.Black, leftMargin, ypos); ypos = ypos + fontheight; ev.Graphics.DrawString ("Left Margin = " + ev.MarginBounds.Left.ToString(), font, Brushes.Black, leftMargin, ypos); ypos = ypos + fontheight; ev.Graphics.DrawString ("Right Margin = " + ev.MarginBounds.Right.ToString(), font, Brushes.Black, leftMargin, ypos); ypos = ypos + fontheight; // Draw a rectangle with default margins ev.Graphics.DrawRectangle( new Pen(Color.Black), ev.MarginBounds.X, ev.MarginBounds.Y, ev.MarginBounds.Width, ev.MarginBounds.Height); }
If we run the application, we will see text describing the four margin values printed outside the rectangle.
Next comes code for the MarginPrinting event handler (see Listing 11.49). We use the default margin of the page as the top location for the first text. Everything else is the same as in Listing 11.48.
Listing 11.49 The MarginPrinting event handler
public void MarginPrinting(object sender, PrintPageEventArgs ev) { // Set the top position as the default margin float ypos = ev.MarginBounds.Top; // Get the default left margin float leftMargin = ev.MarginBounds.Left; // Create a font Font font = new Font("Arial",16); // Get the font's height float fontheight = font.GetHeight(ev.Graphics); // Draw four strings ev.Graphics.DrawString("Top Margin = " + ev.MarginBounds.Top.ToString(), font, Brushes.Black, leftMargin, ypos); ypos = ypos + fontheight; ev.Graphics.DrawString("Bottom Margin = " + ev.MarginBounds.Bottom.ToString(), font, Brushes.Black, leftMargin, ypos); ypos = ypos + fontheight; ev.Graphics.DrawString ("Left Margin = " + ev.MarginBounds.Left.ToString(), font, Brushes.Black, leftMargin, ypos); ypos = ypos + fontheight; ev.Graphics.DrawString ("Right Margin = " + ev.MarginBounds.Right.ToString(), font,Brushes.Black, leftMargin, ypos); ypos = ypos + fontheight; // Draw a rectangle with default margins ev.Graphics.DrawRectangle( new Pen(Color.Black), ev.MarginBounds.X, ev.MarginBounds.Y, ev.MarginBounds.Width, ev.MarginBounds.Height); }
When we run this code, we will see text appearing inside the rectangle printed using the page margin values.
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