Still working on getting formatted output. I have a routine using the Graphics.Drawstring method from the PrintPage EventArgs class in VB.NET printing output to a printer, and it works perfectly for single-line text fields, etc.
However, when dealing with multi-line text fields where the users could insert carriage returns, and my need to insert manual line breaks, is not working. I end up printing all lines on top of each other.
I've developed branching logic to search for VBCR in the field, and to go down a line for it but not print it. I've also included logic to look for logical line breaks in the field.
I'm sure this is a simple logic error but in the past 4 hours of stepping through my code I'm not seeing where the problem lies. Anyone see?
Private Sub PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs) Try Dim yPos As Single = 100 Dim leftMargin As Single = ev.MarginBounds.Left Dim topMargin As Single = ev.MarginBounds.Top Dim drawBoldFont As New Font("Arial", 10, FontStyle.bold) Dim drawFont As New Font("Arial", 10) Dim lines as single = 17 Dim spaces as single = 7 Dim header as string Dim x as integer dim linesToSkip as integer 'Add the page heading and the time submitted ev.Graphics.DrawString("THE FOLLOWING REQUEST HAS BEEN SUBMITTED", drawBoldFont, Brushes.Black, leftMargin, yPos, New StringFormat()) yPos = yPos + (2*lines) header = "Department: " ev.Graphics.DrawString(header, drawBoldFont, Brushes.Black, leftMargin, yPos, New StringFormat()) ev.Graphics.DrawString(Me.txtDepartment.Text.Trim, drawFont, Brushes.Black, leftMargin+(len(header)*spaces), yPos, New StringFormat()) yPos = yPos + (1*lines) header = "Contact Name: " ev.Graphics.DrawString(header, drawBoldFont, Brushes.Black, leftMargin, yPos, New StringFormat()) ev.Graphics.DrawString(Me.txtContact.Text.Trim, drawFont, Brushes.Black, leftMargin+(len(header)*spaces), yPos, New StringFormat()) yPos = yPos + (1*lines) header = "Phone: " ev.Graphics.DrawString(header, drawBoldFont, Brushes.Black, leftMargin, yPos, New StringFormat()) ev.Graphics.DrawString(Me.txtPhone.Text.Trim, drawFont, Brushes.Black, leftMargin+(len(header)*spaces), yPos, New StringFormat()) yPos = yPos + (2*lines)'*********All of the above work fine, but when I start getting to the multi-line field below it breaks up header = "Message: " ev.Graphics.DrawString(header, drawBoldFont, Brushes.Black, leftMargin, yPos, New StringFormat()) x = 1 linesToSkip = 1 dim currentChar As Integer dim currentLine As Integer currentChar = 0 currentLine = 1 Dim chars As Integer Dim foundLineReturn As Boolean While currentChar < Me.txtMenu.Text.Length chars = 0 foundLineReturn = False While chars < 80 If Me.txtMenu.Text.Substring(currentChar + chars, 1) = vbCr Then foundLineReturn = True If chars > 1 Then If currentLine = 1 Then ev.Graphics.DrawString(Me.txtMenu.Text.Substring(currentChar, chars), drawFont, Brushes.Black, leftMargin + (Len(header) * spaces), yPos, New StringFormat()) Else ev.Graphics.DrawString(Me.txtMenu.Text.Substring(currentChar, chars), drawFont, Brushes.Black, leftMargin, yPos, New StringFormat()) End If End If yPos = yPos + (2 * lines) chars += 1 currentChar = currentChar + chars Exit While Else chars += 1 End If End While If foundLineReturn = False Then If Me.txtMenu.Text.Substring(currentChar + chars, 1) <> " " And _ Me.txtMenu.Text.Substring(currentChar + chars, 1) <> "-" And _ Me.txtMenu.Text.Substring(currentChar + chars, 1) <> vbLf Then ' As long as the last character is not space or carriage return, ' keep subtracting another character from the text to be printed. chars = 80 If currentLine = 1 Then chars = chars - 20 While chars > 0 AndAlso _ Me.txtMenu.Text.Substring(currentChar + chars, 1) <> " " AndAlso _ Me.txtMenu.Text.Substring(currentChar + chars, 1) <> vbLf chars -= 1 End While chars += 1 End If If chars = 0 Or chars = 1 Then chars = 80 If currentLine = 1 Then ev.Graphics.DrawString(Me.txtMenu.Text.Substring(currentChar, chars), drawFont, Brushes.Black, leftMargin + (Len(header) * spaces), yPos, New StringFormat()) Else ev.Graphics.DrawString(Me.txtMenu.Text.Substring(currentChar, chars), drawFont, Brushes.Black, leftMargin, yPos, New StringFormat()) End If currentChar = currentChar + chars currentLine += 1 yPos = yPos + (1 * lines) End If End While yPos = yPos + (1 * lines)'additionally none of the below prints either yPos = yPos + (2*lines) header = "Sent: " ev.Graphics.DrawString(header, drawBoldFont, Brushes.Black, leftMargin, yPos, New StringFormat()) ev.Graphics.DrawString(Now.ToShortDateString & " - " & Now.ToShortTimeString, drawFont, Brushes.Black, leftMargin+(len(header)*spaces), yPos, New StringFormat()) yPos = yPos + (2*lines) Catch ex As Exception HandleError("Error in escort request form PrintPage routine: " & ex.Message, "PrintPage") End Try End Sub
If stepping through the code, it turns out that the logic is working correctly and the conditions are working as they should, then you may want to use the measurestring function to determine how much space a text would take on page.
thearniec
ASKER
I'm sorry guys, I must be dense today. I've done some googles of TextRenderer.drawText and I'm finding it works about the same as Graphics.DrawString. Does DrawText automatically insert line breaks?
And CodeCruiser, I'm not sure how MeasureString will help given my code, because I am moving the Y Coordinate in the code but what happens is the first line and second line of a multi-line text field print on top of each other for some reason. Paragraphs are spread apart. I THINK the problem is that a carriage return is printing with one line moving it down but I've tried filtering out VBCR, VBCRLF, VBLF, and I'm getting the same results.
Where do you get the text from? Are you sure it contains carriage returns?
thearniec
ASKER
CC: The text is a user text field, much like I'm typing in right now with the Post Comment/solution field here on EE.com. It is used for a user to enter an order, and it seems likely that many users will choose to put one item per line in this field. As such, I am trying to code it so it CAN contain carriage returns, but it does not have to.
Thanks agian for your help with this...I truly appreciate it.
Nasir Razzaq
The MeasureString would come in handy if there is no carriage return in the text. You could use this function to determine whether you need to add a line break or draw it on single line.
You could put a messagebox.show(asc(e.keychar)) in the keypress event of textbox where the input is being provided to determine what asc code is added for enter key and use that to find line breaks.
Well I checked, it is VBCR being used, which I was checking for.
I'm still thinking the code I have above SHOULD work, and that I have a logic error that I can't find.
But beyond that, I cannot imagine that I'm the only one trying to print a multi-line textfield to a printer. Are there no classes or basic code that can do what I'm trying?
Nasir Razzaq
There is a paid solution. DeveloperExpress.
thearniec
ASKER
Been workin gat this for 2 more hours this morning...still no go. Anything else that does not include buying Devleoper Express?
Open in new window