Richtextbox converts line number to scroll position

Now I can synchronize my two RichTextBox using this part of the code:

 private const int SB_HORZ = 0x0; private const int SB_VERT = 0x1; private const int WM_HSCROLL = 0x114; private const int WM_VSCROLL = 0x115; private const int SB_THUMBPOSITION = 4; [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int GetScrollPos(int hWnd, int nBar); [DllImport("user32.dll")] private static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw); [DllImport("user32.dll")] private static extern bool PostMessageA(IntPtr hWnd, int nBar, int wParam, int lParam); internal int HScrollPos { private get { return GetScrollPos((int)this.Handle, SB_HORZ); } set { SetScrollPos((IntPtr)this.Handle, SB_HORZ, value, true); PostMessageA((IntPtr)this.Handle, WM_HSCROLL, SB_THUMBPOSITION + 0x10000 * value, 0); } } internal int VScrollPos { get { return GetScrollPos((int)this.Handle, SB_VERT); } set { SetScrollPos((IntPtr)this.Handle, SB_VERT, value, true); PostMessageA((IntPtr)this.Handle, WM_VSCROLL, SB_THUMBPOSITION + 0x10000 * value, 0); } } 

I can synchronize RichTextBoxes during keystrokes, up and Vscroll events. This is actually not my goal, I want to synchronize my RichTextBoxes based on the content that I need:

  • Get the current RichTextBox line of the RichTextBox form.
  • Set the scrollbar position using the line number in another RichTextBox (without losing focus from the current one).
  • Get line number using scrollbar position.

Note: you can ask if you need more details.
Thanks in advance.

+7
c # winforms richtextbox scrollbar
source share
1 answer

From what I understand, you need to synchronize scrolling by 2 RichTextBox es based on line number. Leave me a comment if I misunderstood it.

RichTextBox extended:

 public class RichTextBoxEx : RichTextBox { // combination of multiple events that may cause focus(caret) to change public event EventHandler FocusChanged; public RichTextBoxEx() { this.KeyPress += (s, e) => RaiseFocusChanged(); this.KeyDown += (s, e) => RaiseFocusChanged(); this.KeyUp += (s, e) => RaiseFocusChanged(); this.MouseClick += (s, e) => RaiseFocusChanged(); } private void RaiseFocusChanged() { var focusChanged = FocusChanged; if (focusChanged != null) { focusChanged(this, null); } } public int GetFirstSelectedLine() { var index = GetFirstCharIndexOfCurrentLine(); return GetLineFromCharIndex(index); } public int GetFirstVisibleLine() { var index = GetCharIndexFromPosition(new Point(1, 1)); return GetLineFromCharIndex(index); } public void ScrollToLine(int line) { if (line < 0) throw new ArgumentOutOfRangeException("line cannot be less than 0"); // save the current selection to be restored later var selection = new { SelectionStart, SelectionLength }; // select that line and scroll it to Select(GetFirstCharIndexFromLine(line) + 1, 0); ScrollToCaret(); // restore selection Select(selection.SelectionStart, selection.SelectionLength); } } 

Using:

 void Main() { var mainScreenArea = Screen.PrimaryScreen.WorkingArea; var rich1 = new RichTextBoxEx() { Width = mainScreenArea.Width / 2 - 10, Dock = DockStyle.Left }; var rich2 = new RichTextBoxEx() { Width = mainScreenArea.Width / 2 - 10, Dock = DockStyle.Right }; rich1.LoadFile(__RTF_FILE_0__); rich2.LoadFile(__RTF_FILE_1__); // pick one : // synchronize by focus rich1.FocusChanged += (s, e) => rich2.ScrollToLine(rich1.GetFirstSelectedLine()); // synchronize by viewbox // rich1.VScroll += (s, e) => rich2.ScrollToLine(rich1.GetFirstVisibleLine()); var form = new Form(); form.Controls.Add(rich1); form.Controls.Add(rich2); form.WindowState = FormWindowState.Maximized; form.ShowDialog() } 
0
source share

All Articles