タブ式テキストエディタ(15) 初期化ファイルをつくる

 初期化のためのシステムにいくつもの選択肢があります。
 @ Win32APIを使って"ini"ファイルを利用する。
 A データセットを使って"xml"ファイルを利用する。
 B シリアライズクラスを使ってバイナリファイルを利用する。
 これ以外にも動的プロパティを使う方法もありますが、面倒くさそうだったので割愛しています。@とAは実質はテキストファイルなので後からの編集が容易です。@は手続きが面倒ですが、なれている方にはさほどでもないでしょう。VB.net風に決めるなら、AのXMLを活用するのが最も簡単な方法ではないでしょうか。"DataSet + XML Schema"の雛形も用意されていますからコードの記述量も少なくて済みます。
 しかし、筆者はあまのじゃくなので今回はBのバイナリファイルを使う方法をとることにします。後から編集するには面倒(バイナリエディタで編集)なのですが、パフォーマンスがよいのが何よりの利点です。
 なお、タブ式テキストエディタは今回で完結です。

初期化データクラス

 まずは初期化データの種類を定義して値を格納するクラスをつくります。ファイルの読み書き時には、直接このクラスにアクセスさせ、一時的に値を格納します。そして、ここで格納したデータを各プロパティへ割り振っていくことにします。
 クラスを宣言する際、バイナリデータとして扱うようにするためには、"Serializable"属性をつける必要があります。また、コンストラクタでは、一回目の起動や初期化ファイルが失われたときのために、初期値の設定を行っています。

  Public Class InitialData
    Inherits System.Object

    ' 変数
    Public frm_state As FormWindowState ' メインフォームのウインドウステート
    Public frm_point As Point            ' メインフォームの位置
    Public frm_size As Size               ' メインフォームのサイズ
    Public view_font As Font             ' フォント
    Public view_toolbar As Boolean    ' ツールバーの可視
    Public view_statusbar As Boolean ' ステータスバーの可視
    Public view_wordwrap As Boolean ' ワードラップ
    Public view_tabwidth As Integer    ' タブ幅
    Public dfind_point As Point           ' 検索ダイアログの位置
    Public dfind_matchcase As Boolean ' 検索条件(大文字子文字の区別)
    Public file_recent As String()          ' 最近使ったファイルのリスト

    ' コンストラクタ
    Public Sub New(ByVal SetValues As Boolean)
       ' 初期値を入れる必要がある場合 
       If SetValues Then
            frm_state = FormWindowState.Normal
            frm_point = New Point(100, 100)
            frm_size = New Size(640, 480)
            view_font = New Font("MS UI Gothic", 10, FontStyle.Regular)
            view_toolbar = True
            view_statusbar = True
            view_wordwrap = True
            view_tabwidth = 0
            dfind_point = New Point(100, 100)
            dfind_matchcase = False
            file_recent = Nothing
        End If
    End Sub
End Class 

データを読み書きする関数

 メインフォーム側に初期化ファイルを読み書きする関数を追加します。この際に、BinaryFormatterクラスを利用してシリアル化、または逆シリアル化を行います。検索ダイアログはインスタンスはこの時点ではまだないのですが、Shredキーワードでプロパティを設定していますので代入が可能です。

Private m_initfile As String                           ' 初期化ファイル
Private m_loadsize As Size                           ' フォームのサイズ
Private m_loadpoint As Point                        ' フォームの位置
Const strInitfile As String = "tsuzuri.dat"      ' 初期化用データファイル

' LoadInitializeData : 初期化データの読み込み
Private Sub LoadInitializeData()
    Dim m_data As InitialData
    If IO.File.Exists(m_initfile) Then
        Dim m_formatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
        Dim m_stream As New IO.FileStream(m_initfile, IO.FileMode.Open)
        ' 初期化データクラスを逆シリアル化
        Try
            m_data = CType(m_formatter.Deserialize(m_stream), InitialData)
        Finally
            m_stream.Close()
        End Try
    Else
        ' 初期化ファイルがないときは初期値を読み込む
        m_data = New InitialData(True)
    End If

    ' 初期化データの値を各プロパティに割り振り
    With m_data
        Me.WindowState = .frm_state
        m_loadpoint = .frm_point
        m_loadsize = .frm_size
        m_font = .view_font
        m_tabwidth = .view_tabwidth
        If .view_toolbar Then mnToolbar.PerformClick()
        If .view_statusbar Then mnStatusbar.PerformClick()
        If .view_wordwrap Then mnWordwrap.PerformClick()
        FindDialog.LoadPoint = .dfind_point
        FindDialog.MatchCase = .dfind_matchcase
        m_recent = New StringCollection()
        If (Not IsNothing(.file_recent)) AndAlso (.file_recent.Length > 0) Then
            Dim i As Integer
           For i = 0 To .file_recent.Length - 1
                m_recent.Insert(.file_recent(i))
            Next
        End If
        If m_recent.Count > 0 Then
            UpdateRecentMenu()
        End If
    End With
    m_data = Nothing
End Sub

' WriteInitializeData : 初期化データの書き出し
Private Sub WriteInitializeData()
    ' 現在の値を初期化データクラスに格納
    Dim m_data As New InitialData(False)
    With m_data
        If Me.WindowState = FormWindowState.Maximized Then
            .frm_state = FormWindowState.Maximized
        Else
            .frm_state = FormWindowState.Normal
        End If
        If Me.WindowState <> FormWindowState.Minimized Then
            .frm_point = Me.Location
            .frm_size = Me.Size
        End If
        .view_font = m_font
        .view_tabwidth = m_tabwidth
        .view_toolbar = mnToolbar.Checked
        .view_statusbar = mnStatusbar.Checked
        .view_wordwrap = mnWordwrap.Checked
        .dfind_point = FindDialog.LoadPoint
        .dfind_matchcase = FindDialog.MatchCase
        If m_recent.Count > 0 Then
            ReDim .file_recent(m_recent.Count - 1)
            Dim i As Integer
            For i = 0 To m_recent.Count - 1
                .file_recent(i) = m_recent(i)
            Next
        End If
    End With

    ' 初期化データクラスをシリアル化
    Dim m_formatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
    Dim m_stream As New IO.FileStream(m_initfile, IO.FileMode.Create)
    Try
        m_formatter.Serialize(m_stream, m_data)
    Finally
        m_stream.Close()
    End Try
    m_data = Nothing
End Sub

初期化ファイルの読み書きの実装

 最後に、既存の関数に初期化ファイルの読み書きを実装します。コンストラクタで初期化ファイルを読み込んでプロパティを初期化。ただし、メインフォームのサイズだけはロード時でなければ調整できないので後回しになります。そしてアンロード時には、逆に各プロパティの値を初期化ファイルに格納しています。

' New : コンストラクタ
Public Sub New()
    ...
    ' 初期化ファイルの読み込み
    m_initfile = IO.Path.Combine(Application.StartupPath, strInitfile)
    LoadInitializeData()
End Sub

' OnLoad : ロード
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
    ' 初期化データからウインドウステートと位置、サイズを設定
    If Me.WindowState <> FormWindowState.Maximized Then
        ' 最大化のときは最大化の状態でロード、それ以外は位置とサイズの値に従う
        Me.Size = m_loadsize
        Me.Location = m_loadpoint
    End If
    ...
End Sub

' Closing : アンロード
Protected Overrides Sub OnClosing(ByVal e As System.ComponentModel.CancelEventArgs)
    ...
    ' 現在の値を初期化ファイルに書き出し
    WriteInitializeData()
    ...
End Sub
| ■HOME | ◆プログラムTop | ▲ページの先頭 | << 前の章 |