フォルダツリービュー(2)

VB SampleFolderTreeView 2 : Make Tree
 フォルダツリービューの二回目です。コンボボックスにドライブ名を、ツリービューにフォルダ名を追加する関数群です。なお、今回の記述はすべて FolderTree クラス内に行います。
 なお、参照設定に、System.Management を追加する必要があります。
【INDEX】
ページ1 : フォームとアイテムクラス
●ページ2 : ドライブとフォルダの表示
メンバとイベントの宣言 ... 変数・定数・イベントの宣言
ノードの表示 ... フォルダを表示するノードの設定
ページ3 : イベント処理とフォルダ操作

■メンバとイベントの宣言
 UseControl (FolderTreeクラス) の宣言部は以下の通りです。
Public Class FolderTree
    Inherits System.Windows.Forms.UserControl

#Region "Windowsフォームデザイナで生成されたコード"
    (略)
#End Region

    ' 内部変数
    Private m_selpath As String = ""        ' 選択されたパス名
    Private m_first As Boolean = False      ' 起動フラグ(更新の許可)

    ' 定数 : メッセージボックスのタイトルバーの文字列
    Private Const strCaption As String = "フォルダツリービュー"
   
    ' 定数 : アイコンの ImageList での Index
    Private Const icoUnknown As Integer = 0      ' 未知のドライブ
    Private Const icoRemovable As Integer = 1    ' リムーバブルディスク
    Private Const icoFixed As Integer = 2            ' ハードディスク
    Private Const icoRemote As Integer = 3        ' リモートディスク
    Private Const icoCDRom As Integer = 4         ' 光学ディスク
    Private Const icoRAMDisk As Integer = 5       ' RAMディスク
    Private Const icoCloseFolder As Integer = 6   ' 閉じたフォルダ
    Private Const icoOpenFolder As Integer = 7   ' 開いたフォルダ

    'イベント : ノードをダブルクリックした時にパス名を渡す
    Public Event NodeDoubleClick(ByVal path As String, ByVal e As System.EventArgs)

    ' イベント : ノードをクリックした時にパス名を渡す
    Public Event NodeMouseDown(ByVal path As String, ByVal e As MouseEventArgs)

    ' プロパティ : 選択されたパス名
    Public Property SelectedPath() As String
        Get
            Return m_selpath
        End Get
        Set(ByVal Value As String)
            m_selpath = Value
        End Set
    End Property
End Class	
| ▲TOP |

■ノードの表示
 コンボボックスのアイテムとツリービューのノードを作成するため、以下の関数を設定します。
UpdateWith ... コンボボックスとツリービューのすべてを更新します。
UpdateDrives ... コンボボックスを更新します。
SetDriveItem ... コンボボックスの項目の設定します。
GetNodes ... ドライブ名またはノードから子ノードを取得・追加します。
GetSubNodes ... サブノードを取得・追加します。
RestoreTree ... 参照するパス名に基づいてノードを展開させます。
' UpdateWith : 全コントロールの更新
' ... 引数path : 展開して表示するパス名(このパスのノードが展開した状態で表示される)
Public Sub UpdateWith(ByVal path As String)
    TV1.Nodes.Clear()  ' ノードのクリア

    ' パス名が無効のときは代わりにアプリケーションのパスを参照
    If IO.Directory.Exists(path) = False Then
        path = Application.StartupPath
    End If

    UpdateDrives(path)  ' ドライブの取得
    RestoreTree(path)  ' ツリーの復元
End Sub

