| ■No87050 (ak さん) に返信 > 先頭行から最終行位置までのバイト計算では、 バイト計算せずに実装することもできますよ。 後述のコードを参考にしてみてください。
ちなみに SelLength プロパティは &H0000&〜&HFFFF& の範囲しか渡せないので、 本文が長くなってくると txtBox.SelStart = Len(txtBox.Text) '65536 以上になるとエラー すら実行できなくなりますのでご注意ください。
■No87023 (魔界の仮面弁士) の訂正 > EM_LINELENGTH の戻り値や EM_GETLINE に渡すバッファは TCHAR 単位なので、 > A 系では「バイト数」、W 系では「文字数」で扱います。 SendMessageA / SendMessageW の違いというわけでは無さそうですね。 手元の環境では、SendMessageA / SendMessageW のいずれを使ったとしても、 VB6 の TextBox に対して送出した場合は バイト単位 VB.NET の TextBox に対して送出した場合は文字数単位となりました。
ということで、SelStart / SelLength プロパティ(文字数単位)のかわりに EM_SETSEL を使って選択する方法に切り替えてみました。 SelStart と違って 65535 文字を超えても大丈夫です。
Option Explicit Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hWnd As OLE_HANDLE, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Const EM_SETSEL As Long = &HB1& Private Const EM_LINEINDEX As Long = &HBB& Private Const EM_LINELENGTH As Long = &HC1& Private Const EM_SCROLLCARET As Long = &HB7&
'TextBox の指定行を選択状態にします ' txtBox : 処理対象の TextBox ' lineNo : 選択する行番号(1〜) ' autoScroll : 選択したあと、その場所までスクロールさせて表示するかどうか ' reverseSelect : True=行末から行頭に選択、False=行頭から行末に選択 Friend Sub SelectLine(ByVal txtBox As TextBox, ByVal lineNo As Long, Optional autoScroll As Boolean = True, Optional reverseSelect As Boolean = True) Dim fromPos As Long, toPos As Long
Dim lineIndex As Long lineIndex = SendMessage(txtBox.hWnd, EM_LINEINDEX, lineNo - 1, 0&) If lineIndex < 0& Then fromPos = &H7FFFFFFF toPos = &H7FFFFFFF Else Dim lineLength As Long lineLength = SendMessage(txtBox.hWnd, EM_LINELENGTH, lineIndex, 0&) If reverseSelect Then fromPos = lineIndex + lineLength toPos = lineIndex Else fromPos = lineIndex toPos = lineIndex + lineLength End If End If SendMessage txtBox.hWnd, EM_SETSEL, fromPos, toPos If autoScroll Then SendMessage txtBox.hWnd, EM_SCROLLCARET, 0&, 0& End If
On Error Resume Next txtBox.SetFocus 'Visible や Enabled が False だと実行時エラー End Sub
引数の「ByVal txtBox As TextBox」を「ByVal txtBox As RichTextBox」に置き換えれば、 そのまま RichTextBox 版にもなります。 |