Here's an abbreviated guide.
First, add references to System.Drawing and System.Windows.Forms (the latter is for the printer selection dialog box).
Second, add the following usings:
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
Third, subclass the PrintDocument class and override OnPrintPage:
class PrintSomething : PrintDocument
{
protected override void OnPrintPage(PrintPageEventArgs e)
{
...
}
}
The available paper space is defined by DefaultPageSettings.PrintableArea which is a rectangle with the coordinate system at (Left, Top) and extending down to (Right, Bottom). The units are in 1/100th of an inch, and the drawing coordinates are also in the same units. So for example, to draw a one inch circle in the middle of the page...
float middleX = (DefaultPageSettings.PrintableArea.Right +
DefaultPageSettings.PrintableArea.Left) / 2.0F;
int middleY = (DefaultPageSettings.PrintableArea.Bottom +
DefaultPageSettings.PrintableArea.Top) / 2.0F;
Pen p = new Pen(Color.Black, 4);
e.Graphics.DrawEllipse(p, middleX - 50.0F, middleY + 50.0F, 100.0F, 100.0F);
Finally, the following code displays the printer selecting dialog and renders the picture if user clicks OK.
static void Main(string[] args)
{
PrintSomething lines = new PrintSomething();
PrintDialog dlg = new PrintDialog();
dlg.Document = lines;
if (dlg.ShowDialog() == DialogResult.OK)
lines.Print();
}
So here is the final program:
//-----------------------------------------------------------------------
// <copyright file="Program.cs" company="Sergey Solyanik">
// Copyright (C) Sergey Solyanik.
//
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
/// <summary>
/// This code prints a target that can be used for scope alignment.
/// </summary>
class PrintTarget : PrintDocument
{
/// <summary>
/// Prints out a target.
/// </summary>
/// <param name="args"> Arguments array. Not used. </param>
static void Main(string[] args)
{
PrintTarget lines = new PrintTarget();
PrintDialog dlg = new PrintDialog();
dlg.Document = lines;
if (dlg.ShowDialog() == DialogResult.OK)
lines.Print();
}
/// <summary>
/// Renders the page.
/// </summary>
/// <param name="e"> Printer parameters and graphics. </param>
protected override void OnPrintPage(PrintPageEventArgs e)
{
Graphics g = e.Graphics;
Pen p1 = new Pen(Color.Black, 0.5F);
Pen p2 = new Pen(Color.Black, 1);
Pen p4 = new Pen(Color.Black, 4);
float step = 100.0F / 16.0F;
int middleX = (int)((DefaultPageSettings.PrintableArea.Right -
DefaultPageSettings.PrintableArea.Left) / step) / 2;
int boundX = ((int)((DefaultPageSettings.PrintableArea.Right -
DefaultPageSettings.PrintableArea.Left) / 200.0F)) * 16;
int middleY = (int)((DefaultPageSettings.PrintableArea.Bottom -
DefaultPageSettings.PrintableArea.Top) / step) / 2;
int boundY = ((int)((DefaultPageSettings.PrintableArea.Bottom -
DefaultPageSettings.PrintableArea.Top) / 200.0F)) * 16;
float top = DefaultPageSettings.PrintableArea.Top +
(middleY - boundY) * step;
float bottom = DefaultPageSettings.PrintableArea.Top +
(middleY + boundY) * step;
float left = DefaultPageSettings.PrintableArea.Left +
(middleX - boundX) * step;
float right = DefaultPageSettings.PrintableArea.Left +
(middleX + boundX) * step;
for (int i = 0; i < boundX; ++i)
{
Pen p;
if (i % 16 == 0)
p = p4;
else if (i % 8 == 0)
p = p2;
else
p = p1;
g.DrawLine(p,
DefaultPageSettings.PrintableArea.Left +
(middleX + i) * step,
top,
DefaultPageSettings.PrintableArea.Left +
(middleX + i) * step,
bottom);
g.DrawLine(p,
DefaultPageSettings.PrintableArea.Left +
(middleX - i) * step,
top,
DefaultPageSettings.PrintableArea.Left +
(middleX - i) * step,
bottom);
}
for (int i = 0; i < boundY; ++i)
{
Pen p;
if (i % 16 == 0)
p = p4;
else if (i % 8 == 0)
p = p2;
else
p = p1;
g.DrawLine(p,
left,
DefaultPageSettings.PrintableArea.Top +
(middleY + i) * step,
right,
DefaultPageSettings.PrintableArea.Top +
(middleY + i) * step);
g.DrawLine(p,
left,
DefaultPageSettings.PrintableArea.Top +
(middleY - i) * step,
right,
DefaultPageSettings.PrintableArea.Top +
(middleY - i) * step);
}
for (int i = 1; i < 4; ++i)
{
g.DrawEllipse(p4,
DefaultPageSettings.PrintableArea.Left +
(middleX - 8 * i) * step,
DefaultPageSettings.PrintableArea.Top +
(middleY - 8 * i) * step,
16 * i * step, 16 * i * step);
}
}
}
And here's what it prints:
Hint: Microsoft XPS document writer is a great way to debug printer output without wasting paper.