Results 1 to 6 of 6

Thread: RichTextBox to Image

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Oct 2018
    Posts
    16

    RichTextBox to Image

    I am trying to convert the entire contents of a Rich Text Box to an Image so I can mirror the image. I am able to capture and mirror the part of the RTB that shows on the screen with the code below but the part of the RTB that is scrolled off the screen isn't captured. I would like to convert the entire contents of the RTB to a single image. Is there a way to capture all of the RTB and not just the part that shows? My RTB will consist of just text in a mixture of font sizes. The image does NOT need to update as the user modifies the RTB. Its just a capture of the final edits.

    Thanks

    Code:
    Public Class Form1
    
        Private Declare Function BitBlt Lib "gdi32.dll" (ByVal hdc As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hdcSrc As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As UInteger) As Boolean
    
        'Show the Rich Text Box as a Mirrored form.
        Private Sub btShowMifforForm_Click(sender As Object, e As EventArgs) Handles btShowMifforForm.Click
            Dim form As Form = New Form()
            form.Size = Me.Size
            Dim pic As PictureBox = New PictureBox()
            pic.Location = Me.RichTextBox1.Location
            pic.Size = Me.RichTextBox1.Size
            Dim bitmap As Bitmap = New Bitmap(Me.RichTextBox1.Width, Me.RichTextBox1.Height)
            DrawToBitmap(Me.RichTextBox1, bitmap, New Rectangle(Point.Empty, Me.RichTextBox1.Size))
            bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX)
            pic.Image = bitmap
            form.Controls.Add(pic)
            form.Show()
        End Sub
    
        Private Overloads Sub DrawToBitmap(ByVal richTextBox As RichTextBox, ByVal image As Bitmap, ByVal targetRectangle As Rectangle)
            Dim g As Graphics = RichTextBox1.CreateGraphics()
            Dim g2 As Graphics = Graphics.FromImage(image)
            Dim gi As IntPtr = g.GetHdc()
            Dim gi2 As IntPtr = g2.GetHdc()
            BitBlt(gi2, 0, 0, richTextBox.Width, richTextBox.Height, gi, 0, 0, &HCC0020)
            g.ReleaseHdc()
            g2.ReleaseHdc()
            g.Dispose()
            g2.Dispose()
        End Sub
    
    End Class

  2. #2
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,588

    Re: RichTextBox to Image

    It appears as though there is an MSDN article with detailed instructions on how to print the content of a RichTextBox control here: https://support.microsoft.com/en-us/help/811401/

    Presumably you can follow these same instructions to simply save your image rather than printing it.

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Oct 2018
    Posts
    16

    Re: RichTextBox to Image

    Thank you for the article. I looked over the code and it looks like this code adds margins and paginates it. I think there is a seperate image for each page. I need to get the entire thing in one image no mater how long it is. I was hoping there was some way to do a select all in the control and output the selection to a bit map.

  4. #4
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,588

    Re: RichTextBox to Image

    If it creates separate images for each page, simply append the sequential image to the original one.

  5. #5
    Frenzied Member jdc2000's Avatar
    Join Date
    Oct 2001
    Location
    Idaho Falls, Idaho USA
    Posts
    1,632

    Re: RichTextBox to Image

    Or, just change the page size to whatever you need. Note that a 5000 page image file will not be very useful.

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Oct 2018
    Posts
    16

    Re: RichTextBox to Image

    Thanks for the pointer(s). Using that article and cross-referencing that to another article and running that code through a C to VB converter I was able to work out this code which does get the entire contents of the richtextbox to a image. Here is the solution I was able to piece together

    Code:
         Inherits Form
    
        <DllImport("user32.dll", EntryPoint:="SendMessage")>
        Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
        End Function
    
    
        Private Const WM_USER As Integer = 1024
        Private Const EM_FORMATRANGE As Integer = (WM_USER + 57)
    
        <StructLayout(LayoutKind.Sequential)>
        Private Structure RECT
            Public Left As Integer
            Public Top As Integer
            Public Right As Integer
            Public Bottom As Integer
        End Structure
    
        <StructLayout(LayoutKind.Sequential)>
        Private Structure CHARRANGE
            Public cpMin As Integer
            Public cpMax As Integer
        End Structure
    
        <StructLayout(LayoutKind.Sequential)>
        Private Structure FORMATRANGE
            Public hdc As IntPtr
            Public hdcTarget As IntPtr
            Public rc As RECT
            Public rcPage As RECT
            Public chrg As CHARRANGE
        End Structure
    
        Private Const inch As Double = 14.4
        Private contentRectangle As Rectangle
    
        Public Sub New()
            MyBase.New
            InitializeComponent()
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.RtbToBitmap(RichTextBox1, Me.contentRectangle, "c:\temp\rtb.jpg")
        End Sub
    
        Private Sub RtbToBitmap(ByVal rtb As RichTextBox, ByVal rectangle As Rectangle, ByVal fileName As String)
            Dim bmp As Bitmap = New Bitmap(rectangle.Width, rectangle.Height)
            Dim gr As Graphics = Graphics.FromImage(bmp)
            Dim hDC As IntPtr = gr.GetHdc
            Dim fmtRange As FORMATRANGE
            Dim rect As RECT
            Dim fromAPI As Integer
            rect.Top = 0
            rect.Left = 0
            rect.Bottom = CType((bmp.Height _
                             + ((bmp.Height _
                             * (bmp.HorizontalResolution / 100)) _
                             * inch)), Integer)
            rect.Right = CType((bmp.Width _
                             + ((bmp.Width _
                             * (bmp.VerticalResolution / 100)) _
                             * inch)), Integer)
            fmtRange.chrg.cpMin = 0
            fmtRange.chrg.cpMax = -1
            fmtRange.hdc = hDC
            fmtRange.hdcTarget = hDC
            fmtRange.rc = rect
            fmtRange.rcPage = rect
            Dim wParam As Integer = 1
            Dim lParam As IntPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange))
            Marshal.StructureToPtr(fmtRange, lParam, False)
            fromAPI = SendMessage(rtb.Handle, EM_FORMATRANGE, wParam, lParam)
            Marshal.FreeCoTaskMem(lParam)
            fromAPI = SendMessage(rtb.Handle, EM_FORMATRANGE, wParam, New IntPtr(0))
            gr.ReleaseHdc(hDC)
            bmp.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg)
            bmp.Dispose()
        End Sub
    
        Private Sub RichTextBox1_ContentsResized(sender As Object, e As ContentsResizedEventArgs) Handles RichTextBox1.ContentsResized
            Me.contentRectangle = e.NewRectangle
        End Sub
    Put richtextbox1 and button1 on the form. Set the rtb properties to multiline=true and set your anchors=Top,Left,Right, scrollbars=none. Thanks again,

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width