| What we have in this page?
The following exercise shows you how to use the printing functionality within GDI+. You’ll use the existing application you’ve been developing in this module and add a menu item that will let you print the contents of the form.
29. Add a using directive for the System::Drawing::Printing namespace to the other using directives at the top of the code.
using namespace System::Drawing::Printing;
30. Add a menu to the form by dragging a MenuStrip from the Toolbox onto the form. Create a File menu, and add two menu items: one Named printItem with the Text &Print, and a second Named exitItem with the Text E&xit. Add a separator bar between the printItem and exitItem. |

31. Setting up menus like this should be familiar to you by now. If you need to refresh your knowledge of how menus work, see previous modules on Windows Forms and Controls. Use the Properties editor to set up event handlers for the Print and Exit menu items or double click the Print and Exit menu items or go to the Events page and double click on the empty field of the Click event. Add the code for the printItem_Click and exitItem_click handler functions.
private: System::Void printItem_Click(System::Object^ sender, System::EventArgs^ e)
{
// The PrintDocument holds the settings
PrintDocument^ pdoc = gcnew PrintDocument();
// Create a dialog and attach it to the document
PrintDialog^ pd = gcnew PrintDialog();
pd->Document = pdoc;
// Show the dialog
if (pd->ShowDialog() == ::CppDraw::DialogResult::OK)
{
// Add the page handler, PrintAPAge is a call back function
pdoc->PrintPage += gcnew PrintPageEventHandler(this, &Form1::PrintAPage);
// Print the page
pdoc->Print();
}
else
MessageBox::Show("Print cancelled", "Information");
}
private: System::Void exitItem_Click(System::Object^ sender, System::EventArgs^ e)
{
// Just exit the application
Application::Exit();
}

The handler code determines which menu item raised the event. If it was the Exit item, the application exits. If it was the Print item, a PrintDialog gets displayed; PrintDialog is one of the common dialog boxes, and it will display the familiar printer selection dialog box shown in the following figure.

The purpose of this dialog box is to gather the information needed for the printing process; this information is stored in a PrintDocument object for later use. So, before you display the PrintDialog, you need to create a PrintDocument object and assign it to the dialog box’s Document property. You can then show the PrintDialog, and when the user dismisses the dialog box, check the return value to see whether you should continue printing.
32. The PrintDocument controls the printing process, so you call its Print function to start printing. You also need to provide a callback function that PrintDocument will call once for each page that needs to be printed. You add the callback in the normal way, by adding an event handler to the PrintDocument. The following is the code for the callback function. Add this event handler function after the Form1 constructor.
void PrintAPage(Object^ pSender, PrintPageEventArgs^ pe)
{
Graphics^ gr = pe->Graphics;
Pen^ pen1 = gcnew Pen(Color::Black);
// Draw the image
Bitmap^ bmp = gcnew Bitmap(L"ramp1.gif");
gr->DrawImage(bmp, 10,10);
for(int i=0; i<list->Count; i++)
{
Line^ pl = dynamic_cast<Line^>(list->default[i]);
gr->DrawLine(pen1, pl->p1.X,pl->p1.Y, pl->p2.X,pl->p2.Y);
}
}

Notice that the code is exactly the same as that in the Paint event handler. In this case, we are taking a very simple-minded approach to printing and simply dumping the content of the form straight to the printer. In real life, you’d probably want to add headers and footers and perhaps format the output differently.
What if your output fits on more than one page? The page handler function is going to be called once for each page, and it’s up to you to keep track of where you are and what needs to be printed. As long as there are more pages to print, set the HasMorePages property of the PrintPageEventArgs object to true before returning from the handler function, and it will get called again. If you have noticed, most of the printing controls already available in the Toolbox which includes PageSetupDialog, PrintDialog, PrintDocument, PrintPreviewControl and PrintPreviewDialog. This should make our printing task programming easier.

33. Build and run the application. Draw some lines and text on the screen, and verify that you can send the output to your printer. You’ll find that the lines appear on the printed output but the text doesn’t. The data for the lines was saved so that it could be redrawn in PrintAPage; the text data wasn’t saved, so it won’t be redrawn.


34. When you click the Cancel button the Print Cancelled message box will be displayed as shown below.
![]() |
35. Some more Graphics member code snippets. Create a new CLR Windows Forms Application named PlayDraw.

