hasmorepages ?

tutypruty

Member
Joined
Jul 31, 2009
Messages
6
Programming Experience
Beginner
hello guys

i am printing to a pdf printer and the result was only one page is printed...

the text printed is from a txtfile and i used the streamreader to pass it on the printer...


pathFile = New System.IO.StreamReader(pathofFile)
line = pathFile.ReadToEnd

e.Graphics.DrawString(line, New Font("Lucida Console", 8), Brushes.Black, 100, 3).


if i set the e.hasmorepages = true.. the 2nd the the rest of the page also print on what is on the 1st page...

but why ??? help me pls...
Thanks in Advance.. =p
 
I can envision a couple of problems

1) You are reading from a file and printing directly from within the print function
If you open the file in the print function, e.hasmorepages = true will cause the file to be opened a second time when the print function is subsequently called again, thus the first set of data that has already been written will be written again.

2) Printing multiple pages from dynamic data, which is essentially what you have when you read your data from a stream can be difficult to master because of several things:

All the data is written every time, it just does not show up on the page because it is out of the margin.

Each time the print function is called, the page number is incremented internally i.e. you don't manage this with code, thus your code must know exactly what has already been printed in any of the subsequent print calls.

3) By setting e.hasmorepages = true and not verifying that there is actually more data to be printed, the code will continue to print over and over again, even if there is no data to be printed, thus you will print into infinity or until your system crashes due to resource overload.

Try this:
Define a private variable with a module wide scope. This will hold the number of lines that have already been printed successfully. In the BeginPrint event, initialize this variable to 0, meaning you have not printed anything just yet.

In the PrintPage event, increment that variable by 1 each time you successfully print a line on the page. You will have to check to ensure that the item you are printing will actually fit on the page by using MeasureString with the coordinates of where it is to be printed.

When you read from the stream, if the line will not fit on the page, close the streamreader, you could otherwise end up with multiple file handles open and cause potential problems down the road, especially if the file is very big.

If the private variable is 0 when the PrintPage event is fired, you will know that this is the first time the event has been fired, thus simply open the streamreader and start using DrawString to put the lines on the page, however, if the private variable is anything else, then you will need to loop through your stream until the number of lines have been processed that match the number that have already been printed. i.e. pick up from the same location where you left off before.

What you might consider doing is creating a function that will increment the stream for you and just call that at the beginning of the PrintPage event.

Something like:
VB.NET:
SeekToStringInFile (ByVal strFilename As String, ByVal intLocation As Integer) As Stream

Of course, since you are reading the whole file en-masse you could make the file contents variable a private global, set it in the BeginPrint event and then trim the already printed portions out of the string, until it is eventually an empty value.

In the end, after your page has printed, you will need to determine if there are more pages that are required to be printed. If there are, set e.hasmorepages to true, otherwise set it to False.

I've put some of the things together in the following example, you will need to incorporate it in your program. I have not tested the code, so it may not be 100% correct.

VB.NET:
Class MyPrintingClass
    Private pathofFile As String
    Private FileContents As String
    Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, _
    ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
        'Make sure the FileContents are empty, just in case the last print event
        'was cancelled or a glitch caused the var to not be completely empty.
        FileContents = ""
    End Sub
    Private Sub PrintDocument_PrintPage(ByVal sender As Object, _ 
    ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
        'Define our string format for proper printing
        Dim strFmt As New StringFormat
        strFmt.Alignment = StringAlignment.Near
        strFmt.LineAlignment = StringAlignment.Near
        strFmt.Trimming = StringTrimming.None
        strFmt.FormatFlags = StringFormatFlags.LineLimit

        Dim charsFitted As Integer
        Dim linesFilled As Integer
        'Our Font
        Dim myFont As New Font("Lucida Console", 8)
        'Read the file, if it hasn't been already
        If FileContents.Length = 0 Then
            Dim pathFile As New System.IO.StreamReader(pathofFile)
            FileContents = pathFile.ReadToEnd
            pathFile.Close()
        End If
        'Measure the contents according to the page
        e.Graphics.MeasureString(FileContents, myFont, _
        New Drawing.SizeF(e.MarginBounds.Width, e.MarginBounds.Height), _
        strFmt, charsFitted, linesFilled)
        'Print the contents
        e.Graphics.DrawString(FileContents, myFont, Brushes.Black, 100, 3)
        'Trim the printed portion out of the variable
        FileContents = Right(FileContents, FileContents.Length - charsFitted)
        'Call the print function again if there is more to be printed
        If FileContents.Length > 0 Then
            e.HasMorePages = True
        Else
            e.HasMorePages = False
        End If
    End Sub
End Class
 
Back
Top