1

I wrote code to display the text in separate pages, like Microsoft Word, I use a Collection of text boxes, and when the user filled one text box, new box is displayed automatically, and the cursor moves to her.

The problem is that when the user writes the last line in the text box, the box scrolls down a bit, as you will see when you will run this code, so how can I disable the scrolling.

the code :

        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.Data;
        using System.Drawing;
        using System.Linq;
        using System.Text;
        using System.Windows.Forms;
        using System.Runtime.InteropServices;

        namespace WindowsFormsApplication1
        {
            public partial class Form1 : Form
            {
                List<myRTB> pages; // collection of our RichTextBox, use as pages

                public Form1()
                {
                    InitializeComponent();

                    pages = new List<myRTB>();
                    pages.Add(new myRTB());
                    pages[0].Width = 200;
                    pages[0].Height = 290;
                    pages[0].Location = new Point(50, 10);
                    pages[0].Name = "0";
                    this.Controls.Add(pages[0]);

                    this.Width = 300;
                    this.Height = 360;
                    this.AutoScroll = true;
                }

                public void AddPage(int correntPageIndex)
                {
                    if (correntPageIndex == (pages.Count - 1)) 
                    {
                        // create a new page
                        pages.Add(new myRTB());
                        pages[correntPageIndex + 1].Width = 200;
                        pages[correntPageIndex + 1].Height = 290;
                        pages[correntPageIndex + 1].Location = new Point(50, pages[correntPageIndex].Location.Y + 300);
                        this.Controls.Add(pages[pages.Count - 1]);
                        this.Name = (correntPageIndex + 1).ToString();
                    }

                    bool CursorInEnd = (pages[correntPageIndex].SelectionStart == pages[correntPageIndex].TextLength);

                    // Transfer the last word on the previous page, to the new page

                    int lastLineIndex = pages[correntPageIndex].GetLineFromCharIndex(pages[correntPageIndex].TextLength - 2);
                    // find the index of the first char in the last line
                    int indexOfFirstCharInLastLine = pages[correntPageIndex].GetFirstCharIndexFromLine(lastLineIndex);
                    // find the index of the last space in the last line
                    int indexOfLastSpace = pages[correntPageIndex].Text.LastIndexOf(' ', indexOfFirstCharInLastLine);

                    string restOfString; 

                    if (indexOfLastSpace < 0) // no spaces in the last line
                    {
                        restOfString = pages[correntPageIndex].Text.Substring(pages[correntPageIndex].TextLength - 1);
                        pages[correntPageIndex + 1].Text.Insert(0, restOfString);
                        pages[correntPageIndex].Text.Remove(pages[correntPageIndex].TextLength - 1);
                    }
                    else // there is spaces in the last line
                    {
                        restOfString = pages[correntPageIndex].Text.Substring(indexOfLastSpace + 1);
                        pages[correntPageIndex + 1].Text = pages[correntPageIndex + 1].Text.Insert(0, restOfString);
                        pages[correntPageIndex].Text = pages[correntPageIndex].Text.Remove(indexOfLastSpace + 1);
                    }

                    if (CursorInEnd)
                    {
                        // Move the cursor to next page 
                        pages[correntPageIndex + 1].SelectionStart = restOfString.Length;
                        pages[correntPageIndex + 1].Focus();
                    }
                }
            }

            class myRTB : RichTextBox
            {
                public myRTB()
                {
                    this.ScrollBars = RichTextBoxScrollBars.None;
                }
                protected override void WndProc(ref Message m)
                {
                    // catch the request resize message
                    if (m.Msg == (WM_REFLECT | WM_NOTIFY)) 
                    {
                        REQRESIZE rrs = (REQRESIZE)(Marshal.PtrToStructure(m.LParam, typeof(REQRESIZE)));
                        if (rrs.nmhdr.code == EN_REQUESTRESIZE)
                        {
                            if (rrs.rc.ToRectangle().Height > this.ClientRectangle.Height)
                            {
                                ((Form1)Parent).AddPage(int.Parse(this.Name));
                            }
                        }
                    }
                    base.WndProc(ref m);
                }

                [StructLayout(LayoutKind.Sequential)]
                public struct NMHDR
                {
                    public IntPtr HWND;
                    public uint idFrom;
                    public int code;
                    public override String ToString()
                    {
                        return String.Format("Hwnd: {0}, ControlID: {1}, Code: {2}",
                        HWND, idFrom, code);
                    }
                }

                [StructLayout(LayoutKind.Sequential)]
                public struct REQRESIZE
                {
                    public NMHDR nmhdr;
                    public RECT rc;
                }

                [StructLayout(LayoutKind.Sequential)]
                public struct RECT
                {
                    public int Left, Top, Right, Bottom;
                    public override string ToString()
                    {
                        return String.Format("{0}, {1}, {2}, {3}", Left, Top, Right,
                        Bottom);
                    }
                    public Rectangle ToRectangle()
                    {
                        return Rectangle.FromLTRB(Left, Top, Right, Bottom);
                    }
                }

                public const int WM_USER = 0x400;
                public const int WM_NOTIFY = 0x4E;
                public const int WM_REFLECT = WM_USER + 0x1C00;
                public const int EN_REQUESTRESIZE = 0x701;

            }
        }
