ARTICLE

The PrintDocument and Print Events in GDI+

Posted by Mahesh Chand Articles | GDI+ & Graphics May 03, 2010
In this article I will explain about the PrintDocument and Print Events in GDI+.
Reader Level:

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.jpg

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.gif

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.jpg

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.


bookGDI.jpg 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.

COMMENT USING