テキストの整形関係のメニューは、ExpandedTextControlクラスをつくった時とほぼ同じ内容になります。変換メニューだけがこちらだけの機能となっています。横着して一つの関数で処理しています。
' 編集メニュー : 元に戻す
Private Sub mnUndo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles mnUndo.Click
If Not IsNothing(TC1.SelectedTab) Then
With DirectCast(TC1.SelectedTab, TextPage).EditBox
.Undo()
.ClearUndo()
End With
End If
End Sub
' 編集メニュー : 切り取り
Private Sub mnCut_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles mnCut.Click
If Not IsNothing(TC1.SelectedTab) Then
DirectCast(TC1.SelectedTab, TextPage).EditBox.Cut()
End If
End Sub
' 編集メニュー : コピー
Private Sub mnCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles mnCopy.Click
If Not IsNothing(TC1.SelectedTab) Then
DirectCast(TC1.SelectedTab, TextPage).EditBox.Copy()
End If
End Sub
' 編集メニュー : 貼り付け
Private Sub mnPaste_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles mnPaste.Click
If Not IsNothing(TC1.SelectedTab) Then
DirectCast(TC1.SelectedTab, TextPage).EditBox.Paste()
End If
End Sub
' 編集メニュー : 削除
Private Sub mnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles mnDelete.Click
If Not IsNothing(TC1.SelectedTab) Then
DirectCast(TC1.SelectedTab, TextPage).EditBox.SelectedText = ""
End If
End Sub
' 編集メニュー : すべて選択
Private Sub mnSelectAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles mnSelectAll.Click
If Not IsNothing(TC1.SelectedTab) Then
DirectCast(TC1.SelectedTab, TextPage).EditBox.SelectAll()
End If
End Sub
' 編集メニュー : 変換
Private Sub mnCUpper_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles mnCUpper.Click, mnCLower.Click, mnCProper.Click, _
mnCWide.Click, mnCNarrow.Click, mnCHira.Click, mnCKata.Click
Dim nIndex As Integer = DirectCast(sender, MenuItem).Index ' メニュー番号
Dim ctrEdit As ExpandedTextControl = DirectCast(TC1.SelectedTab, TextPage).EditBox
Dim nStrConv As VbStrConv = VbStrConv.None ' 変換方法
Select Case nIndex
Case 0 : nStrConv = VbStrConv.UpperCase ' 大文字変換
Case 1 : nStrConv = VbStrConv.LowerCase ' 小文字変換
Case 2 : nStrConv = VbStrConv.ProperCase ' プロパー変換
Case 3 : nStrConv = VbStrConv.Wide ' 全角変換
Case 4 : nStrConv = VbStrConv.Narrow ' 半角変換
Case 5 : nStrConv = VbStrConv.Hiragana ' ひらがな変換
Case 6 : nStrConv = VbStrConv.Katakana ' カタカナ変換
End Select
' 選択部分のテキストを入れ替え
ctrEdit.SelectedText = StrConv(ctrEdit.SelectedText, nStrConv)
End Sub
指定した行への移動はダイアログボックスを使います。ダイアログボックスを開いて、取得した値に基づいて行を移動させています。諸関数はリッチテキストの章で設定したオリジナルのものも含まれます。ダイアログボックスについては次の項を参照してください。
' 編集メニュー : 指定行へ移動
Private Sub miJump_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles mnJump.Click
Dim ctrEdit As ExpandedTextControl = DirectCast(TC1.SelectedTab, TextPage).EditBox
Dim nMax As Integer = ctrEdit.GetLineCount ' 行数
Dim d As New NumericDialog("指定行へ移動", "行目へ移動(全" & nMax.ToString & "行)")
Try
Dim nLine, nChar As Integer
nChar = ctrEdit.SelectionStart ' 現在の文字の位置
nLine = ctrEdit.GetLineIndex(nChar) ' nCharがある行の位置
d.SetValues(ctrEdit.GetLineCount, 1, nLine + 1) 'ダイアログにデータをセット
If d.ShowDialog(Me) = DialogResult.OK Then
ctrEdit.ScrollToLine(d.Value - 1) ' キャレットを移動
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "行指定エラー", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
d.Dispose()
End Try
End Sub

