タブ式テキストエディタ(9) ファイルのドラッグ&ドロップに対応させる

 ファイルをドラッグ&ドロップされた時の処理を考えてみます。以下のケースに対応させるようにしたいと思います。
  ・・・ ファイルがアプリケーションのアイコンにドラッグ&ドロップされた。
  ・・・ ファイルがタブページのテキスト上にドラッグ&ドロップされた。
  ・・・ ファイルがタブコントロール上にドラッグ&ドロップされた。
 さらに、後半でタブページに関する他のイベントもコーディングしてしまいます。

アイコンへのドラッグ&ドロップ

 ファイルがアイコンにドラッグ&ドロップされると、コマンドラインにファイル名が格納されます。これをMain関数で引数として受け取ると、簡単に各ファイル名を取り出すことができます。このとき、[スタートアップの設定]で"Sub Main"に設定しなおす必要があります。
 そして、フォーム読み込み時(OnLoad)に、コマンドライン引数を解析してドラッグ&ドロップの実行関数へ処理を渡します。実行関数は次の項を参照してください。
 なお、引き受けるファイルをテキスト系に限定するために、ファイルフィルタのリストをつくってフィルタリングすることにします。

' コマンドライン引数
Shared m_cmdargs As String() 
' ファイルフィルタ
Private m_extensions As String() = _
  {".txt", ".rtf", ".ini", ".htm", ".html", ".xml", ".xsd", ".log", ".csv", ".css"} 

' Sub Main : エントリ・ポイント
Public Shared Sub Main(ByVal CmdArgs As String())
    m_cmdargs = CmdArgs                 ' コマンドライン引数の取得
    Application.Run(New Tsuzuricyo()) ' アプリケーションを実行
End Sub

' Load : ロード
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
    ' 実行ファイルのアイコンにファイルがドロップされたときの処理
    If Not IsNothing(m_cmdargs) Then
        OnFileDrop(m_cmdargs, m_extensions)
    End If
End Sub 

ドラッグ&ドロップの実行

 以下がドラッグ&ドロップの実行関数です。フィルターの指定があるかないかで処理を分岐させています。該当するすべてのファイルをタブコントロール上に、新しいページをつくって読み込みます。

' OnFileDrop : ファイルのドラッグドロップ
' 引数 files : 受け入れるファイル(複数可)
' 引数 filter : 受け入れるファイルの拡張子
Private Sub OnFileDrop(ByVal files As String(), ByVal filter As String())
    Dim strFile As String    ' ファイル名
    Dim strExt As String    ' 拡張子名
    If IsNothing(filter) Then
        For Each strFile In files
            If IO.File.Exists(strFile) Then
                PageFromFile(strFile, Nothing)
            End If
        Next
    Else
        For Each strFile In files
            If IO.File.Exists(strFile) Then
                For Each strExt In filter
                    If LCase(IO.Path.GetExtension(strFile)).Equals(strExt) Then
                        PageFromFile(strFile, Nothing)
                    End If
                Next
            End If
        Next
    End If
End Sub

タブページのテキスト上へのドラッグ&ドロップ

 ファイルがテキスト上にドラッグ&ドロップされると、ExpandedTextControlクラスのOnFileDropイベントが発生(第3章参照)します。それを受けて、上記のOnFileDrop関数(違う名前にすればよかった)へと処理を渡します。

' タブページ : テキストへのファイルのドラッグドロップ
Private Sub TextPage_OnFileDrop(ByVal e As DragEventArgs)
    OnFileDrop(CType(e.Data.GetData(DataFormats.FileDrop, False), String()), m_extensions)
End Sub

タブコントロールへのドラッグ&ドロップ

 タブコントロールにファイルがドラッグ&ドロップされた時は、テキスト上にドラッグ&ドロップされたものとみなして、処理を上記の"OnFileDrop"イベントに渡すだけです。

' タブコントロール : ドラッグドロップの受け入れ
Private Sub TC1_DragEnter(ByVal sender As Object, _
            ByVal e As System.Windows.Forms.DragEventArgs) Handles TC1.DragEnter
    If e.Data.GetDataPresent(DataFormats.FileDrop) Then
        e.Effect = DragDropEffects.All
    End If
End Sub

' タブコントロール : ドラッグドロップ
Private Sub TC1_DragDrop(ByVal sender As Object, _
            ByVal e As System.Windows.Forms.DragEventArgs) Handles TC1.DragDrop
    TextPage_OnFileDrop(e)
End Sub 

その他のタブコントロール関連のイベント

"Closingイベント"
 アプリケーション終了時、未保存の文書があるかチェックします。

"SelectedIndexChangedイベント"
 アクティブなページが切り替えられた時、ワードラップ、タブ幅を再設定し、また、ファイル名をタイトル部分とステータスバーに反映させます。

"ControlAddedイベント"
 ページが追加された時、タイトル部分とステータスバーのファイル名の表示を変更します。

"ControlRemovedイベント"
 ページが削除された時、タイトル部分とステータスバーのファイル名の表示を変更します。

' Closing : アンロード
Protected Overrides Sub OnClosing( _
            ByVal e As System.ComponentModel.CancelEventArgs)
    If TC1.TabPages.Count > 0 Then
        Dim n As Integer
        For n = 0 To TC1.TabPages.Count - 1
            If Not AllowUpdate(DirectCast(TC1.TabPages(n), TextPage)) Then
                e.Cancel = True
                Exit Sub
            End If
        Next
    End If
    Application.Exit()
End Sub

' タブコントロール : ページの選択イベント
Private Sub TC1_SelectedIndexChanged(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles TC1.SelectedIndexChanged
    If Not IsNothing(TC1) Then
        If TC1.TabPages.Count > 0 Then
            Dim page As TextPage = DirectCast(TC1.SelectedTab, TextPage)
            If Not mnWordwrap.Checked = page.EditBox.WordWrap Then
                mnWordwrap.PerformClick()    ' ワードラップの設定
            End If
            m_tabwidth = page.EditBox.TabWidth  ' タブ幅の設定
            UpdateInfo(page)    ' 表示の変更
        End If
    End If
End Sub

' タブコントロール : ページの追加イベント
Private Sub TC1_ControlAdded(ByVal sender As Object, _
            ByVal e As ControlEventArgs) Handles TC1.ControlAdded
    If TC1.TabPages.Count = 1 Then
        Dim page As TextPage = DirectCast(e.Control, TextPage)
        UpdateInfo(page)    ' 表示の変更
    End If
End Sub

' タブコントロール : ページの削除イベント
Private Sub TC1_ControlRemoved(ByVal sender As Object, _
            ByVal e As ControlEventArgs) Handles TC1.ControlRemoved
    If TC1.TabPages.Count = 1 Then
        UpdateInfo(Nothing)    ' 表示の変更
    End If
End Sub 
| ■HOME | ◆プログラムTop | ▲ページの先頭 | << 前の章 | 次の章 >> |