非IT企業に勤める中年サラリーマンのIT日記

非IT企業でしかもITとは全く関係ない部署にいる中年エンジニア。唯一の趣味がプログラミングという”自称”プログラマー。

C#:テキストボックスのスクロール位置を取得・復元する方法

   

C#でTextBoxやRichTextBoxでスクロール位置を取得したり指定位置に移動したい場合、それに対応したプロパティやメソッドはありません。

スクロールを制御する場合は、WindowsAPIを使う必要があります。

広告

まずは今回紹介するプログラムの動作説明

FormにRichTextBoxを貼り付けています。行ごとに番号を入力しているのはあくまで手打ちです。外観はこんな感じ。

 

スクロールを適当なところに持って行って(下の例は中央あたり)、「Ctrl」+「A」を押します。

 

すると、メッセージボックスが現れます。数値はスクロールバーの縦位置になります。つまり、スクロールバーの位置を取得できたってわけですね。まずここがWindowsAPIで取得しています。

 

そこから、スクロールを適当な場所に移動します。そして今度は「Ctrl」+「B」を押します。

 

先ほど、「Ctrl」+「A」を押したところに戻り、メッセージボックスでそこの位置がまた表示されます。スクロール位置が復元できました。これもWindowsAPIで制御。

 

…という感じのプログラムです。次はソースコードです。

ソースコード

こちらがソースコードです。これをコピペしてコンパイルすれば上記で説明したものができます。

using System;
using System.Drawing;
using System.Windows.Forms;

class EditorTest{
  static void Main(string[] args){
    Application.Run(new MainWindow(args));
  }
}

class MainWindow : Form{
  private RichTextBox textBox;
  private Point pos;

  [System.Runtime.InteropServices.DllImport("USER32.dll")]
  private static extern IntPtr SendMessage(System.IntPtr hWnd, Int32 Msg, Int32 wParam, ref Point lParam);

  public MainWindow(string[] args){
    this.StartPosition = FormStartPosition.CenterScreen;
    this.Width = 500;
    this.Height =400;
    this.Text = "テキストボックステスト";
    pos = new Point(0, 0);

    textBox = new RichTextBox(){
      Dock = DockStyle.Fill,
      Font = new Font("MS ゴシック", 14),
      Parent=this,
    };
    textBox.KeyDown += new KeyEventHandler(keyDowned);
  }

  private void keyDowned(object sender, KeyEventArgs e){
    if(e.KeyCode == Keys.A && e.Control){
      // スクロール位置を取得
      SendMessage(this.textBox.Handle, 0x04DD, 0, ref pos);
      MessageBox.Show(pos.Y+"");
    }

    if(e.KeyCode == Keys.B && e.Control){
      // 指定のスクロール位置を復元
      SendMessage(this.textBox.Handle, 0x04DE, 0, ref pos);
      MessageBox.Show(pos.Y+"");
    }
  }
}
 

 

解説

まず、ソース全文の15, 16行目にあるこの2行で、関連するDLLファイルを呼び出しています。

[System.Runtime.InteropServices.DllImport("USER32.dll")]
private static extern IntPtr SendMessage(System.IntPtr hWnd, Int32 Msg, Int32 wParam, ref Point lParam);
 

 

で、33行目以降で「Ctrl」+「A」でスクロール位置を取得、「Ctrl」+「B」でスクロール位置を復元しているわけです。

private void keyDowned(object sender, KeyEventArgs e){
  if(e.KeyCode == Keys.A && e.Control){
    // スクロール位置を取得
    SendMessage(this.textBox.Handle, 0x04DD, 0, ref pos);
    MessageBox.Show(pos.Y+"");
  }

  if(e.KeyCode == Keys.B && e.Control){
    // 指定のスクロール位置を復元
    SendMessage(this.textBox.Handle, 0x04DE, 0, ref pos);
    MessageBox.Show(pos.Y+"");
  }
}
 

 

スクロール位置の制御ぐらい標準のプロパティかメソッドで可能にしてほしいですね…。

 

広告

 - C#応用編