Solved

SelPrint doesn't work!

Posted on 1998-07-31
1
297 Views
Last Modified: 2012-06-27
I am trying to print the contents of a RichTextBox using the SelPrint method.  I have tried the example in the VB 4 SelPrint documentation which is as follows...

This example prints the formatted text in a RichTextBox control.  To try this example, put a RichTextBox control, a CommonDialog control, and a CommandButton control on a form.  Paste this code into the Click event of the CommandButton control.  Then run the example.

Private Sub Command1_Click()
      CommonDialog1.Flags = cdlPDReturnDC + cdlPDNoPageNums
      If RichTextBox1.SelLength = 0 Then
            CommonDialog1.Flags = CommonDialog1.Flags + cdlPDAllPages
      Else
            CommonDialog1.Flags = CommonDialog1.Flags + cdlPDSelection
      End If
      CommonDialog1.ShowPrinter
      RichTextBox1.SelPrint CommonDialog1.hDC
End Sub

But when I try it out, nothing prints!  I keyed in some text into the RichTextBox and clicked on the command button, but although there is a little disk activity (which shows something is happening), nothing prints.  How can I make this example work, so that it prints?  I have my printer set up properly as the default printer, so why isn't it working?
0
Comment
Question by:Richard2000
1 Comment
 
LVL 6

Accepted Solution

by:
anthonyc earned 50 total points
Comment Utility
Start a new project in the Visual Basic 32-bit edition. Form1 is created
   by default.
 
2. Put a CommandButton and a RichTextBox control on Form1.
 
3. Add the following code to Form1:
 
   Option Explicit
 
   Private Sub Form_Load()
      Dim LineWidth As Long
 
      ' Initialize Form and Command button
      Me.Caption = "Rich Text Box WYSIWYG Printing Example"
      Command1.Move 10, 10, 600, 380
      Command1.Caption = "&Print"
 
      ' Set the font of the RTF to a TrueType font for best results
      RichTextBox1.SelFontName = "Arial"
      RichTextBox1.SelFontSize = 10
 
      ' Tell the RTF to base it's display off of the printer
      LineWidth = WYSIWYG_RTF(RichTextBox1, 1440, 1440) '1440 Twips=1 Inch
 
      ' Set the form width to match the line width
      Me.Width = LineWidth + 200
   End Sub
 
   Private Sub Form_Resize()
      ' Position the RTF on form
      RichTextBox1.Move 100, 500, Me.ScaleWidth - 200, Me.ScaleHeight - 600
   End Sub
 
   Private Sub Command1_Click()
      ' Print the contents of the RichTextBox with a one inch margin
      PrintRTF RichTextBox1, 1440, 1440, 1440, 1440 ' 1440 Twips = 1 Inch
   End Sub
 
4. Insert a new standard module into the project, Module1.bas is created by
   default.
 
