CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Nov 2003
    Posts
    53

    Question RichTextBox questions

    I want to make a "view only" rich text box.

    fyi:
    • I am deriving a new class from RichTextBox
    • I've set the ReadOnly property to true.


    1. Is there a way to prevent selection of items?
    2. Is there a way to remove the blinking cursor?

  2. #2
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: RichTextBox questions

    Quote Originally Posted by ezimmerman View Post
    I want to make a "view only" rich text box.


    fyi:
    • I am deriving a new class from RichTextBox
    • I've set the ReadOnly property to true.
    1. Is there a way to prevent selection of items?
    2. Is there a way to remove the blinking cursor?
    Instead of using the RTB directly use it and do it ownerdrawn. Then use something as a canvas where you draw the RTB output.
    No selection possible, no access to the data. Not necessary to make it read only. No cursor
    Here is the class I'm using
    Code:
     /// <summary>
    /// Ownerdrawn Richtextbox not zoomable
    /// </summary>
    public class RichTextBoxPrintCtrl:RichTextBox{
        //Convert the unit used by the .NET framework (1/100 inch) 0.254 mm)
        //and the unit used by Win32 API calls (twips 1/1440 inch)
        // 1 mm = 56,6928 twip 
        private const double anInch = 14.4;
    
        [StructLayout(LayoutKind.Sequential)] 
        private struct RECT	{
            public int Left;
    	public int Top;
    	public int Right;
    	public int Bottom;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct CHARRANGE {
    	public int cpMin;         //First character of range (0 for start of doc)
    	public int cpMax;           //Last character of range (-1 for end of doc)
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct FORMATRANGE	{
    	public IntPtr hdc;             //Actual DC to draw on
    	public IntPtr hdcTarget;       //Target DC for determining text formatting
    	public RECT rc;                //Region of the DC to draw to (in twips)
    	public RECT rcPage;            //Region of the whole DC (page size) (in twips)
    	public CHARRANGE chrg;         //Range of text to draw (see earlier declaration)
        }
    
        private const int WM_USER  = 0x0400;
        private const int EM_FORMATRANGE  = WM_USER + 57;
    	
        [DllImport("USER32.dll")]
        private static extern IntPtr SendMessage (IntPtr hWnd , int msg , IntPtr wp, IntPtr lp); 
    
        //  Renders the contents of the RichTextBox for printing
        //  Return the last character printed + 1 (printing start from this point for next page)
        /// <summary>
        /// Prints the RTB in the devicecontext
        /// Margin sizes needs to be done in the PrintPageEvents
        /// </summary>
        /// <param name="charFrom"></param>
        /// <param name="charTo"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        public int Print( int charFrom, int charTo,PrintPageEventArgs e) {
    	//Calculate the area to render and print
    	RECT rectToPrint; 
    	rectToPrint.Top = (int)(e.MarginBounds.Top * anInch);
    	rectToPrint.Bottom = (int)(e.MarginBounds.Bottom * anInch);
    	rectToPrint.Left = (int)(e.MarginBounds.Left * anInch);
    	rectToPrint.Right = (int)(e.MarginBounds.Right * anInch);
            //Calculate the size of the page
    	RECT rectPage; 
    	rectPage.Top = (int)(e.PageBounds.Top * anInch);
    	rectPage.Bottom = (int)(e.PageBounds.Bottom * anInch);
    	rectPage.Left = (int)(e.PageBounds.Left * anInch);
    	rectPage.Right = (int)(e.PageBounds.Right * anInch);
            Graphics g = e.Graphics;
            IntPtr res = Draw(charFrom, charTo, ref rectToPrint, ref rectPage, g);
    	//Return last + 1 character printer
    	return res.ToInt32();
        }
    
        /// <summary>
        /// The internal Draw method that draws the  RTB Text in WYSIWYG Format.
        /// </summary>
        /// <param name="charFrom"></param>
        /// <param name="charTo"></param>
        /// <param name="rectToPrint"></param>
        /// <param name="rectPage"></param>
        /// <param name="g"></param>
        /// <returns></returns>
        private IntPtr Draw(int charFrom, int charTo, ref RECT rectToPrint, ref RECT rectPage, Graphics g) {
            IntPtr hdc = g.GetHdc();
            FORMATRANGE fmtRange;
            fmtRange.chrg.cpMax = charTo;				//Indicate character from to character to 
            fmtRange.chrg.cpMin = charFrom;
            fmtRange.hdc = hdc;                    //Use the same DC for measuring and rendering
            fmtRange.hdcTarget = hdc;              //Point at printer hDC
            fmtRange.rc = rectToPrint;             //Indicate the area on page to print
            fmtRange.rcPage = rectPage;            //Indicate size of page
    
            IntPtr res = IntPtr.Zero;
    
            IntPtr wparam = IntPtr.Zero;
            wparam = new IntPtr(1);
    
            //Get the pointer to the FORMATRANGE structure in memory
            IntPtr lparam = IntPtr.Zero;
            lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
            Marshal.StructureToPtr(fmtRange, lparam, false);
    
            //Send the rendered data for printing 
            res = SendMessage(Handle, EM_FORMATRANGE, wparam, lparam);
    
            //Free the block of memory allocated
            Marshal.FreeCoTaskMem(lparam);
            //Release the device context handle obtained by a previous call
            g.ReleaseHdc(hdc);
            return res;
        }
    
        /// <summary>
        /// Draws the RTB as it is by use of the Graphics adapter of the canvas. Sizes  in Twips
        /// </summary>
        /// <param name="recInner"></param>
        /// <param name="recDoc"></param>
        /// <param name="g"></param>
        public void DrawRTBText( int width, int height, Rectangle recMargin, Rectangle recDoc, Graphics g) {
            RECT rectToPrint;
            this.Width = width;
            this.Height = height;
            rectToPrint.Left = recMargin.Left;
            rectToPrint.Right = recMargin.Width+ recMargin.Left;
            rectToPrint.Top = recMargin.Top;
            rectToPrint.Bottom = recMargin.Top + recMargin.Height;
            RECT rectPage;
            rectPage.Left = recDoc.Left;
            rectPage.Top = recDoc.Top;
            rectPage.Right = recDoc.Left + recDoc.Width;
            rectPage.Bottom = recDoc.Top + recDoc.Height;
            int len = this.Text.Length;
            Draw(0, len, ref rectToPrint, ref rectPage, g);
        }
    }
    Last edited by JonnyPoet; October 14th, 2009 at 02:45 PM.
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  3. #3
    Join Date
    Nov 2003
    Posts
    53

    Question Re: RichTextBox questions

    How do I do that?

  4. #4
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: RichTextBox questions

    Quote Originally Posted by ezimmerman View Post
    How do I do that?
    Simple use for example a picturebox as the canvas and the class I provided as the RTB class. The picturebox has the possibillity to ownerdraw so in that drawing method use call the DrawRTBText method of the derived RTB class.

    So after you have filled your RTB with data simple invalidate the Picturebox so it will call its draw method, which will call the DrawRTBTex mmethod. The RTB is drawn on the canvas then (in the picturebox) In my case this looks like the picture in the bottom. ( BTW The text is simple an example its a word doc loaded into that RTB and as I also did some rulers it also looks like word, but it is an ownerdrawn RTB.) The text is a letter talking to a friend about a learning project and if people would be interested into a project like that. )
    Attached Images Attached Images
    Last edited by JonnyPoet; October 14th, 2009 at 03:37 PM.
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  5. #5
    Join Date
    Nov 2003
    Posts
    53

    Re: RichTextBox questions

    Brilliant, but how are you loading it so you still get scrollbars?
    What does your pictureBox paint handler look like?

    Thanks again!
    Eric

  6. #6
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: RichTextBox questions

    Lokk at this page
    http://www.codeproject.com/KB/cs/Biz...02#xx3104702xx
    When you modify that code as I did then you can use that RTB together wiz the canvas created by that control.
    Read the comments too and especially look for the corrections of code I did as 'nussknacker' there
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

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

Featured