数値指定ダイアログは、手抜きをして他のメニューでも使い回しができるようにつくります。コンストラクタでタイトルと説明文字列を設定して、"SetValues"関数で上限値や下限値を指定するようにします。例によってデザイナを使っていませんので、記述が長めになっています。
Public Class NumericDialog
Inherits System.Windows.Forms.Form
' 変数
WithEvents lb1 As System.Windows.Forms.Label ' 説明表示用ラベル
WithEvents en1 As System.Windows.Forms.TextBox ' 入力用テキストボックス
WithEvents bnOK As System.Windows.Forms.Button ' OKボタン
WithEvents bnCancel As System.Windows.Forms.Button ' キャンセルボタン
Private m_notes As String = "" ' 単位の説明の文字列
Private m_value As Integer = 0 ' 設定した値
Private m_max As Integer = Integer.MaxValue ' 入力の上限値
Private m_min As Integer = Integer.MinValue ' 入力の下限値
' プロパティ
Public Property Notes() As String
Get
Return m_notes
End Get
Set(ByVal Value As String)
m_notes = Value
End Set
End Property
Public Property Value() As Integer
Get
Return m_value
End Get
Set(ByVal Value As Integer)
m_value = Value
End Set
End Property
Public Property MaxValue() As Integer
Get
Return m_max
End Get
Set(ByVal Value As Integer)
m_max = Value
End Set
End Property
Public Property MinValue() As Integer
Get
Return m_min
End Get
Set(ByVal Value As Integer)
m_min = Value
End Set
End Property
' New コンストラクタ
' ... 引数caption : ダイアログのタイトル
' ... 引数notes : 説明表示用文字列
Public Sub New(ByVal caption As String, ByVal notes As String)
MyBase.New()
InitializeControls()
Me.Text = caption
m_notes = notes
End Sub
' InitializeControls : コントロールの初期化
Private Sub InitializeControls()
Me.lb1 = New System.Windows.Forms.Label()
Me.en1 = New System.Windows.Forms.TextBox()
Me.bnOK = New System.Windows.Forms.Button()
Me.bnCancel = New System.Windows.Forms.Button()
Me.SuspendLayout()
With lb1
.Name = "lb1"
.Location = New System.Drawing.Point(62, 8)
.Size = New System.Drawing.Size(148, 20)
.TabIndex = 0
.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
End With
With en1
.Name = "en1"
.Location = New System.Drawing.Point(8, 8)
.Size = New System.Drawing.Size(52, 19)
.TabIndex = 1
.Text = ""
.TextAlign = HorizontalAlignment.Center
End With
With bnOK
.Name = "bnOK"
.FlatStyle = FlatStyle.System
.Location = New System.Drawing.Point(196, 8)
.Size = New System.Drawing.Size(72, 22)
.TabIndex = 2
.Text = "OK"
End With
With bnCancel
.Name = "bnCancel"
.FlatStyle = FlatStyle.System
.Location = New System.Drawing.Point(196, 36)
.Size = New System.Drawing.Size(72, 22)
.TabIndex = 3
.Text = "キャンセル"
End With
Me.AutoScaleBaseSize = New Size(5, 12)
Me.ClientSize = New Size(278, 64)
Me.Controls.AddRange(New Control() {Me.bnCancel, Me.bnOK, Me.en1, Me.lb1})
Me.FormBorderStyle = FormBorderStyle.FixedToolWindow
Me.Name = "NumericDialog"
Me.StartPosition = FormStartPosition.CenterParent
Me.AcceptButton = bnOK
Me.CancelButton = bnCancel
Me.Text = "数値の指定"
Me.ResumeLayout(False)
End Sub
' ロード
Private Sub Dialog_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
lb1.Text = m_notes
With en1
.Text = m_value.ToString
.MaxLength = 11
.ImeMode = ImeMode.NoControl
.Focus()
End With
bnOK.CausesValidation = True
End Sub
' 値を設定
' ... 引数max : 入力の上限値
' ... 引数min : 入力の下限値
' ... 引数current : 現在の値
Public Sub SetValues(ByVal max As Integer, ByVal min As Integer, ByVal current As Integer)
m_max = max
m_min = min
m_value = current
End Sub
' OKボタン
Private Sub bnOK_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles bnOK.Click
Dim msg As String = ""
If IsNumeric(en1.Text) Then
Dim nValue As Integer = CInt(en1.Text)
If nValue < m_min Or nValue > m_max Then
msg = "範囲外の値です。(範囲 :" & m_min & "〜" & m_max & ")"
MessageBox.Show(msg, "入力エラー", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
en1.Focus()
en1.SelectAll()
Else
m_value = nValue
Me.DialogResult = DialogResult.OK
End If
Else
msg = "整数の値を入力してください。"
MessageBox.Show(msg, "入力エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
en1.Focus()
en1.SelectAll()
End If
End Sub
' キャンセルボタン
Private Sub bnCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles bnCancel.Click
Me.DialogResult = DialogResult.Cancel
End Sub
End Class
編集メニューの使用可・不可の切り替えをコーディングします。「検索・置換」メニューと「すべて選択」メニューは、テキストを取得する必要がありますが、textプロパティやlinesプロパティで取得するとアンドゥデータが消えてしまうので、Win32APIの力を借りて実現しています。第3章でつくった関数で対応しています。
' 編集メニュー
Private Sub mnEdit_Select(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles mnEdit.Select
Dim p As TextPage = DirectCast(TC1.SelectedTab, TextPage)
If Not IsNothing(p) Then
Dim nLineCount As Integer = p.EditBox.GetLineCount
Dim nLineLength As Integer = p.EditBox.GetLineLength(0)
mnUndo.Enabled = p.EditBox.CanUndo
mnCut.Enabled = Not p.EditBox.SelectedText.Equals("")
mnCopy.Enabled = Not p.EditBox.SelectedText.Equals("")
mnPaste.Enabled = Clipboard.GetDataObject.GetDataPresent(DataFormats.Text) _
OrElse Clipboard.GetDataObject.GetDataPresent(DataFormats.Rtf)
mnDelete.Enabled = Not p.EditBox.SelectedText.Equals("")
mnFind.Enabled _
= (Not (nLineCount + nLineLength).Equals(1)) AndAlso (Not FindDialog.Exists)
mnJump.Enabled = Not (nLineCount <= 1)
mnConvert.Enabled = Not p.EditBox.SelectedText.Equals("")
mnSelectAll.Enabled = Not (nLineCount + nLineLength).Equals(1)
End If
End Sub