5. Add the following code to Module1:
 
   Option Explicit
 
   Private Type Rect
      Left As Long
      Top As Long
      Right As Long
      Bottom As Long
   End Type
 
   Private Type CharRange
     cpMin As Long     ' First character of range (0 for start of doc)
     cpMax As Long     ' Last character of range (-1 for end of doc)
   End Type
 
   Private Type FormatRange
     hdc As Long       ' Actual DC to draw on
     hdcTarget As Long ' Target DC for determining text formatting
     rc As Rect        ' Region of the DC to draw to (in twips)
     rcPage As Rect    ' Region of the entire DC (page size) (in twips)
     chrg As CharRange ' Range of text to draw (see above declaration)
   End Type
 
   Private Const WM_USER As Long = &H400
   Private Const EM_FORMATRANGE As Long = WM_USER + 57
   Private Const EM_SETTARGETDEVICE As Long = WM_USER + 72
   Private Const PHYSICALOFFSETX As Long = 112
   Private Const PHYSICALOFFSETY As Long = 113
 
   Private Declare Function GetDeviceCaps Lib "gdi32" ( _
      ByVal hdc As Long, ByVal nIndex As Long) As Long
   Private Declare Function SendMessage Lib "USER32" Alias "SendMessageA" _
      (ByVal hWnd As Long, ByVal msg As Long, ByVal wp As Long, _
      lp As Any) As Long
   Private Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" _
      (ByVal lpDriverName As String, ByVal lpDeviceName As String, _
      ByVal lpOutput As Long, ByVal lpInitData As Long) As Long
 
   ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
   '
   ' WYSIWYG_RTF - Sets an RTF control to display itself the same as it
   '               would print on the default printer
   '
   ' RTF - A RichTextBox control to set for WYSIWYG display.
   '
   ' LeftMarginWidth - Width of desired left margin in twips
   '
   ' RightMarginWidth - Width of desired right margin in twips
   '
   ' Returns - The length of a line on the printer in twips
   '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
   Public Function WYSIWYG_RTF(RTF As RichTextBox, LeftMarginWidth As Long,
   _
      RightMarginWidth As Long) As Long
      Dim LeftOffset As Long, LeftMargin As Long, RightMargin As Long
      Dim LineWidth As Long
      Dim PrinterhDC As Long
      Dim r As Long
 
      ' Start a print job to initialize printer object
      Printer.Print Space(1)
      Printer.ScaleMode = vbTwips
 
      ' Get the offset to the printable area on the page in twips
      LeftOffset = Printer.ScaleX(GetDeviceCaps(Printer.hdc, _
         PHYSICALOFFSETX), vbPixels, vbTwips)
 
      ' Calculate the Left, and Right margins
      LeftMargin = LeftMarginWidth - LeftOffset
      RightMargin = (Printer.Width - RightMarginWidth) - LeftOffset
 
      ' Calculate the line width
      LineWidth = RightMargin - LeftMargin
 
      ' Create an hDC on the Printer pointed to by the Printer object
      ' This DC needs to remain for the RTF to keep up the WYSIWYG display
      PrinterhDC = CreateDC(Printer.DriverName, Printer.DeviceName, 0, 0)
 
      ' Tell the RTF to base it's display off of the printer
      '    at the desired line width
      r = SendMessage(RTF.hWnd, EM_SETTARGETDEVICE, PrinterhDC, _
         ByVal LineWidth)
 
      ' Abort the temporary print job used to get printer info
      Printer.KillDoc
 
      WYSIWYG_RTF = LineWidth
   End Function
 
   ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
   '
   ' PrintRTF - Prints the contents of a RichTextBox control using the
   '            provided margins
   '
   ' RTF - A RichTextBox control to print
   '
   ' LeftMarginWidth - Width of desired left margin in twips
   '
   ' TopMarginHeight - Height of desired top margin in twips
   '
   ' RightMarginWidth - Width of desired right margin in twips
   '
   ' BottomMarginHeight - Height of desired bottom margin in twips
   '
   ' Notes - If you are also using WYSIWYG_RTF() on the provided RTF
   '         parameter you should specify the same LeftMarginWidth and
   '         RightMarginWidth that you used to call WYSIWYG_RTF()
   ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
   Public Sub PrintRTF(RTF As RichTextBox, LeftMarginWidth As Long, _
      TopMarginHeight, RightMarginWidth, BottomMarginHeight)
      Dim LeftOffset As Long, TopOffset As Long
      Dim LeftMargin As Long, TopMargin As Long
      Dim RightMargin As Long, BottomMargin As Long
      Dim fr As FormatRange
      Dim rcDrawTo As Rect
      Dim rcPage As Rect
      Dim TextLength As Long
      Dim NextCharPosition As Long
      Dim r As Long
 
      ' Start a print job to get a valid Printer.hDC
      Printer.Print Space(1)
      Printer.ScaleMode = vbTwips
 
      ' Get the offsett to the printable area on the page in twips
      LeftOffset = Printer.ScaleX(GetDeviceCaps(Printer.hdc, _
         PHYSICALOFFSETX), vbPixels, vbTwips)
      TopOffset = Printer.ScaleY(GetDeviceCaps(Printer.hdc, _
         PHYSICALOFFSETY), vbPixels, vbTwips)
 
      ' Calculate the Left, Top, Right, and Bottom margins
      LeftMargin = LeftMarginWidth - LeftOffset
      TopMargin = TopMarginHeight - TopOffset
      RightMargin = (Printer.Width - RightMarginWidth) - LeftOffset
      BottomMargin = (Printer.Height - BottomMarginHeight) - TopOffset
 
      ' Set printable area rect
      rcPage.Left = 0
      rcPage.Top = 0
      rcPage.Right = Printer.ScaleWidth
      rcPage.Bottom = Printer.ScaleHeight
 
      ' Set rect in which to print (relative to printable area)
      rcDrawTo.Left = LeftMargin
      rcDrawTo.Top = TopMargin
      rcDrawTo.Right = RightMargin
      rcDrawTo.Bottom = BottomMargin
 
      ' Set up the print instructions
      fr.hdc = Printer.hdc   ' Use the same DC for measuring and rendering
      fr.hdcTarget = Printer.hdc  ' Point at printer hDC
      fr.rc = rcDrawTo            ' Indicate the area on page to draw to
      fr.rcPage = rcPage          ' Indicate entire size of page
      fr.chrg.cpMin = 0           ' Indicate start of text through
      fr.chrg.cpMax = -1          ' end of the text
 
      ' Get length of text in RTF
      TextLength = Len(RTF.Text)
 
      ' Loop printing each page until done
      Do
         ' Print the page by sending EM_FORMATRANGE message
         NextCharPosition = SendMessage(RTF.hWnd, EM_FORMATRANGE, True, fr)
         If NextCharPosition >= TextLength Then Exit Do  'If done then exit
         fr.chrg.cpMin = NextCharPosition ' Starting position for next page
         Printer.NewPage                  ' Move on to next page
         Printer.Print Space(1) ' Re-initialize hDC
         fr.hDC = Printer.hDC
         fr.hDCTarget = Printer.hDC
      Loop
 
      ' Commit the print job
      Printer.EndDoc
 
      ' Allow the RTF to free up memory
      r = SendMessage(RTF.hWnd, EM_FORMATRANGE, False, ByVal CLng(0))
   End Sub
 
6. Save the project.
 
7. Run the project.
 
8. Enter or paste some text into the RichTextBox.

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now