2009-08-19 23 views
17

MultiLine = trueAcceptsTab == trueのWinForms TextBoxコントロールを使用すると、表示されるタブ文字の幅はどのように設定できますか?WindowsフォームのTextBoxコントロールでTAB幅を設定する方法は?

これは、プラグインのための迅速で汚れたスクリプト入力ボックスとして使用したいと思います。これは、中に呼び出すことができ

// set tab stops to a width of 4 
private const int EM_SETTABSTOPS = 0x00CB; 

[DllImport("User32.dll", CharSet = CharSet.Auto)] 
public static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam); 

public static void SetTabWidth(TextBox textbox, int tabWidth) 
{ 
    Graphics graphics = textbox.CreateGraphics(); 
    var characterWidth = (int)graphics.MeasureString("M", textbox.Font).Width; 
    SendMessage(textbox.Handle, EM_SETTABSTOPS, 1, 
       new int[] { tabWidth * characterWidth }); 
} 

:受け入れ答えから

...それは本当に全くの空想である必要はありませんが、タブは8つの文字幅として表示されていない場合、それはいいだろうFormのコンストラクタですが、最初にInitializeComponentsが実行されていることを確認してください。

+1

グラフィックスも同様に廃棄してください。おそらくステートメントを使用して配置してください。 –

答えて

11

テキストボックスにEM_SETTABSTOPSメッセージを送信するとうまくいくと思います。

+0

MSDNリンクはWindows CE用です。私はそれを変えた。 – SLaks

7

私はあなたが現在TextBoxを使用している知っているが、あなたはRichTextBoxを使用して逃げることができる場合代わりにSelectedTabsプロパティを使用して、目的のタブ幅を設定することができます。

richTextBox.SelectionTabs = new int[] { 15, 30, 45, 60, 75}; 

これらのオフセットはピクセルであり、文字ではありません。

5

提供されている例が正しくありません。

メッセージのEM_SETTABSTOPSは、タブサイズがdialog template unitsであり、ピクセルではないと予想しています。いくらか掘り下げた後、ダイアログテンプレートユニットは1/4th the average width of the window's characterに等しいと思われる。したがって、2文字の長さのタブに8、4文字に16などを指定する必要があります。

ので、コードのように単純化することができる:拡張メソッドを使用すると

public static void SetTabWidth(TextBox textbox, int tabWidth) 
{ 
    SendMessage(textbox.Handle, EM_SETTABSTOPS, 1, 
      new int[] { tabWidth * 4 }); 
} 
+0

ありがとう、ロリス、私はこれを知らなかった。 –

6

、あなたはTextBoxコントロールのクラスに新しいメソッドを追加することができます。私は、別のタブ幅をしたい人のために

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

namespace Extensions 
{ 
    public static class TextBoxExtension 
    { 
     private const int EM_SETTABSTOPS = 0x00CB; 

     [DllImport("User32.dll", CharSet = CharSet.Auto)] 
     private static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam); 

     public static Point GetCaretPosition(this TextBox textBox) 
     { 
      Point point = new Point(0, 0); 

      if (textBox.Focused) 
      { 
       point.X = textBox.SelectionStart - textBox.GetFirstCharIndexOfCurrentLine() + 1; 
       point.Y = textBox.GetLineFromCharIndex(textBox.SelectionStart) + 1; 
      } 

      return point; 
     } 

     public static void SetTabStopWidth(this TextBox textbox, int width) 
     { 
      SendMessage(textbox.Handle, EM_SETTABSTOPS, 1, new int[] { width * 4 }); 
     } 
    } 
} 
+0

ありがとう!これは本当にクールです! –

+0

よろしくお願いします!実際、TextBoxがMultilineとAcceptsTabであることを確認するために、独自のコードチェックに追加したさらに洗練された機能が有効になっています。 –

+0

ありがとう、Brien、それはこの機能をカプセル化する非常に良い方法です! – BillW

1

:これは私が上記以前の貢献者から集められたものから、(あなたに挿入キャレットの現在の位置の座標を与える追加の拡張メソッドを含む)私の実装です

using System.Runtime.InteropServices; 

[DllImport("User32.dll", CharSet = CharSet.Auto)] 
private static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, uint[] lParam); 
private const int EM_SETTABSTOPS = 0x00CB; 

private void InitialiseTabStops() 
{ 
    // Declare relative tab stops in character widths 
    var tabs = new uint[] { 2, 2, 4, 8, 2, 32 }; 

    // Convert from character width to 1/4 character width 
    for (int position = 0; position < tabs.Length; position++) 
     tabs[position] *= 4; 

    // Convert from relative to absolute positions 
    for (int position = 1; position < tabs.Length; position++) 
     tabs[position] += tabs[position - 1]; 

    SendMessage(textBox.Handle, EM_SETTABSTOPS, tabs.Length, tabs); 
} 
関連する問題