Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WinForms

WordWrap with PrintDocument

0.00/5 (No votes)
25 Jul 2007CPOL 1  
Code to ensure word wrapping in a PrintDocument object.

Introduction

Here is a simple way to ensure your text wraps when you display a PrintDialog or a PrintPreviewDialog.

Using the code

The code is simple...here is the code for the PrintDialog:

VB
private printFont As Font = New Font("Tahoma", 12, FontStyle.Regular)
private aBunchOfLongLines As String

Private Sub New()
    
  aBunchOfLongLines = "This software is provided 'as-is', with no warrenties " & _
    "of any kind stating operability of a specific " & vbNewLine
  aBunchOfLongLines &= "or error free operation.  Use of " & _
    "the application is entirely the user's responsibility. " & vbNewLine
  aBunchOfLongLines &= "The software vendor assumes no responsibility " & _
    "for use of this application.  This includes damage " & vbNewLine
  aBunchOfLongLines &= "which may occur during operation of the " & _
    "application to the users files or computer system. " & vbNewLine
  aBunchOfLongLines &= "By use of this application, you agree that you " & _
    "will take full responsibility for any damage that may " & vbNewLine
  aBunchOfLongLines &= "occur.  If you do not wish to use this " & _
    "application any further, please uninstall it from your computer."

End Sub

Private Sub tsbPrint_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles tsbPrint.Click
    Dim pd As New Printing.PrintDocument()
    Me.PrintDialog1.AllowPrintToFile = False
    Me.PrintDialog1.AllowSelection = False
    Me.PrintDialog1.AllowSomePages = False
    Me.PrintDialog1.UseEXDialog = True
    Me.PrintDialog1.Document = pd
    If Me.PrintDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
        Try
        'convert string to stream so we can read the lines
            Dim aBytes() As Byte = System.Text.Encoding.ASCII.GetBytes( _
                                   aBunchOfLongLines)
            Dim strmMem As New MemoryStream(aBytes)
            streamToPrint = New IO.StreamReader(strmMem)
            pd.PrinterSettings = Me.PrintDialog1.PrinterSettings
            AddHandler pd.PrintPage, AddressOf pd_PrintPage
        'print the document
            pd.Print()
        Catch ex As Exception

        Finally
            streamToPrint.Close()
        End Try
    End If
End Sub

Here is the code for the PrintPreviewDialog:

VB
Private Sub tsbPreview_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles tsbPreview.Click
    Dim aBytes() As Byte = System.Text.Encoding.ASCII.GetBytes( _
                           aBunchOfLongLines)
    Dim strmMem As New MemoryStream(aBytes)
    streamToPrint = New IO.StreamReader(strmMem)
    Dim pd As New Printing.PrintDocument()
    AddHandler pd.PrintPage, AddressOf pd_PrintPage
    Me.PrintPreviewDialog1.AllowTransparency = False
    'used to resize the dialog
    Dim dlg As Form = DirectCast(Me.PrintPreviewDialog1, Form)
    dlg.Width = 600
    dlg.Height = 400
    dlg.WindowState = FormWindowState.Maximized
    Me.PrintPreviewDialog1.Document = pd
    Me.PrintPreviewDialog1.ShowDialog()
    streamToPrint.Close()
End Sub

Here is the actual output to the PrintDocument. Notice the StringFormat object. This is what causes the wrapping, and also can be used to measure the text area for the line.

VB
Private Sub pd_PrintPage(ByVal sender As Object, _
            ByVal ev As Printing.PrintPageEventArgs)
    Dim yPos As Single = 0
    Dim leftMargin As Single = ev.MarginBounds.Left
    Dim topMargin As Single = ev.MarginBounds.Top
    Dim line As String = Nothing
    Dim actual As SizeF = Nothing
    yPos = topMargin
    While yPos < ev.MarginBounds.Top + ev.MarginBounds.Size.Height
        line = streamToPrint.ReadLine()
        'stringformat is what makes wrapping happen
        Dim sf As StringFormat = StringFormat.GenericTypographic
        sf.Alignment = StringAlignment.Near
        sf.LineAlignment = StringAlignment.Near
        sf.FormatFlags = StringFormatFlags.LineLimit
        sf.Trimming = StringTrimming.Word
        If line Is Nothing Then
            Exit While
        ElseIf line.Equals("") Then
            'have to have something to easure, even if it is a blank line
            line = " "
        End If
        actual = ev.Graphics.MeasureString(line, printFont, _
                 New SizeF(ev.MarginBounds.Size.Width, _
                 ev.MarginBounds.Size.Height), sf)
        ev.Graphics.DrawString(line, printFont, Brushes.Black, _
           New RectangleF(leftMargin, yPos, ev.MarginBounds.Size.Width, _
           ev.MarginBounds.Size.Height), sf)
        yPos = yPos + actual.Height
    End While
    ' If more lines exist, print another page.
    If (line IsNot Nothing) Then
        ev.HasMorePages = True
    Else
        ev.HasMorePages = False
    End If
End Sub

Hope this helps everyone out.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)