Public Class Form1
' Constants and SendMessage function
Const WM_USER As Integer = &H400
Const EM_GETSCROLLPOS As Integer = WM_USER + 221
Const EM_SETSCROLLPOS As Integer = WM_USER + 222
Declare Function SendMessage Lib "user32.dll" Alias "SendMessageW" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, ByRef lParam As Point) As Integer
' Scrollpositions of rtb1 and rtb2
Dim ptScrollPos_RTB1, ptScrollPos_RTB2 As Point
' Wether the scroll was made by the user (false) or by the synched scrolling function (true)
Dim blnScrolled_RTB1, blnScrolled_RTB2 As Boolean
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Load the RTB's with textfile
Dim strFilePath As String = ""
Using ofd As New OpenFileDialog With {.Filter = "Text files (*.txt)|*.txt|All files|*.*", .Title = "Open text file"}
If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then
strFilePath = ofd.FileName
RTB1.LoadFile(strFilePath, RichTextBoxStreamType.PlainText)
RTB2.LoadFile(strFilePath, RichTextBoxStreamType.PlainText)
Else
MessageBox.Show("You are encouraged to load a large file.", "Choose file", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
End Using
' Set the default scrollposition of RTB's
SendMessage(RTB1.Handle, EM_GETSCROLLPOS, 0, ptScrollPos_RTB1)
SendMessage(RTB2.Handle, EM_GETSCROLLPOS, 0, ptScrollPos_RTB2)
End Sub
Private Sub RTB1_VScroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RTB1.VScroll
' Do not continue if the scroll was made by this program and not by the user (to prevent endless loops)
If blnScrolled_RTB2 Then Exit Sub
' Set a flag so RTB2 knows it is scrolled by RTB1 and not by the user
blnScrolled_RTB1 = True
Dim diff As Integer
' Check scrollposition after scrolling
Dim pt As Point
SendMessage(RTB1.Handle, EM_GETSCROLLPOS, 0, pt)
' Compare Y-value (height) with scrollposition before scrolling
diff = pt.Y - ptScrollPos_RTB1.Y
' Set RTB1 scrollposition variable to new scrollposition
ptScrollPos_RTB1 = pt
' Only sync scrolling when checkbox is checked
If chk.Checked Then
' Get RTB2 scrollposition
Dim pt2 As Point
SendMessage(RTB2.Handle, EM_GETSCROLLPOS, 0, pt2)
' Set RTB2 scrollpos Y (height) to old scrollposition + the difference in RTB1 scrollposition
SendMessage(RTB2.Handle, EM_SETSCROLLPOS, 0, New Point(pt.X, diff + pt2.Y))
End If
' Re-Set the flag
blnScrolled_RTB1 = False
End Sub
Private Sub RTB2_VScroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RTB2.VScroll
' Do not continue if the scroll was made by this program and not by the user (to prevent endless loops)
If blnScrolled_RTB1 Then Exit Sub
' Set a flag so RTB1 knows it is scrolled by RTB2 and not by the user
blnScrolled_RTB2 = True
Dim diff As Integer
' Check scrollposition after scrolling
Dim pt As Point
SendMessage(RTB2.Handle, EM_GETSCROLLPOS, 0, pt)
' Compare Y-value (height) with scrollposition before scrolling
diff = pt.Y - ptScrollPos_RTB2.Y
' Set RTB2 scrollposition variable to new scrollposition
ptScrollPos_RTB2 = pt
' Only sync scrolling if checkbox is checked
If chk.Checked Then
' Get RTB1 scrollposition
Dim pt2 As Point
SendMessage(RTB1.Handle, EM_GETSCROLLPOS, 0, pt2)
' Set RTB2 scrollpos Y (height) to old scrollposition + the difference in RTB2 scrollposition
SendMessage(RTB1.Handle, EM_SETSCROLLPOS, 0, New Point(pt.X, diff + pt2.Y))
End If
' Re-Set the flag
blnScrolled_RTB2 = False
End Sub
End Class