That sucks you've been robbed. I've never done a report like that in .NET but there is an article in the new Visual Studio Magazine about it. You have to use the System.Drawing.Printing namespace. What part are you stuck on?
The basic printing functions built into Visual Studio are very primitive. While I've managed to do things like printing two columns of plain text (example at http://www.vbforums.com/showthread.p...hreadid=204202) to do very much more than that requires extending the builtin print handler, which is a little bit beyond me at the moment. I found a DLL for a custom control that extends the RichTextBox and builds in a more functional print handler, but it only prints in one column and is probably not all that useful for doing tabular reports. If you want to try it out it's attached with source.
Actually it seems there's an API function that prints formatted text but I've never messed with API calls from VB (guess now is as good a time as any to learn how heh)
ms-help://MS.VSCC/MS.MSDNVS/gdi/fontext_0odw.htm
The Graphics.DrawString method that's part of the .NET framework doesn't seem to support embedded/mixed formatting:
Actually it seems that DrawText does the same thing as the .NET method DrawString (omits formatting). As the guy who wrote the above DLL says, it looks like EM_FORMATRANGE message is what you need to invoke in order to render mixed format text?
Why is this so hard? Why isn't the print handler a little less dinky? Friggin Wordpad has this built into it. *grumble*
Getting it into a richtext and formatting it there isn't the problem, I'm already able to do that - it's getting it to the printer with the formatting intact. All the Graphics.DrawString method seems to be able to do is draw text in one font, one style, one point size. You're allowed to use tabs and returns but that's pretty much the only formatting it will interpret. Font changes, point size changes and underline/bold/italic state changes are ignored.
Yes you can - but I haven't seen a way to print mixed-format text in a rectangle with font changes, point size changes etc. *reads pages 919-926 a little closer than last time* maybe I just didn't understand it before.
...
Yeah my problem with that way of doing things is that in order to go to the printer without scrutinizing the hell out of each and every character, I'd like to use the string measurement method Graphics.MeasureString - where I'm out of ideas is getting the text, with embedded formatting information like size change, underline/bold/font changes etc., from a RichTextBox into MeasureString and DrawString. The Programming VB .NET book examples all deal with just drawing text on a form, and there's no concern for how the text will wrap or clip (what MeasureString handles). I dunno, maybe there's a simple way to get text out of the RichTextBox and into DrawString with formatting intact, but I just don't see it.
Last edited by Slow_Learner; Oct 11th, 2002 at 02:02 AM.
Actually I think it may be a mistake to try to shoehorn RichTextBoxes into my printing scheme. Here's what I'm using right now:
Code:
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim iCharsLeftColumn, iCharsRightColumn As Integer
Dim iLinesLeftColumn, iLinesRightColumn As Integer
Dim strForPageLeftColumn, strForPageRightColumn As String
Dim fmtStringFormatLeft As New StringFormat()
Dim fmtStringFormatRight As New StringFormat()
Dim iTabStopsLeft() As Single = {50, 50, 50, 50, 50, 50}
fmtStringFormatLeft.SetTabStops(0, iTabStopsLeft)
Dim iTabStopsRight() As Single = {220, 50, 50}
fmtStringFormatRight.SetTabStops(0, iTabStopsRight)
Dim rectLeftColumn As New RectangleF( _
e.MarginBounds.Left, e.MarginBounds.Top, _
(e.MarginBounds.Width / 2) - 10, e.MarginBounds.Height)
Dim rectRightColumn As New RectangleF( _
(e.MarginBounds.Width / 2) + 90, e.MarginBounds.Top, _
(e.MarginBounds.Width / 2) - 10, e.MarginBounds.Height)
Dim sizeMeasure As New SizeF((e.MarginBounds.Width / 2) - 10, _
e.MarginBounds.Height - PrintFont.GetHeight(e.Graphics))
fmtStringFormatLeft.Trimming = StringTrimming.Word
fmtStringFormatRight.Trimming = StringTrimming.Word
e.Graphics.MeasureString(strPrintLeftColumn, PrintFont, sizeMeasure, _
fmtStringFormatLeft, iCharsLeftColumn, iLinesLeftColumn)
e.Graphics.MeasureString(strPrintRightColumn, PrintFont, sizeMeasure, _
fmtStringFormatRight, iCharsRightColumn, iLinesRightColumn)
strForPageLeftColumn = strPrintLeftColumn.Substring(0, iCharsLeftColumn)
strForPageRightColumn = strPrintRightColumn.Substring(0, iCharsRightColumn)
e.Graphics.DrawString(strForPageLeftColumn, PrintFont, Brushes.Black, rectLeftColumn, _
fmtStringFormatLeft)
e.Graphics.DrawString(strForPageRightColumn, PrintFont, Brushes.Black, rectRightColumn, _
fmtStringFormatRight)
If iCharsLeftColumn < strPrintLeftColumn.Length Then
strPrintLeftColumn = strPrintLeftColumn.Substring(iCharsLeftColumn)
Else
strPrintLeftColumn = rtxtPrintLeftColumn.Text
End If
If iCharsRightColumn < strPrintRightColumn.Length Then
strPrintRightColumn = strPrintRightColumn.Substring(iCharsRightColumn)
Else
strPrintRightColumn = rtxtPrintRightColumn.Text
End If
If iCharsLeftColumn < strPrintLeftColumn.Length Or _
iCharsRightColumn < strPrintRightColumn.Length Then
e.HasMorePages = True
Else
e.HasMorePages = False
End If
End Sub
Before the print event is fired I've been able to get text into the two richtextboxes and get it formatted the way I like it (with underlines and bolds and whatnot). The downside is that the formatting is lost (which makes sense as I'm looking at the RichTextBox.Text property to get the text to work with, and that appears to just give a string as the docs say it does.)
While this doesn't look super clean (at least it doesn't to me) it's a lot cleaner than anything I can envision if I didn't render a whole page's worth of column at a time - I think I might be able to work out a way to keep track of how much of a column I've used and draw the text line-by-line to the graphics object of the printdocument, but that seems MESSY AS HELL and I'm not very eager to do it like that if there's a more elegant solution.
In the hope that someone is helped (I feel sorry for the original poster for hijacking his thread so badly) please feel free to use this extended control: