This article has been excerpted from book "Graphics Programming with GDI+".
So far we have seen how to print simple text and how to read and set printer settings. In the previous sections we saw that in a printing application, we create a PrintDocument object, set its printer name, set the printer page event handler, and then call the Print method. PrintDocument offers more than this. In this section we will cover PrintDocument members and print events.
The PrintDocument class is used to tell the printing system how printing will take place. Table 11.4 describes the properties of the PrintDocument class.
Besides the properties described in Table 11.4, PrintDocument also provides printing-related methods that invoke print events. These methods are described in Table 11.5.
FIGURE 11.9: Reading printer properties
TABLE 11.4: PrintDocument properties
Property |
Description |
DefaultPageSettings |
Represents the page settings using a PageSettings object. |
DocumentName |
Returns the name of the document to be displayed in a print status dialog box or printer queue while printing the document. |
PrintController |
Returns the print controller that guides the printing process. |
PrinterSettings |
Returns the printer settings represented by a PrinterSettings object. |
TABLE 11.5: PrintDocument methods
Method |
Description |
OnBeginPrint |
Raise the BeginPrint event, which is called after the Print method and before the first page of the document is printed. |
OnEndPrint |
Raises the EndPrint event, which is called when the last page of the document has been printed. |
OnPrintPage |
Raises the PrintPage event, which is called before a page prints. |
OnQueryPageSettings |
Raises the QueryPageSettings event, which is called immediately before each PrintPage event. |
Print |
Starts the document's printing process. |
All of these methods allow derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class. We will discuss these methods and their events, and how to handle them, in our examples.
Understanding Print Events
During the printing process, the printing system fires events according to the stage of a printing process. The three common events are BeginPrint, PrintPage, and EndPrint. As their names indicate, the BeginPrint event occurs when the Print method is called, and the EndPrint event occurs when the last page of the document has been printed. The PrintPage event occurs for each page being printed (as in Figure 11.10) when the Print method is called and after the BeginPrint event has occurred.
Figure 11.10 shows a flowchart for the print events during a printing process. The BeginPrint event is raised after the Print method is called. Then the printing process checks if there are any pages. If there are, the PrintPage event occurs, which is responsible for the actual printing, and the control goes back to check if there are more pages to print. When all pages are done printing, the EndPage event is fired.
FIGURE 11.10: Print events
The PrintEventArgs class provides data for BeginPrint and EndPrint events. This class is inherited from CancelEventArgs, which implements a single property called Cancel, that indicates if an event should be canceled (in the current .NET Framework release, PrintEventArgs is reserved for future use).
The BeginPrint event occurs when the Print method is called and before the first page prints. BeginPrint takes a PrintEventArgs object as an argument. This event is the best place to initialize resources. The PrintEventHandler method, which is used to handle the event code, is called whenever the BeginPrint event occurs.
The PrintPage event occurs when the Print method is called and before a page prints. When we create a PrintPageEventHandler delegate, we identify a method that handles the PrintPage event. The event handler is called whenever the PrintPage event occurs.
The code snipped that follows creates a PrintPageEventHandler delegate, where pd_PrintPage is an event handler:
PrintDocument pd = new PrintDcoument();
pd.PrintPage += new PrintPageEventHandler )pd_PrintPage);
PrintPageEventHandler takes a PrintPageEventArgs object as its second argument, which has the six properties described in Table 11.6.
The following code snippet shows how to get the Graphics object from PrintPageEventArgs:
public void pd_PrintPage(object sender, PrintPageEventArgs ev)
{
//Get the Graphics object attached to PrintPageEventArgs
Graphics g = ev.Graphics;
}
The EndPrint event occurs when the last page of the document has been printed. It takes a PrintEventArgs object as an argument. This is the best place to free your resources. The PrintEventHandler method is called whenever the EndPrint event occurs and is used to handle the event code.
Now let's write an application that shows how to use these events. We create a Windows application and add a combo box and a button to the form. We set ComboBox.Name to printersList and the text to the button to PrintEvent Start. The final form looks like Figure 11.11.
TABLE 11.6: PrintPageEventArgs properties
Property |
Description |
Cancel |
Indicates whether the print jobs should be canceled. Both get and set. |
Graphics |
Returns the Graphics object. |
HasMorePages |
Indicates whether an additional page should be printed. Used in multipage document before the Print methods is called. Both get and set. |
MarginBounds |
Returns the portion of the page inside the margins. |
PageBounds |
Returns the total area of the page |
PageSettings |
Returns page setting for the current page. |
FIGURE 11.11: The print events application
Next we add a reference to the System.Drawing.Printing namespace as follows:
using System.Drawing.Printing;
Then we add code on the form's load event handler that adds all installed printers to the combo box (see Listing 11.18).
LISTING 11.18: Loading all installed printers
private void Form1_Load(object sender, System.EventArgs e)
{
//See if any printers are installed
if (PrinterSettings.InstalledPrinters.Count <= 0)
{
MessageBox.Show("Printer not found!");
return;
}
//Get all available printers and add them to the combo box
foreach (String printer in
PrinterSettings.InstalledPrinters)
{
printerList.Items.Add(printer.ToString());
}
}
Now we write code for the button click event handler. Listing 11.19 create all three print event handlers, attaches them to a PrintDocument object, and calls PrintDocument's print methods.
LISTING 11.19: Attaching BeginPrint, EndPrint, and PagePrinteventhandlers
private void PrintEvents_Click(object sender, System.EventArgs e)
{
//Get the selected printer
string printerName =
printersList.SelectedItem.ToString();
//Create a PrintDocument object and set the current printer
PrintDocument pd = new PrintDocument();
pd.PrinterSettings.PrinterName = printerName;
//BeginPrint event
pd.BeginPrint +=
new PrintEventHandler(BgnPrntEventHandler);
//PrintPage event
pd.PrintPAge +=
new PrintPageEventHandler(PrntPgEventHanlder);
//EndPrint event
pf.EndPrint +=
new PrintEventHandler(EndPrntEventHandler);
//Print the document
pd.Print();
}
As state earlier, the BeginPrint event handler can be used to initialize resources before printing starts, and the EndPrint event handler can be used to free allocated resources. Listing 11.20 shows all three print event handlers. The PrintPage event handler uses the properties for PrintPageEventArgs can calls DrawRectangle and FillRectangle to print the rectangles. This example simply shows how to call these events. You can use the PrintPage event handler to draw anything you want to print, as we have seen in previous examples.
LISTING 11.20: The BeginPrint, EndPrint, and PagePrint event handlers
public void BgnPrntEventHandler(object sender, PrintEventArgs peaArgs)
{
//Create a brush and apen
redBrush = new SolidBrush(Color.Red);
bluePen = new Pen(Color.Blue, 3);
}
public void EndPrntEventHandler(object sender, PrintEventArgs peaArgs)
{
//Release brush and pen objects
redBrush.Dispose();
bluePen.Dispose();
}
public void PrntPgEventHandler(object snder, PrintPageEventArgs ppeArgs)
{
//Create PrinterSettings object
PrinterSettings ps = new PrinterSettings();
//Get Graphics object
Graphics g = ppeArgs.Graphics;
//Create PageSettings object
PageSettings pgSetting = new PageSetting(ps);
//Set page margins
ppeArgs.PageSettings.Margins.Left = 50;
ppeArgs.PageSettings.Margins.Right = 100;
ppeArgs.PageSettings.Margins.Top = 50;
ppeArgs.PageSettings.Margins.Bottom = 100;
//Create two rectangles
Rectangle rect1 = new Rectangle(20, 20, 50, 50);
Rectangle rect2 = new Rectangle(100, 100, 50, 100);
//Draw and fill rectangles
g.DrawRectangle(bluePen, rect1);
g.FillRectangle(redBrush, rect2);
}
As this discussion has shown, the print event can be handy when you need to initialize or free resources.
Conclusion
Hope the article would have helped you in understanding the PrintDocument and Print Events in GDI+. Read other articles on GDI+ on the website.
|
This book teaches .NET developers how to work with GDI+ as they develop applications that include graphics, or that interact with monitors or printers. It begins by explaining the difference between GDI and GDI+, and covering the basic concepts of graphics programming in Windows. |