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 WindowsFormsApplication9
{
public partial class Form1 : Form
{
/// <summary>
/// Получает текущее положение ползунка полосы прокрутки.
/// </summary>
/// <param name="hWnd">Дескриптор.</param>
/// <param name="nBar">Тип.</param>
/// <returns></returns>
[DllImport("User32.dll")]
public extern static int GetScrollPos(IntPtr hWnd, int nBar);
/// <summary>
/// Функция для отправки сообщений.
/// </summary>
/// <param name="hWnd">Дескриптор.</param>
/// <param name="msg">Само сообщение.</param>
/// <param name="wParam">Параметры.</param>
/// <param name="lParam">Дополнительные параметры.</param>
[DllImport("User32.dll")]
public extern static int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
public enum ScrollBarType : uint
{
SbHorz = 0,
SbVert = 1,
SbCtl = 2,
SbBoth = 3
}
public enum Message : uint
{
/// <summary>
/// Сообщение для вертикальной полосы прокрутки
/// </summary>
WM_VSCROLL = 0x0115
}
public enum ScrollBarCommands : uint
{
/// <summary>
/// Положение ползунка полосы прокрутки в конце операции
/// </summary>
SB_THUMBPOSITION = 4
}
private RichTextBox rich1 = new RichTextBox();
private RichTextBox rich2 = new RichTextBox();
public Form1()
{
InitializeComponent();
// тестовый текст
string text = "";
for (int i = 0; i < 99; i++)
{
text += "Имеется 2 richTextBox, нужно установить значение текущего вертикального скролла первого, как у в данный момент у второго. Пробовал всякие offset, копался в гугле, но ничего внятного не нашел.\r\n";
}
// добавляем поля на форму
rich1.Name = "rich1";
rich1.Dock = DockStyle.Top;
rich1.Text = text;
rich1.VScroll += rich_VScroll;
this.Controls.Add(rich1);
rich2.Name = "rich2";
rich2.Dock = DockStyle.Top;
rich2.Text = text;
rich2.VScroll += rich_VScroll;
this.Controls.Add(rich2);
}
/// <summary>
/// Обработчик изменения положения ползунка полосы прокрутки.
/// </summary>
private void rich_VScroll(object sender, EventArgs e)
{
// кто вызвал событие
RichTextBox currentRich = (RichTextBox)sender;
// если событие вызвал rich2, то второй будет rich1 и наоборот
RichTextBox otherRich = currentRich.Name.Equals("rich1") ? rich2 : rich1;
// получаем позицию ползунка полосы прокрутки текущего поля
int pos = GetScrollPos(currentRich.Handle, (int)ScrollBarType.SbVert);
pos <<= 16;
// чтобы не застрять в бесконечности
// (можно так не делать и прикрутить обработчик только к одному полю)
otherRich.VScroll -= rich_VScroll;
// --
// передаем позицию во второе поле
uint par = (uint)ScrollBarCommands.SB_THUMBPOSITION | (uint)pos;
SendMessage(otherRich.Handle, (int)Message.WM_VSCROLL, new IntPtr(par), new IntPtr(0));
otherRich.VScroll += rich_VScroll;
}
}
}