Audes
@Audes

Как синхронизировать положение ползунков полос прокрутки в двух RichTextBox?

Имеется два RichTextBox, нужно установить значение текущего вертикального скролла первого, как в данный момент у второго. Пробовал всякие offset, копался в гугле, но ничего внятного не нашел.
  • Вопрос задан
  • 3125 просмотров
Решения вопроса 1
AlekseyNemiro
@AlekseyNemiro
full-stack developer
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;
    }
  }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы