次の操作のすべてをこの一つの関数でまかないますが、ちょっと長くなってしまいました。まあ一つの関数に記述する限界は100行くらいだそうですから、ぎりぎり許容範囲かなと思います。
@ 新規ページに新規文書を追加する。
A 新規ページに既存のファイルを読み込む。
B アクティブなページに新規文書を設定する。
C アクティブなページに既存のファイルを読み込む。
' 変数 : タブ幅
Private m_tabwidth As Integer = 0
' PageFromFile : 指定したファイルを指定したページに開く
' ... 引数path : パス名。ただし、 [Nothing] で新規作成、[""] でOpenFileDialog を生成
' ... 引数page : 対象ページ。ただし、[Nothing] で新規ページ
Public Sub PageFromFile(ByVal path As String, ByVal page As TextPage)
Dim d As OpenFileDialog ' 「ファイルを開く」ダイアログボックス
Dim strFilter As String = _
"テキストファイル(*.txt,*.rtf,*.html,*.css)|*.txt;*.rtf;*.html;*.css|すべてのファイル(*.*)|*.*"
Static nFilter As Integer = 1 ' ダイアログのフィルター番号
Try
Dim strFile As String = "" ' ファイル名
Dim strCaption As String = "" ' 見出しの文字列
' ページの表示
If IsNothing(path) Then
' 新規作成
Dim nNumber As Integer = 0 ' 文書番号
Dim bBreak As Boolean ' ループ脱出フラグ
Do
bBreak = True
nNumber += 1
strCaption = "無題" & nNumber.ToString
Dim p As TextPage
If TC1.TabPages.Count > 0 Then
For Each p In TC1.TabPages
If p.Text = strCaption Then
bBreak = False : Exit For
End If
Next
End If
Loop Until bBreak
ElseIf path.Length = 0 Then
' ダイアログからファイル名を取得
d = New OpenFileDialog()
d.Filter = strFilter
d.FilterIndex = nFilter
If d.ShowDialog = DialogResult.OK Then
strFile = d.FileName
strCaption = IO.Path.GetFileNameWithoutExtension(strFile)
nFilter = d.FilterIndex
End If
Else
' 指定されたファイル名
strFile = path
strCaption = IO.Path.GetFileNameWithoutExtension(strFile)
End If
If strCaption <> "" Then
' ページの取得
If IsNothing(page) Then
' 新規ページ
page = New TextPage()
page.Visible = False
Dim ctrEdit As ExpandedTextControl = page.EditBox
AddHandler ctrEdit.TextChanged, AddressOf TextPage_TextStateChanged
AddHandler ctrEdit.SelectionChanged, AddressOf TextPage_TextStateChanged
AddHandler ctrEdit.OnFileDrop, AddressOf TextPage_OnFileDrop
TC1.TabPages.Add(page)
Else
' 既存ページ
page.Visible = False
End If
With page
' ページの初期設定
.EditBox.Clear()
.EditBox.Font = m_font
.EditBox.SetWordWrap(mnWordwrap.Checked)
.EditBox.SetTabStops(m_tabwidth)
' ファイルの読み込み
.LoadFile(strFile)
.Text = strCaption
.Visible = True
TC1.SelectedTab = page
.EditBox.Focus()
End With
If strFile <> "" Then UpdateRecentFiles(strFile)
UpdateInfo(page)
End If
Catch ex As Exception
MessageBox.Show(ex.Message, _
"I/Oエラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
If Not IsNothing(d) Then d.Dispose()
End Try
End Sub
m_tabwidth(タブ幅)は、ページを設定する時に使用します。0の時は自動的にデフォルト値(第3章)となります。また、関数内の変数"nFilter"は、ダイアログのフィルター番号で、Static宣言をしています。二度目以降にダイアログを開いたときはこの値が適用されます。
まず、引数"path"の値を調べ、"Nothing"なら新規作成、空文字""ならファイルを開くダイアログボックスを開いてユーザーに選択を求めます。指定されたファイルがあるときはそのまま変数""strFile"と"strCaption"に代入します。
続いて引数"page"を調べ、"Nothing"の時は、新たにタブページをつくってタブコントロールの追加します。指定のページがある場合は、該当ページ上に新規作成文書をつくるか、ファイルをロードします。
ページを新たにつくる際に結びつけるイベントは以下の二つです。とりあえず関数だけつくっておくことにします。中身については追々埋めていこうと思います。
' タブページ : テキスト状態の変更イベント
Private Sub TextPage_TextStateChanged(ByVal sender As Object, ByVal e As EventArgs)
' テキストの変更、選択文字列の変更時の処理
End Sub
' タブページ : テキストへのファイルのドラッグドロップ
Private Sub TextPage_OnFileDrop(ByVal e As DragEventArgs)
' テキスト部分へファイルがドラッグ&ドロップされた時の処理
End Sub
次いで、ファイルへの保存です。「上書き保存」、「名前をつけて保存」の両方に対応しています。
引数"path"が"Noting"、または空文字""の時、「ファイルに保存」ダイアログボックスを開きます。ファイル名に指定があるときは上書き保存。
' PageToFile : 指定ページの内容を指定したファイルに保存
' ... 引数path : パス名。ただし、 [Noting] または[""] でSaveFileDialog を呼び出し
' ... 引数page : 対象ページ。
Public Sub PageToFile(ByVal path As String, ByVal page As TextPage)
Dim d As SaveFileDialog
Dim strFilter As String = _
"テキストファイル(*.txt)|*.txt|リッチテキスト(*.rtf)|*.rtf|HTML(*.html)|*.html|すべてのファイル(*.*)|*.*"
Try
If (Not IsNothing(path)) AndAlso IO.File.Exists(path) Then
' ファイル名が指定されたとき
page.SaveFile(path)
UpdateRecentFiles(path)
Else
' ファイル名の指定がないとき
d = New SaveFileDialog()
With d
.Filter = strFilter
.OverwritePrompt = False
End With
If (d.ShowDialog = DialogResult.OK) AndAlso (d.FileName.Length > 0) Then
Dim strFile As String = d.FileName ' ファイル名
' 拡張子のチェック
If IO.Path.GetExtension(strFile) <> "" Then
If d.FilterIndex = 1 Then
strFile = IO.Path.ChangeExtension(strFile, ".txt")
ElseIf d.FilterIndex = 2 Then
strFile = IO.Path.ChangeExtension(strFile, ".rtf")
ElseIf d.FilterIndex = 3 Then
strFile = IO.Path.ChangeExtension(strFile, ".html")
End If
Else
strFile += ".txt"
End If
' 既存ファイルのチェック
Dim bSave As Boolean = True ' 保存許可
If IO.File.Exists(strFile) Then
Dim msg As String = _
"ファイル [" & IO.Path.GetFileName(strFile) & "] は、すでに存在します。" _
& vbCrLf & "上書きしますか?"
If MessageBox.Show(msg, _
"上書きの確認", _
MessageBoxButtons.OKCancel, _
MessageBoxIcon.Question) _
= DialogResult.Cancel Then
bSave = False
End If
End If
If bSave Then
page.SaveFile(strFile)
page.Text = IO.Path.GetFileNameWithoutExtension(strFile)
UpdateInfo(page)
UpdateRecentFiles(strFile)
End If
End If
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "I/Oエラー", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
If Not IsNothing(d) Then d.Dispose()
End Try
End Sub
途中、拡張子をチェックしています。自動付加の対象としているのは".txt"と".rtf"ですが、フィルターの種類共々、そのうち改良して".html"や".css"など、もうちょっと増やしたいと思っています。