Printer Settings


So far, all the printing in this chapter has been done to the default printer, as defined by Windows itself. The user can change the printer for a document via the Printer button on the PageSetupDialog. It's more common, however, to allow the user to choose the printer after choosing the Print item from the File menu. For this you use the PrintDialog component, as shown in Figure 7.9.

Figure 7.9. The PrintDialog Component

Using the PrintDialog component looks like this:

 
 Dim printDialog1 As PrintDialog Sub InitializeComponent()   ...   Me.printDialog1 = New PrintDialog()   ...   ' Can set the PrintDialog's Document property   ' in the Property Browser   Me.printDialog1.Document = Me.printDocument1   ... End Sub Sub printButton_Click(sender As Object, e As EventArgs)   ' Let the user choose the printer   If printDialog1.ShowDialog() = DialogResult.OK Then       printDocument1.Print()   End If End Sub 

Like PageSetupDialog, the PrintDialog component allows you to set a number of options before it is shown:

 
 NotInheritable Class PrintDialog   Inherits CommonDialog   Implements IComponent   Implements IDisposable   ' Constructors   Public Sub New()   ' Properties   Property AllowPrintToFile() As Boolean   Property AllowSelection() As Boolean   Property AllowSomePages() As Boolean   Property Document() As PrintDocument   Property PrinterSettings() As PrinterSettings   Property PrintToFile() As Boolean   Property ShowHelp() As Boolean   Property ShowNetwork() As Boolean   ' Events   Event HelpRequest As EventHandler   ' Methods   MustOverride Sub Reset() End Class 

You must set the Document property before showing a PrintDialog object. The other PrintDialog properties are similar in function to the PageSetupDialog properties. A couple of properties are special, however, because they determine what to print. Let's take a look.

Print Range

The AllowSelection property of the PrintDialog lets the user print only the current selection, [2] and AllowSomePages allows the user to decide on a subset of pages to be printed. Both settings require you to print specially, based on the PrintRange property of the PrinterSettings class, which is of type PrintRange:

