TextBoxのタブ幅を変更する - C#

テキストボックスのタブ幅を変更する方法を紹介します。

UI

以下のUIを作成します。TextBoxを1つButtonを1つ配置します。TextBoxのAcceptTabプロパティをTrueに設定します。

コード

以下のコードを記述します。
方法1、方法2どちらでも同じ実行結果になります。

コード 方法1

SendMessage Windows APIのlparam, wparamをIntPtrで定義した場合の例です。
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 ChangeTabWidth
{
  public partial class FormMain : Form
  {
    const int EM_SETTABSTOPS = 0x00CB;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    public FormMain()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      int[] tabarray = new int[] { 96,8,32 };
      int wparam = tabarray.Length;
            
      IntPtr parray = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)) * tabarray.Length);
      Marshal.Copy(tabarray, 0, parray, tabarray.Length);
      IntPtr ret = SendMessage(textBox1.Handle, EM_SETTABSTOPS, new IntPtr(wparam),parray);
    }
  }
}

解説

  int[] tabarray = new int[] { 96,8,32 };
  int wparam = tabarray.Length;
タブ幅を設定するための配列を作成します。上記の例では最初のタブ幅が96, 2番目のタブ幅が8, 3番目のタブ幅が32となります。合わせてタブ幅を設定する配列の長さを取得します。

  IntPtr parray = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)) * tabarray.Length);
  Marshal.Copy(tabarray, 0, parray, tabarray.Length);
SendMessage Windows APIには配列のIntPtrを渡す必要があるため、配列と同じデータを持つIntPtrを作成します。Marshal.AllocCoTaskMemメソッドで配列の値を格納できるだけのサイズを確保します。サイズの確保ができた後、Marshal.Copy()メソッドを呼び出し、配列のデータをIntPtrのメモリにコピーします。

  IntPtr ret = SendMessage(textBox1.Handle, EM_SETTABSTOPS, new IntPtr(wparam),parray);
EM_SETTABSTOPSウィンドウメッセージをtextBox1に送信します。wparamにはタブ幅の配列のサイズを与えます。lparamにはタブ幅の配列を示すIntPtrを与えます。

コード 方法2

SendMessage Windows APIのlparamをint, wparamをint[]で定義した場合の例です。
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 ChangeTabWidth
{
  public partial class FormMain : Form
  {
    const int EM_SETTABSTOPS = 0x00CB;

    [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
    static extern IntPtr SendMessageAR(IntPtr hWnd, UInt32 Msg, int wParam, int[] lParam);

    public FormMain()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      int[] tabarray = new int[] { 96,8,32 };
      int wparam = tabarray.Length;
            
      SendMessageAR(textBox1.Handle, EM_SETTABSTOPS, wparam, tabarray);
    }
  }
}

解説

  int[] tabarray = new int[] { 96,8,32 };
  int wparam = tabarray.Length;
タブ幅を設定するための配列を作成します。上記の例では最初のタブ幅が96, 2番目のタブ幅が8, 3番目のタブ幅が32となります。合わせてタブ幅を設定する配列の長さを取得します。

  SendMessageAR(textBox1.Handle, EM_SETTABSTOPS, wparam, tabarray);
EM_SETTABSTOPSウィンドウメッセージをtextBox1に送信します。wparamにはタブ幅の配列のサイズを与えます。lparamにはタブ幅の配列を与えます。

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


文字を入力します。"Owl\tDuck\tPenguin\tPigion"を入力しました。下図の状態となります。


いったんテキストボックスをすべてクリアし、button1を押したのち、同じ文字を入力します。button1を押すことでタブ幅が変更されるため、下図の結果となります。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2012-07-12
iPentec all rights reserverd.