' UpdateDrives : ドライブリストの更新 ' 引数path : 展開して表示するパス名(このパスのノードが展開した状態で表示される) Private Sub UpdateDrives(Optional ByVal path As String = Nothing) Cursor.Current = Cursors.WaitCursor ' カーソルを待機状態に CB1.Items.Clear() ' コンボボックスの項目をクリア ' コンボボックスに項目を追加 If (Not IsNothing(path)) And (IO.Directory.Exists(path)) Then ' パス名が有効の時は、該当ドライブのみ取得して追加 Dim m_root As String = path.Substring(0, 2) ' ドライブ名 Dim m_param As String = "Win32_LogicalDisk.DeviceID=""" & m_root & """" Dim m_obj As New System.Management.ManagementObject(m_param) Dim m_item As New DriveItem() m_obj.Get() ' ドライブのマネジメントオブジェクト SetDriveItem(m_item, m_obj) ' ドライブアイテムオブジェクト CB1.Items.Add(m_item) ' コンボボックスに項目を追加 CB1.SelectedIndex = 0 m_obj.Dispose() Else ' パス名が無効の時は、すべてのドライブを取得して追加 Dim m_searcher As _ New System.Management.ManagementObjectSearcher _ ("SELECT * From Win32_LogicalDisk") Dim m_obj As System.Management.ManagementObject For Each m_obj In m_searcher.Get() ' マネジメントオブジェクトからドライブアイテムを取得して項目を追加 Dim m_item As New DriveItem() SetDriveItem(m_item, m_obj) CB1.Items.Add(m_Item) Next ' リソースの開放 m_searcher.Dispose() ' リストの選択 If m_selpath <> "" Then ' 選択していたパス名が有効のときは、該当するドライブを選択状態にする Dim strDrive As String = m_selpath.Substring(0, 2) ' ドライブ名 Dim i As Integer For i = 0 To CB1.Items.Count - 1 If LCase(DirectCast(CB1.Items(i), DriveItem).Name) = LCase(strDrive) Then CB1.SelectedIndex = i ' ドライブ項目の選択 Exit For End If Next End If End If Cursor.Current = Cursors.Default ' カーソルを元に戻す End Sub
' SetDriveItem : ドライブアイテムの取得 ' ... 引数item : ドライブアイテムオブジェクト ' ... 引数obj : ドライブのマネジメントオブジェクト Private Sub SetDriveItem(ByVal item As DriveItem, _ ByVal obj As Management.ManagementObject) Dim m_image As Integer ' アイコンのインデックス ' アイコンの選択 ' DriveType...0=UnKnown,2=Removable,3=LocalDisk,4=Network,5=CD,6=RAM Select Case CInt(obj("DriveType").ToString) Case 2 : m_image = icoRemovable Case 3 : m_image = icoFixed Case 4 : m_image = icoRemote Case 5 : m_image = icoCDRom Case Else : m_image = icoRAMDisk End Select ' ドライブアイテムのプロパティの取得 item.Name = CStr(obj("Name")) ' ドライブ名 item.ImageIndex = m_image ' アイコンのインデックス If TypeName(obj("VolumeName")) Is "String" Then ' ドライブのボリュームラベル item.Volume = obj("VolumeName").ToString End If End Sub
' GetNodes : ツリーノードの取得(ドライブ名から) ' ... 引数drive : ドライブ名 Private Sub GetNodes(ByVal drive As String) Dim m_path As String ' フォルダ名 Dim m_array As String() ' フォルダ名の配列 ' フォルダの取得 If Not drive.EndsWith("\") Then drive &= "\" ' 末尾に"\"を付加 m_array = IO.Directory.GetDirectories(drive) ' フォルダ名の配列の取得 m_array.Sort(m_array) ' 昇順に並べ替え ' ツリービューにノードを追加 For Each m_path In m_array If (GetAttr(m_path) And FileAttribute.Hidden) <> FileAttribute.Hidden Then ' 隠し属性(Hidden)のフォルダは除外してノードを作成 Dim newNode As New PathNode(m_path, icoCloseFolder, icoOpenFolder) TV1.Nodes.Add(newNode) ' ツリービューにノードを追加 GetNodes(newNode) ' 子ノードを取得して追加 End If Next End Sub
' GetNodes : ツリーノードの取得(ツリーノードから) ' ... 引数node : 参照するノード Private Sub GetNodes(ByVal node As PathNode) Dim m_path As String ' パス名 Dim m_folder As String ' フォルダ名 Dim m_array As String() ' フォルダ名の配列 ' フォルダの取得 m_folder = DirectCast(node, PathNode).FolderPath ' フォルダ名 If Not m_folder.EndsWith("\") Then m_folder &= "\" ' 末尾に"\"を追加 m_array = IO.Directory.GetDirectories(m_folder) ' フォルダの取得 m_array.Sort(m_array) ' 並べ替え ' ツリービューにノードを追加 For Each m_path In m_array If (GetAttr(m_path) And FileAttribute.Hidden) <> FileAttribute.Hidden Then ' 隠し属性のフォルダを除いてノードを作成 Dim newNode As New PathNode(m_path, icoCloseFolder, icoOpenFolder) node.Nodes.Add(newNode) ' ツリービューにノードを追加 End If Next End Sub
' GetSubNodes : サブノードの取得 ' ... 引数node : 参照する親ノード Private Sub GetSubNodes(ByVal node As PathNode) Dim subNode As PathNode ' 親ノードの子ノードごとに処理 For Each subNode In node.Nodes GetNodes(subNode) Next ' 展開済みフラグを立てる node.IsVested = True End Sub
' RestoreTree : ツリーの復元 ' ... 引数path : 展開するパス名 Private Sub RestoreTree(ByVal path As String) Try ' 指定パスのノードまで展開 Dim m_array As String() ' 展開するフォルダのリスト Dim m_size As Integer = -1 ' 配列のサイズ Dim m_path As String = path ' パス名 ' パス名から展開すべき親フォルダを配列化 (ただしルートはドライブのため除外) Do Until m_path = IO.Path.GetPathRoot(m_path) m_size += 1 ReDim Preserve m_array(m_size) m_array(m_size) = m_path m_path = IO.Path.GetDirectoryName(m_path) Loop ' ノードの展開 Dim m_node1 As PathNode Dim m_nodes As TreeNodeCollection = TV1.Nodes Dim m_count As Integer = m_array.Length Dim i As Integer = m_count - 1 Do For Each m_node1 In m_nodes ' 配列のパス名と一致するノードを展開 If StrComp(m_array(i), m_node1.FolderPath, CompareMethod.Text) = 0 Then ' 選択フォルダ(path)でなければ展開 If StrComp(m_node1.FolderPath, path, CompareMethod.Text) <> 0 Then m_node1.Expand() End If Exit For End If Next m_nodes = m_node1.Nodes i -= 1 Loop Until i < 0 TV1.SelectedNode = m_node1 ' ノードを選択状態にする m_selpath = m_node1.FolderPath ' プロパティの更新 Catch ex As Exception MessageBox.Show(ex.Message, "復元時エラー", _ MessageBoxButtons.OK, MessageBoxIcon.Stop) UpdateWith(path) ' エラー時は再度更新 End Try End Sub
| ▲TOP |

| ■HOME | ◆プログラムTop | ▲ページの先頭 |