36. Set the form Text to Graphics Member and the Size to 520, 385. Insert Paint event handler function and try the following codes.
private: System::Void Form1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e)
{
// The following code snippet examples that
// demonstrate some of the members exposed by the Graphics type
///////////////////////////DrawLines//////////////////////////
// Create pens.
Pen^ redPen = gcnew Pen(Color::Red, 3.0f);
Pen^ greenPen = gcnew Pen(Color::Green, 3.0f);
// Create points that define curve.
Point point1 = Point(50, 50);
Point point2 = Point(100, 25);
Point point3 = Point(200, 5);
Point point4 = Point(250, 50);
Point point5 = Point(300, 100);
Point point6 = Point(350, 200);
Point point7 = Point(250, 250);
array<Point>^ curvePoints = {point1, point2, point3, point4, point5, point6, point7};
// Draw lines between original points to screen.
e->Graphics->DrawLines(redPen, curvePoints);
// Draw curve to screen.
e->Graphics->DrawCurve(greenPen, curvePoints);
//////////////////////DrawArc////////////////////////////////
// Create pen.
Pen^ blackPen = gcnew Pen(Color::Black,3.0f);
// Create rectangle to bound ellipse.
Rectangle rect = Rectangle(0, 0, 100, 200);
// Create start and sweep angles on ellipse.
float startAngle = 45.0F;
float sweepAngle = 270.0F;
// Draw arc to screen.
e->Graphics->DrawArc(blackPen, rect, startAngle, sweepAngle);
////////////////////DrawBezier//////////////////////////////
// Create pen.
Pen^ yellowPen1 = gcnew Pen(Color::Yellow,3.0f);
// Create points for curve.
Point start = Point(100,100);
Point control1 = Point(200,10);
Point control2 = Point(350,50);
Point end = Point(500,100);
// Draw arc to screen.
e->Graphics->DrawBezier( yellowPen1, start, control1, control2, end );
/////////////////DrawEllipse//////////////////
// Create pen.
Pen^ bluePen = gcnew Pen(Color::Blue,2.0f);
// Create rectangle for ellipse.
Rectangle rect1 = Rectangle(150, 200, 200, 100);
// Draw ellipse to screen.
e->Graphics->DrawEllipse(bluePen, rect1);
///////////////////DrawIcon///////////////////
// Create icon.
System::Drawing::Icon^ newIcon = gcnew System::Drawing::Icon("msdn.ico");
// Create rectangle for icon.
Rectangle rect2 = Rectangle(350, 200, 70, 70);
// Draw icon to screen.
e->Graphics->DrawIcon(newIcon, rect2);
//////////////////DrawIconUnstretched///////////////////
// Create icon.
System::Drawing::Icon^ newIcon1 = gcnew System::Drawing::Icon("msdn.ico");
// Create rectangle for icon.
Rectangle rect3 = Rectangle(400, 300, 200, 200);
// Draw icon to screen.
e->Graphics->DrawIconUnstretched(newIcon1, rect3);
///////////////FillPie//////////////////
// Create solid brush.
SolidBrush^ redBrush = gcnew SolidBrush(Color::Red);
// Create rectangle for ellipse.
Rectangle rect4 = Rectangle(50, 50, 200, 100);
// Create start and sweep angles.
float startAngle1 = 0.0F;
float sweepAngle1 = 45.0F;
// Fill pie to screen.
e->Graphics->FillPie(redBrush, rect4, startAngle1, sweepAngle1);
///////////////////DrawPolygon/////////////////////
// Create pen.
Pen^ whitePen = gcnew Pen(Color::White,3.0f);
// Create points that define polygon.
Point point11 = Point(50,50);
Point point21 = Point(75,150);
Point point31 = Point(150,50);
Point point41 = Point(170,70);
Point point51 = Point(200,100);
Point point61 = Point(300,150);
Point point71 = Point(200,200);
array<Point>^ curvePoints1 = {point11, point21, point31, point41, point51, point61, point71};
// Draw polygon to screen.
e->Graphics->DrawPolygon(whitePen, curvePoints1);
}
37. Build and run your application. The following output should be expected.

A Very Quick Reference
| To | Do this |
| Draw on a form. | Create a Graphics object using the form’s CreateGraphics function. For example:
Remember to call Dispose/delete on the Graphics object when you’ve finished with it.
|
| Draw lines and the outlines of shapes. | Create Pen objects, and use them in calls to Graphics class drawing functions. Use the Pens and SystemPens classes to obtain Pens with standard colors. |
| Fill shapes. | Create Brush objects, and use them in calls to Graphics class drawing functions. Use the Brushes and SystemBrushes classes to obtain brushes with standard colors. |
| Use colors. | Create Color objects, and use them when constructing Pen and Brush objects. |
| Display images. | Create a Bitmap object, passing it the name of an image file. Then use the DrawImage function of the Graphics class to render the image. |
| Print from an application. | Create a PrintDialog. Create a PrintDocument and assign it to the Document property of PrintDialog. Show the dialog box, and check whether it returns DialogResult::OK. Create a callback function, attach it to the PrintPage event of PrintDocument, and then call the Print function of PrintDocument to print the page. |
|
Table 11 | |