I'm able now to synchronize my two RichTextBox
using this potion of 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 the RichTextBoxes
while key down ,up and Vscroll
event.
Indeed this is not my goal, I want to synchronize my RichTextBoxes
basing on the content,
What do I need:
RichTextBox
.RichTextBox
(without losing the focus from the current one).Note: you are welcome to ask if you need any more details.
Thanks in advance.
From what I understand, you need to synchronize scrolling on 2 RichTextBox
es based on the 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);
}
}
Usage :
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()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With