TextBox(またはRichTextBox)の現在のカレット位置(行と列)を取得するテキストボックス(またはリッチテキストボックス)内で現在カレットのある行と列を取得する方法です。 理論的に行を数える行を理論的に数える場合(WordWrapがTrueで、右側で折り返されていても一行として数える)は、次のように計算できます。ここでは、テキストボックス"TextBox1"の現在のカレットの位置を計算しています。 [VB.NET] '文字列 Dim str As String = TextBox1.Text 'カレットの位置を取得 Dim selectPos As Integer = TextBox1.SelectionStart 'カレットの位置までの行を数える Dim row As Integer = 1 Dim startPos As Integer = 0 Dim endPos As Integer While (True) endPos = str.IndexOf(vbLf, startPos) If (endPos < 0 Or endPos >= selectPos) Then Exit While End If startPos = endPos + 1 row += 1 End While '列の計算 Dim col As Integer = selectPos - startPos + 1 '結果を表示 Console.WriteLine("行:{0} 列:{1}", row, col) [C#] //文字列 string str = TextBox1.Text; //カレットの位置を取得 int selectPos = TextBox1.SelectionStart; //カレットの位置までの行を数える int row = 1, startPos = 0; for (int endPos = 0; (endPos = str.IndexOf('\n', startPos)) < selectPos && endPos > -1; row++) { startPos = endPos + 1; } //列の計算 int col = selectPos - startPos + 1; //結果を表示 Console.WriteLine("行:{0} 列:{1}", row, col); 物理的に行を数える行を物理的に数える場合(WordWrapがTrueで、右側で折り返されていれば2行として数える)は、SendMessage関数を使用して取得します。 次の例では、Button1をクリックすることにより、物理的な現在のカレットの位置を表示しています。
[VB.NET]
<System.Runtime.InteropServices.DllImport("User32.Dll")> _
Private Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer) As Integer
End Function
Private Const EM_LINEINDEX As Integer = &HBB
Private Const EM_LINEFROMCHAR As Integer = &HC9
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'現在の行を取得する
Dim row As Integer = SendMessage( _
TextBox1.Handle, EM_LINEFROMCHAR, -1, 0) + 1
'現在の列を取得する
Dim lineIndex As Integer = SendMessage( _
TextBox1.Handle, EM_LINEINDEX, -1, 0)
Dim col As Integer = TextBox1.SelectionStart - lineIndex + 1
Console.WriteLine("行:{0} 列:{1}", row, col)
End Sub
[C#]
[System.Runtime.InteropServices.DllImport("User32.Dll")]
private static extern int SendMessage(
IntPtr hWnd,int Msg,int wParam,int lParam);
private const int EM_LINEINDEX = 0xBB;
private const int EM_LINEFROMCHAR=0xC9;
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArgs e)
{
//現在の行を取得する
int row = SendMessage(
TextBox1.Handle, EM_LINEFROMCHAR, -1, 0) + 1;
//現在の列を取得する
int lineIndex = SendMessage(
TextBox1.Handle, EM_LINEINDEX, -1, 0);
int col = TextBox1.SelectionStart - lineIndex + 1;
Console.WriteLine("行:{0} 列:{1}", row, col);
}
RichTextBoxまたは、.NET Framework 2.0以降の場合RichTextBoxの物理的な行は、GetLineFromCharIndexメソッドで取得できます。GetLineFromCharIndexメソッドは、.NET Framework 2.0からは、TextBox(TextBoxBase)クラスにも追加されました。 GetLineFromCharIndexメソッドは、1行目を「0」とします。
[VB.NET]
'RichTextBox1の現在の物理行を表示する
Console.WriteLine(
RichTextBox1.GetLineFromCharIndex(RichTextBox1.SelectionStart))
[C#]
//RichTextBox1の現在の物理行を表示する
Console.WriteLine(
RichTextBox1.GetLineFromCharIndex(RichTextBox1.SelectionStart));
しかしこの方法では、自動的に折り返されている行の一番最後にカレットがあるときは、次の行の番号を返してしまいます。
(この記事は、「.NETプログラミング研究 第51号」で紹介したものを基にしています。) 注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。
|
|
Copyright 2002-2008 DOBON!. All rights reserved.
|