Rich Text Boxで最終行までScrollされたことを検知する

財務が見え~るは、シェアウェアです。
認証パスワードを入力してもらうのですが、そのとき利用規約を最後までスクロールすると、実際に読んでもらったかどうかは別として(笑)上記規約に同意する・・といったチェックボックスが活性化し、そこをチェックすると初めてパスワード入力が可能になる。
よく見かけるそんな仕様を考えました。
c#では(てか.Net)では、なぜかText Box・Rich Text BoxともにScrollバーの動きを捉えることができず、Win APIをかませないとできない との記述が 色々なサイトに書いています。実装方法も色々載っているのですが、私の理解不足か、スンナリとはいきませんでした。
うまくいったのがここ、クラスライブラリを作って実装しました。参考までにソースを掲載します。

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;

namespace nobotta
{
  public class RTFScrolledBottom : RichTextBox
  {
    public event EventHandler ScrolledToBottom;

    private const int WM_VSCROLL = 0x115;
    private const int WM_MOUSEWHEEL = 0x20A;
    private const int WM_USER = 0x400;
    private const int SB_VERT = 1;
    private const int EM_SETSCROLLPOS = WM_USER + 222;
    private const int EM_GETSCROLLPOS = WM_USER + 221;

    [DllImport("user32.dll")]
    private static extern bool GetScrollRange(IntPtr hWnd, int nBar, out int lpMinPos, out int lpMaxPos);

    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, Int32 wMsg, Int32 wParam, ref Point lParam);

    public bool IsAtMaxScroll()
    {
      int minScroll;
      int maxScroll;
      GetScrollRange(this.Handle, SB_VERT, out minScroll, out maxScroll);
      Point rtfPoint = Point.Empty;
      SendMessage(this.Handle, EM_GETSCROLLPOS, 0, ref rtfPoint);

      return (rtfPoint.Y + this.ClientSize.Height >= maxScroll);
    }

    protected virtual void OnScrolledToBottom(EventArgs e)
    {
      if (ScrolledToBottom != null)
          ScrolledToBottom(this, e);
    }

    protected override void OnKeyUp(KeyEventArgs e)
    {
      if (IsAtMaxScroll())
          OnScrolledToBottom(EventArgs.Empty);
      base.OnKeyUp(e);
    }

    protected override void WndProc(ref Message m)
    {
      if (m.Msg == WM_VSCROLL || m.Msg == WM_MOUSEWHEEL)
      {
        if (IsAtMaxScroll())
          OnScrolledToBottom(EventArgs.Empty);
      }
      base.WndProc(ref m);
    }
  }
}
スポンサーリンク
Rectangle大広告
Rectangle大広告

シェアする

  • このエントリーをはてなブックマークに追加

フォローする