user1543998
  • 145
  • 1
  • 3
  • 10

1 Answers1

0

To ensure that the text does not scroll automatically, take a look at the following answer to a similar problem.

Disabling RichTextBox autoscroll

Here's another great answer to your problem:

Prevent Autoscrolling in RichTextBox

I copied over the code from the link above, please ensure to give that user credit for providing this code (its not mine)

   [System.Runtime.InteropServices.DllImport("user32.dll")] 

   static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam); 
   const int WM_USER = 0x400; 
   const int EM_HIDESELECTION = WM_USER + 63;

   void OnAppend(string text)     
   {         
   bool focused = richTextBox1.Focused; 
   //backup initial selection 
   int selection = richTextBox1.SelectionStart;         
   int length = richTextBox1.SelectionLength;         
   //allow autoscroll if selection is at end of text         
      bool autoscroll = (selection==richTextBox1.Text.Length);
      if (!autoscroll)         
      {  
         //shift focus from RichTextBox to some other control            
        if (focused) 
          textBox1.Focus();             
         //hide selection             
      SendMessage(richTextBox1.Handle, EM_HIDESELECTION, 1, 0);
      }          

      richTextBox1.AppendText(text);

      if (!autoscroll)         
      {             
         //restore initial selection            
         richTextBox1.SelectionStart = selection;             
         richTextBox1.SelectionLength = length;             
         //unhide selection             
         SendMessage(richTextBox1.Handle, EM_HIDESELECTION, 0, 0);             
         //restore focus to RichTextBox             
         if(focused) richTextBox1.Focus();         
      }     
   } 
Community
  • 1
  • 1
Dayan
  • 7,634
  • 11
  • 49
  • 76
  • In my example I already wrote **this.ScrollBars = RichTextBoxScrollBars.None;** And it makes that scroll bar is not displayed, but the text box still scrolling. – user1543998 Aug 07 '12 at 11:44
  • Sorry for that, missed that VERY important line of code :) i updated my answer, i think it will help you. – Dayan Aug 07 '12 at 12:22
  • but still, after you type, if you move the cursor to the last line on the first page, the text box scrolls down a bit, and shown a space under the line. – user1543998 Aug 07 '12 at 13:55
  • Hmm, maybe try adding some code under the focus event to check if theres any new line after the end of that page, if so then remove that line, disable scroll and and get focus of next richtexboxt? Its a dirty work around but it might just work. – Dayan Aug 07 '12 at 14:27
  • Focus() some other control seems to be the key here. – Dan Bechard Jul 18 '14 at 17:53