[2] What, if anything, the "current selection" means is application-specific. However, Betsy Hardinger, the copy editor for this book, made an impassioned plea during her editing of this book that when the print dialog is invoked while there is a current selection, the print dialog default to printing only the selection and not all 75 pages of the document (which Betsy often finds herself printing when she doesn't want to). Thank you.

 
 Enum PrintRange   AllPages ' Print all pages (default)   Selection ' Print only the current selection   SomePages ' Print pages from FromPage to ToPage End Enum 

Before you can set a print range that's different from AllPages, you must set AllowSelection or AllowSomePages (or both) to true (they both default to false). AllowSomePages also requires that the PrinterSettings FromPage and ToPage be set greater than the default of zero:

 
 Dim totalPages As Integer = 13 Dim page As Integer Dim maxPage As Integer Sub printButton_Click(sender As Object, e As EventArgs)   printDocument1.PrinterSettings.FromPage = 1   printDocument1.PrinterSettings.ToPage = totalPages   printDocument1.PrinterSettings.MinimumPage = 1   printDocument1.PrinterSettings.MaximumPage = totalPages   printDialog1.AllowSomePages = True   If printDialog1.ShowDialog() == DialogResult.OK Then     printDocument1.Print()   End If End Sub 

Although it's not required, it's a good idea when setting AllowSomePages to true to also set MinimumPage and MaximumPage so that users can't accidentally ask for a page out of the allowed range. If AllowSelection or AllowSomePages is set to true, the PrintPage event will have to check the PrintRange and FromPage/ToPage properties to see what to print:

 
 Dim totalPages As Integer = 13 Dim page As Integer Dim maxPage As Integer Sub printButton_Click(sender As Object, e As EventArgs)   ...   If printDialog1.ShowDialog() = DialogResult.OK Then       If printDialog1.PrinterSettings.PrintRange = _               PrintRange.SomePages Then           ' Set first page to print to FromPage           page = printDocument1.PrinterSettings.FromPage           ' Set last page to print to ToPage           maxPage = printDocument1.PrinterSettings.ToPage       Else           ' Print all pages           page = 1           maxPage = totalPages       End If       ' Print from first page to last page       printDocument1.Print()   End If End Sub Sub printDocument1_PrintPage(sender As Object, e As PrintPageEventArgs)   Dim g As Graphics = e.Graphics   ' print current page...   ' Check whether there are more pages to print   page += 1   e.HasMorePages = (page <= maxPage) End Sub 

In addition to the PrintRange, FromPage, and ToPage properties, the PrinterSettings class has many more settings for use in determining exactly how the user would like to print:

 
 Class PrinterSettings   Implements ICloneable   ' Constructors   Public Sub New()   ' Properties   Property CanDuplex() As Boolean   Property Collate() As Boolean   Property Copies() As Short   Property DefaultPageSettings() As PageSettings   Property Duplex() As Duplex   Property FromPage() As Integer   Shared Property InstalledPrinters() As StringCollection   Property IsDefaultPrinter() As Boolean   Property IsPlotter() As Boolean   Property IsValid() As Boolean   Property LandscapeAngle() As Integer   Property MaximumCopies() As Integer   Property MaximumPage() As Integer   Property MinimumPage() As Integer   Property PaperSizes() As PaperSizeCollection   Property PaperSources() As PaperSourceCollection   Property PrinterName() As String   Property PrinterResolutions() As PrinterResolutionCollection   Property PrintRange() As PrintRange   Property PrintToFile() As Boolean   Property SupportsColor() As Boolean   Property ToPage() As Integer   ' Methods   Function CreateMeasurementGraphics() As Graphics End Class 

One thing of particular interest is the CreateMeasurementGraphics method, which returns a Graphics object based on the printer and its settings. You can use this Graphics object for making measurement calculations and for enumerating the font families (using the FontFamily.GetFamilies method), all without having to actually start a print operation.

Targeting the Printer

I'd like to remind you again that because the drawing happens on a Graphics object, all the drawing techniques from Chapters 4, 5, and 6 work just as well with printers as they do with screens. However, unlike the screen, where page units default to Pixel, the page units for the printer default to Display. Furthermore, whereas Display means Pixel on the screen, for the printer, Display maps the printer resolution to a logical 100 dpi. Because printers often have different resolutions both vertically and horizontally and are almost never 100 dpi anyway, this may seem unintuitive. However, because the default system font setting is 96 dpi on the screen, mapping the printer to a logical 100 dpi means that the default mappings for both screen and printer yield a quick and dirty near-WYSIWYG, without your having to change a thing. If you want something even closer, you're free to use page units such as inches or millimeters, as discussed in Chapter 6: Advanced Drawing.

If you do change the units, remember to convert PageBounds and MarginBounds to the new units as well. You can use the Graphics method TransformPoints:

 
 Shared Function TranslateBounds(g As Graphics, _   bounds As Rectangle) As RectangleF   ' Translate from units of 1/100th of an inch to page units   Dim dpiX As Single = g.DpiX   Dim dpiY As Single = g.DpiY   Dim pts(1) As PointF   pts(0) = _       New PointF(bounds.X * dpiX / 100.0F, _         bounds.Y * dpiY / 100.0F)   Pts(1) = _       New PointF(bounds.Width * dpiX / 100.0F, _         bounds.Height * dpiX / 100.0F)   g.TransformPoints( _       CoordinateSpace.Page, CoordinateSpace.Device, pts)   Return New RectangleF(pts(0).X, pts(0).Y, pts(1).X, pts(1).Y) End Function 

The TranslateBounds helper method uses the current Graphics object to translate a PageBounds or MarginBounds rectangle from units of 100 dpi to whatever the page unit is set to. This helper is meant to be used from the PrintPage handler:

 
 Sub printDocument1_PrintPage(sender As Object, e As PrintPageEventArgs)   Dim g As Graphics = e.Graphics   g.PageUnit = GraphicsUnit.Inch   Dim thinPen As Pen = New Pen(Color.Black, 0)   Dim pageBounds As RectangleF = GetRealPageBounds(e, preview)   pageBounds = TranslateBounds(g, Rectangle.Truncate(pageBounds))   g.DrawRectangle(_       thinPen,       pageBounds.X,       pageBounds.Y,       pageBounds.Width,       pageBounds.Height)   ... End Sub 

Notice that PageUnit is set on the Graphics object right away so that any drawing that takes place in the PrintPage handler will be in those units. Notice also the creation of a new Pen object with a thickness of zero. By default, all the pens exposed from the Pens class have a width of 1, which will be one unit thick, or, in this example, one inch thick. A pen of width zero, on the other hand, will always be one device unit thick, something that is more useful for framing a rectangle.

Finally, notice that the PrintPage handler sets the PageUnit during each page being printed. Each time the PrintPage handler is called, it gets a fresh Graphics object, so don't forget to reset its options every time.



Windows Forms Programming in Visual Basic .NET
Windows Forms Programming in Visual Basic .NET
ISBN: 0321125193
EAN: 2147483647
Year: 2003
Pages: 139

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net