コンボボックスのアイテムとツリービューのノードを作成するため、以下の関数を設定します。
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