Visual Basic 初級講座 |
Visual Basic 中学校 > 初級講座 >
第25回 実技2 フォルダ情報一覧
今回は フォルダのサイズ・ファイル数・フォルダ数を一覧表示するソフトを作ります。これはWindowsにはない機能ですのである程度の使いではあると思います。とくにフォルダのサイズがわかるとハードディスクを整理するときに便利なのが嬉しいです。
今回のソフトの作成にあたってはこれまで初級講座で解説してきたコントロールの知識はあまり使いません。初級講座ではコントロールの一般的な説明をしてきただけで個別のコントロールの具体的な使用方法については説明していないからです。
しかしながら、今回の目標は実際にいろいろなコントロールを使って「使えるアプリケーション」を作る手順を体験してもらうことです。未知のコントロールや未知のプログラミング技法は余裕綽々(よゆうしゃくしゃく)で受け流してください。一応簡単な解説もしてあります。
この回の要約 ・フォルダ情報一覧ソフトを作る |
便宜のために完成版をダウンロードできるようにしておきます。実際に動かしながら説明を読みたい方は先にダウンロードしてください。
完成版 フォルダ情報一覧 10.85KB lha形式(拡張子lzh)
はじめにこれから作るソフトの主な機能・使い方を説明します。
■画像1:完成版
ソフトは左側のフォルダツリーと右側の一覧にわかれます。左側のツリーで選択したフォルダに含まれるファイルとフォルダの一覧が右側の一覧部分に表示されます。このとき、ファイルについてはサイズも表示されます。
一覧で、フォルダのサイズ・ファイル数・フォルダ数を表示するには[詳細表示]ボタンをクリックします。ここでいうサイズ等はエクスプロらーでファイルを右クリックして表示されるプロパティ画面の値と同じですべてのサブフォルダの合計です。
一覧はタイトルの部分をクリックすることで並び替えることもできます。たとえば、サイズ順に並び替えたければ「サイズ」と書かれているタイトルをクリックします。クリックするたびに降順と昇順が入れ替わります。
「自動的に詳細を表示する」チェックボックスをチェックしている場合は左側のツリーでフォルダを選択した段階で一覧にフォルダのサイズ・ファイル数・フォルダ数も表示されますが、これらを計算するためには時間がかかりますので注意です。
その他の小さな機能として一覧部分でファイルやフォルダをクリックすると、そのファイルやフォルダを開くことができます。また、ステータスバーには現在一覧しているフォルダのフルパスが表示されます。
実際の作業の説明に入る前にファイル・フォルダの一覧とループについて簡単に説明しておきます。今回のソフトではファイル・フォルダの一覧をループで処理する個所が何箇所かあるので最初にこの点を知っておくとプログラムの理解の助けになると思います。
VBではフォルダの情報を取得したりフォルダを操作するときにDirectoryInfoクラス(読み方:DirectoryInfo = ディレクトリインフォ)を使うのが一般的です。このクラスはインスタンス化するとき(つまりNewを使うとき)に対象のフォルダをフルパスで指定します。たとえば、C:\Program Files\を表すDirectoryInfoクラスのインスタンスを作成するには次のようにします。
Dim Folder As New IO.DirectoryInfo("C:\Program Files\") |
■リスト1:DirectoryInfoクラスのインスタンシング
これだけでもこのフォルダに対して情報を取得したり操作するためのメソッドやプロパティが使えるようになるので便利なのですがその中でもGetFilesメソッド(読み方:GetFiles = ゲットファイルズ)とGetDirectoriesメソッド(読み方:GetDirectories = ゲットディレクトリーズ)はそれぞれ、そのフォルダの直下にあるファイルの一覧とフォルダの一覧を返すのでよく使います。
このメソッドの詳しい使い方は今後の初級講座で解説します。ここではこの2つを使ってファイルやフォルダを1つずつ処理していくループの記述方法だけ紹介します。
次のように記述するとこのフォルダに属するフォルダの名前がひとつずつリストボックスに追加されていきます。
Dim
Folder As
New IO.DirectoryInfo("C:\Program
Files\") Dim oFolder As IO.DirectoryInfo For
Each oFolder
In
Folder.GetDirectories |
■リスト2:フォルダの列挙
ここでは説明を簡単にするために名前だけを取り出していますが、変数oFolderもDirectoryInfo型ですので名前以外にもさまざまな情報を取り出すことができます。とにかくFor Each 〜 NextループとGetDirectoriesメソッドを組み合わせた処理は何かと使う機会がありますので丸暗記しても良いくらいです。For Each 〜 Next ループについては次々回かその次くらいで解説する予定です。
ファイルの場合はFileInfoクラス(読み方:FileInfo = ファイルインフォ)を使って次のようにループを回します。
Dim
Folder As
New IO.DirectoryInfo("C:\Windows\") Dim oFile As IO.FileInfo
For
Each oFile
In Folder.GetFiles |
■リスト3:ファイルの列挙
前置きはこのくらいにしてそろそろプログラムを開始します。新規プロジェクトを作成し、名前はFolderInfoとしてください。
フォームには次の通りにコントロールを配置してください。
■画像2:コントロールの配置。ここには表示されてないがImageListも配置する(本文参照)。
コントロールを配置する順番は重要です。次の順番では位置してください。
StatusBar1 |
Splitter1 |
tvFolders(TreeView) |
Panel1 |
lvFolder(ListView) |
その他のコントロール |
■表1:配置する順番
他の順番で配置してもZオーダーを調節すればなんとかなりますが、下手な順番で配置するとDockプロパティによる配置の制御がうまくいかないので面倒です。
この他に、ImageListも配置してください。ImageListはフォームに貼り付けると、フォームではなくフォームの下の部分(コントロールトレイ)に表示されます。ImageListはツリービューやリストビューに表示するアイコンを管理するためのコントロールで、これ自体が画面に表示されると言うことはありません。
今回は第3章 コントロール の実技にあたりますのでできるだけいろいろな種類のコントロールを扱ってみました。
各コントロールのプロパティは次の通りに設定してください。プロパティに何も指定していないコントロールに対してはこの段階では何も設定する必要はありません。
コントロール | 種類 | プロパティ | 値 |
Form1 | Form | Text | フォルダ情報一覧 |
Splitter1 | Splitter | ||
tvFolders | TreeView | Dock | Left |
ImageList | ImageList1 | ||
Panel1 | Panel | Dock | Top |
lvFolder | ListView | AutoArrange | False |
Columns | (本文中で説明) | ||
SmallImageList | ImageList1 | ||
Dock | Fill | ||
View | Details | ||
btnDetail | Button | Text | 詳細表示 |
chkDetail | CheckBox | Text | 自動的に詳細を表示する |
StatusBar1 | StatusBar | ||
ImageList1 | ImageList | Images | (本文中で説明) |
■表2:コントロールのプロパティ
以上のプロパティ設定が終了した段階で実行してみる何も機能はしませんが、フォームのサイズ変更やスプリッターによる領域のサイズ変更がうまく動作することが確認できます。
ここでリストビューについてごく簡単に説明しておきます。リストビューは複数の項目を表示するためのコントロールです。この点はリストボックスなどとも共通ですが、リストビューは他のコントロールと異なり4つの違った形式で項目を表示することができます。この形式を指定するのがViewプロパティ(読み方:View = ビュー)です。
Viewプロパティには次の4つの値を設定することができます。
値 | 読み方 | 意味 |
LargeIcon | ラージアイコン | 大きいアイコン形式 |
SmallIcon | スモールアイコン | 小さいアイコン形式 |
List | リスト | 一覧形式 |
Details | ディテイルズ | 詳細形式 |
■表3:リストビューの表示形式
これらはWindowsのエクスプローラの表示形式とまったく同じです。Windowsではファイルの表示方法をアイコン・一覧・詳細などの形式から選択できますが、まさにそれがリストビューの表示形式です。「小さいアイコン形式」はWindowsXPには存在しないようですが、たしかWindows98くらいにはあったように記憶しています。
これらの表示形式のうち詳細形式がもっとも重要です。詳細形式の場合は他の形式とことなり複数の情報を表示することができるからです。他の形式ではファイルの「名前」を表示するだけで終わってしまいますが、詳細形式なら「名前」の他に「サイズ」どの「ファイル数」だのいろいろな情報を表示することができます。リストビューのメソッドやプロパティでも詳細形式の場合でしか使わないものが多いです。
このようにリストビューはなかなか便利なのですが、多機能なために使い方を理解するのが少しばかり大変です。リストボックスなどは機能が単純なためにちょっと練習すればすぐ使い方がわかるのですがリストビューを使いこなすにはより多くの訓練が必要です。今回のソフト作りを通してリストビューの使い方の概要が把握できればすばらしい成果といえるでしょう。
さて、ツリービュー(tvFolders)やリストビュー(lvFolder)のためにあらかじめアイコンを用意しておく必要があります。用意したアイコンはImageList1のImagesプロパティ(読み方:Images = イメージス)に登録します。
まず、以下のリンクをクリックしてフォルダのアイコンをダウンロードしてください。お手元に開いているフォルダのアイコンと閉じているフォルダのアイコンがあればそれを使用しても構いません。
アイコン 767B lha形式(拡張子lzh)
アイコンを用意したら、ImageList1のプロパティウィンドウでImagesプロパティを選択します。3点ボタン( ... と表示されているボタン)をクリックしてアイコン登録画面を開いてください。
■画像3:Imagesプロパティ
ここに、[追加]ボタンを押して、閉じているフォルダのアイコンと開いているフォルダのアイコンを追加します。
■画像4:アイコンの登録
最後はOKボタンをクリックして閉じてください。
これで、ツリービュー(tvFolders)とリストビュー(lvFolders)はこのアイコンを使用できるようになります。最初にプロパティを設定したときにtvFoldersのImageListプロパティとlvFoldersのSmallImageListプロパティにこのImageList1を設定したことを思い出してください。
次に一覧のために列を追加します。今回は名前、サイズ、ファイル数、フォルダ数を表示するので4列必要です。
プロパティウィンドウでlvFoldersのColumnsプロパティ(読み方:Columns = カラムス)を選択し、3点ボタン( ... と表示されているボタン)をクリックします。
ImageListにImagesを登録したのを同じようなダイアログ画面が開きますのでここに列を追加していきます。[追加]ボタンをクリックするたびに列が1つ増えるので列が4つになるようにしてください。
■画像5:列の設定
それぞれの列をクリックすると右側にプロパティが表示されるので、次の表の通りにプロパティを設定してください。
列 | プロパティ | 値 |
ColumnHeader1 | Text | 名前 |
Width | 200 | |
ColumnHeader2 | Text | サイズ |
TextAlign | Right | |
ColumnHeader3 | Text | ファイル数 |
TextAlign | Right | |
ColumnHeader4 | Text | フォルダ数 |
TextAlign | Right |
■表4:列の設定
作業が終わったら[OK]をクリックしてダイアログを閉じてください。
このプロパティの設定の意味はわかりやすいと思います。TextAlignプロパティ(読み方:TextAlign = テキストアライン)はわかりにくいかも知れないので補足しておきます。このプロパティは表示するテキストの配置を指定するものです。Rightを指定した場合はテキストが右詰で表示されます。パソコンの世界では数値は右詰で表示するのが常識となっています。
さて、コントロールの設定がようやく完了しました。いよいよプログラムに取り掛かりたいのですがもう少し準備をします。
というのは今回予定している機能の中でどうしても初級レベルを越えてしまうの部分があるのでその部分を先にコピー&貼り付けしてもらいます。この部分のプログラムは解説しません。
ここで貼り付けてもらうプログラムの内容を簡単にまとめると次の通りです。
オブジェクト名 | 種類 | 説明 |
FolderProperty | 構造体 | フォルダのサイズ・ファイル数・フォルダ数を一括管理できるように変数をまとめた物。 |
ItemImage | 列挙体 | ImageList1のアイコンの番号を記録したもの。閉じたフォルダは0番(ClosedFolder)、開いたフォルダは1番(OpenedFolder)と言った具体 |
FileSorter | クラス | リストビューに並び替え機能を提供するクラス。昇順・降順の並び替えや並び替え対象列の判断などExecuteメソッドを呼び出すだけで並び替えに対するすべてをこのクラスが実行・管理する。 |
■表5
表をみるとわかるのですが初級講座で初めて自作のクラスが登場します。FileSorterがそれです。FileSorterが担当するリストビューの項目を並び替える機能は意外と複雑なのでこのように自作クラスとして独立させました。
では作業に移りましょう。
ソリューションエクスプローラでFolderInfoプロジェクトを右クリックして[追加] - [クラスの追加]を選択してください。
■画像6:クラスの追加
クラス名を入力するダイアログが表示されていますがデフォルトの「Class1」のまま[OK]ボタンをクリックしてクラスを追加します。そうするとプロジェクトにクラスのためのファイルが追加されます。
■画像7:クラス追加後のソリューションエクスプローラ
このClass1をダブルクリックすると次のように記述したプログラムが現れます。
Public
Class Class1
End Class |
■リスト4:クラスの初期状態。このコードはすべて削除する。
これを消してまっさらにして下さい。つまり何もない状態です。
そして、この下のプログラムをコピーして貼り付けてください。
Public Structure
FolderProperty Public Size As Long Public FileCount As Long Public FolderCount As Long End Structure |
Public Enum
ItemImage ClosedFolder = 0 OpenedFolder = 1 File = 2 End Enum |
Public
Class FileSorter Implements IComparer
Private Column As
Integer |
Public
Sub New(ByVal
BindingListView As ListView) Me.BindingListView = BindingListView End Sub |
Public Sub
Execute(ByVal Column As
Integer) Me.Column = Column
If Me.SortOrder = SortOrder.Ascending
Then If IsNothing(BindingListView.ListViewItemSorter) ThenBindingListView.ListViewItemSorter = Me Else BindingListView.Sort() End If End Sub |
Public Function Compare(ByVal
x As Object,
ByVal y As
Object) As
Integer Implements
System.Collections.IComparer.Compare
Dim
strX As String =
CType(x, ListViewItem).SubItems(Column).Text '●[名前]列の場合は単純に比較 If Column = 0 ThenIf SortOrder = SortOrder.Ascending Then Return Comparer.Default.Compare(strX, strY) '昇順 Else Return Comparer.Default.Compare(strY, strX) '降順 End If End If '●[サイズ]列の場合は単位(" KB")を除去して数値として比較
'▼比較できるように形式を整える
If strX = "" Then If strY = "" ThenYValue = -1 ' ""を0より小さい物として扱うための技巧的処理 Else YValue = Left(strY, Len(strY) - UnitLength) '単位(" KB")を除去して数値のみにする。 End If '▼比較実行 If SortOrder = SortOrder.Ascending Then Return Comparer.Default.Compare(XValue, YValue) '昇順 Else Return Comparer.Default.Compare(YValue, XValue) '降順 End If End FunctionEnd Class |
■リスト5
この作業が終わった段階でもう一度実行してみてください。何か問題があればこの段階でエラーが発生します。エラーが発生しなかった場合はここまでの作業はうまくいっています。
これ以降の作業はすべてForm1に対して行います。間違えないようにソリューションエクスプローラでForm1をダブルクリックしてForm1のデザイン画面を開いておいてください。プログラムをコピー&貼り付けするときもClass1ではなくForm1に貼り付けるように注意してください。
いよいよメインのプログラムにとりかかります。この後はまずフォルダツリーを表示できるようにしてから、フォルダの詳細情報一覧表示をできるようにします。その後残った細かい部分を片付けます。
まずフォルダツリーの部分をプログラムする前にツリービューの仕組みについて簡単に説明しておきます。ツリービューはWindowsのエクスプローラのフォルダツリーなどでもみなれているコントロールです。ツリービューでは各項目のことを「ノード」と呼びます。そして多くのノードには親ノードと子ノードが存在すると言う構造になっています。
トップレベルのノードには親ノードが存在しません。トップレベルのノードのことを「ルートノード」とも言います。
フォルダツリーを作成する場合はじめから見えない部分も含めて全フォルダをノードとして追加するわけではありません。全フォルダを追加していたらそれだけで大変な時間がかかってしまいます。フォルダツリーでは必要な部分だけをノードとして追加します。
たとえば、一番初めに追加されるのはコンピュータのドライブを表すノードです。CやDやEなどいくつかのノードが追加されるだけです。ユーザーがCのノードを展開しようとしたときにはじめてCドライブの直下にあるフォルダの一覧がノードに追加されます。
では、具体的にプログラムを開始します。
まずはドライブの一覧をトップレベルのノードして追加するためのShowDriveNodesメソッドを記述します。次のようになります。
'■ShowDriveNodes '■機能:フォルダツリーにドライブを表すルートノードを追加する。 Private Sub ShowDriveNodes()
Dim Drive
As
String For Each Drive In IO.Directory.GetLogicalDrives DriveNode =
New
TreeNode(Drive.Replace("\", ""), ItemImage.ClosedFolder,
ItemImage.OpenedFolder) 'Cドライブを表すノードを選択状態にする。 Next End Sub |
■リスト6:ドライブ一覧をツリービューに追加
ドライブの一覧を取得するためにDirectoryクラスのGetLogicalDrivesメソッド(読み方:GetLogicalDrives = ゲットロジカルドライブス)を使用しています。これはさきほど説明したGetDirectoriesメソッドによるループに似ています。
ここではループを回すごとに変数Driveに"C:\"だとか"D:\"だとかドライブを表す文字列がセットされます。ノードを追加するときは後のことも考えて \ を削除してから追加します。また、追加するときにノードが開いているときと閉じているときのアイコンを指定します。アイコンの指定は番号で行います。この番号はImageList1で指定したアイコンの番号と一致します。
この部分では 0 とか 1 とか直接数値で番号を指定することは避けてItemImage.ClosedFolderのように定義済みの列挙体を通して番号を指定しています。ItemImage列挙体はさきほどClass1にはりつけたプログラムの中に含まれています。直接0とか1とか書いても動作は同じです。
これだけのことを行っているのがこの1行です。この1行は機能が多いですね。
DriveNode = New TreeNode(Drive.Replace("\", ""), ItemImage.ClosedFolder, ItemImage.OpenedFolder)
なお、ノードを表すクラスはTreeNodeクラス(読み方:TreeNode = ツリーノード)です。
はじめからCドライブを選択するようにIf文でCドライブを探す処理もこのメソッドに含まれています。
このメソッドは呼び出されなければ機能しません。フォームのLoadイベントでこのメソッドを呼び出すようにしてください。
Private
Sub Form1_Load(ByVal
sender As
System.Object, ByVal
e As
System.EventArgs) Handles MyBase.Load ShowDriveNodes() End Sub |
■リスト7
参考 Loadイベントの自動生成 フォームのLoadイベントはフォームをダブルクリックすると自動的に生成されますが、今回のプログラムのようにDockプロパティを使ってコントロールが画面いっぱいに配置されている場合フォームをダブルクリックできる場所がないように思えます。 こんなときはフォームのタイトルバーをダブルクリックしてみてください。これでもLoadイベントを自動生成することができます。 |
この段階で実行してみるとフォルダツリーにドライブの一覧が表示されてそれらしくなってきます。
■画像8:ドライブ一覧機能まで完成したところ
今度はツリービューでノードを選択するとその下のフォルダが表示されるようにしてみます。子ノードを追加するためのメソッドAddSubNodesをプログラムに追加してください。
'■AddSubNodes '■機能:フォルダツリーの子ノードにサブフォルダを追加する。 '■引数:ParentNode 対象のノード Private Sub AddSubNodes(ByVal ParentNode As TreeNode) Try
Dim Folder
As
New
IO.DirectoryInfo(ParentNode.FullPath & "\") For
Each oFolder
In
Folder.GetDirectories
Catch ex
As Exception |
■リスト8:フォルダ一覧をツリービューに追加
ただ単にノードを追加するのではなく、実際のフォルダ一覧を見ながらフォルダに対応するノードを追加することになるのでこのようになります。具体的には 先ほど説明したようにGetDirectoriesメソッドによるループを使用します。
このメソッドも呼び出されなければ意味がないので、ツリービューのノード選択時に呼び出すようにします。ツリービューのAfterSelectイベント(読み方:AfterSelect = アフターセレクト)に次の通りプログラムしてください。
'■tvFolders_AfterSelect '■[フォルダツリー]ノード選択時 '■機能:子ノードを追加し、フォルダ一覧を表示する。 Private Sub tvFolders_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tvFolders.AfterSelect '▼このノードがはじめて選択された場合は子ノードを追加する。
If
e.Node.GetNodeCount(False)
= 0 Then StatusBar1.Text = e.Node.FullPath End Sub |
■リスト9
ノードが選択されたときにいつでもフォルダの一覧を追加していては時間がもったいないのではじめてノードを選択したときだけフォルダ一覧を追加するようにしています。はじめてかどうかは子ノードがあるかないかで判断しています。ですから子フォルダがないフォルダのノードをクリックしたときは何度もAddSubNodesが呼ばれてしまいますが子フォルダのないのですからそれほど問題はありません。
子ノードが数はTreeNodeクラスのGetNodeCountメソッド(読み方:GetNodeCount = ゲットノードカウント)で取得できます。選択されたノードはこのイベントのTreeViewEventArgsクラス(読み方:TreeViewEventArgs = ツリービューイベントオーグス)である第2引数のNodeプロパティ(読み方:Node = ノード)で取得できます。
このイベントではついでに現在のノードをフルパスをステータスバーに表示します。
ここでも実際に実行して動作を確認してみてください。どうでしょうか?Windowsのエクスプローラと同じようにフォルダをたどることができましたか?
以上でフォルダツリーに関するプログラムは終了です。フォルダツリーはいろいろなソフトで使われるのでこの節で解説している手法を覚えておくと何かと重宝です。
それではメイン機能であるフォルダの詳細表示部分を作りましょう。ツリービューで選択したフォルダの内容をリストビューで一覧表示する機能です。
まず、フォルダのサイズ・ファイル数・フォルダ数を取得するために以下のGetFolderProperty関数を追加してください。
'■GetFolderProperty '■機能:フォルダのサイズ・ファイル数・フォルダ数を取得する。 '■引数:FolderName 対象のフォルダのフルパス。末尾に \ が必要。 '■備考:サイズの単位はバイト Private Function GetFolderProperty(ByVal FolderName As String) As FolderProperty
Dim Folder
As New
IO.DirectoryInfo(FolderName) Try
For
Each oFile In
Folder.GetFiles()
For
Each oFolder In
Folder.GetDirectories()
Catch ex
As System.UnauthorizedAccessException Return Detail End Function |
■リスト10:フォルダ情報取得
この関数は初級講座の現段階では複雑すぎるので詳しくは触れません。
簡単に説明します。まず、この関数はサイズ・ファイル数・フォルダ数と3つの値を返したいので戻り値の型はFolderProperty型にしました。さきほどClass1に貼り付けてもらったコードの中にFolderPropertyがあったことを思い出してください。
具体的な処理内容を見ると、ここでもDirectoryInfoクラスのGetFilesメソッドとGetDirectoriesメソッドを使ったループが登場しています。ファイルのループではファイルサイズをどんどん足し算していきます。ファイル数(FileCount)も1ずつ足していきます。フォルダのループではフォルダのサイズ・ファイル数・フォルダ数をどんどん足していきます。ここでフォルダのサイズ・ファイル数・フォルダ数を取得するためにこの関数は自分自身を呼び出しているところがポイントです。このように自分で自分を呼び出す処理を再帰処理を呼びます。
なお、Windowsのアクセス権のないフォルダを対象とした場合セキュリティ上の理由でエラーが発生します。今回はこのエラーは無視しているのでアクセス権のないフォルダに対しては計算結果が正確でなくなりますので注意してください。
次に、この関数を利用してフォルダやファイルの詳細情報を一覧に表示するためのListFolderItemsメソッドを次の通り記述してください。
'■ListFolderItems '■機能:一覧(lvFolder)にフォルダ・ファイルを表示する。 '■引数:FolderPath 対象のフォルダのフルパス。末尾に \ はつけない。 '■ WithDetail フォルダの詳細情報を表示する場合True。 Private Sub ListFolderItems(ByVal FolderPath As String, Optional ByVal WithDetail As Boolean = False)
Dim Folder
As New
IO.DirectoryInfo(FolderPath & "\") lvFolder.BeginUpdate() '●サブフォルダの情報を取得・表示 For Each oFolder In Folder.GetDirectories ListRow = New ListViewItem(oFolder.Name, ItemImage.ClosedFolder) '名前
If WithDetail
Then lvFolder.Items.Add(ListRow) Next '●ファイルの情報を取得・表示
For
Each oFile In Folder.GetFiles lvFolder.EndUpdate() End Sub |
■リスト11:一覧を追加
少し長いですがやっていることは単純です。まずフォルダの一覧でループを回し、必要な情報を追加した上で、ファイルの一覧でループを回し同様に情報を追加します。ここのループもやはりGetDirectoriesメソッドとGetFilesメソッドを利用しています。
リストビューに項目を追加するにはリストボックスと同じでItems.Addメソッドを指定します。ただし、ここでは単に文字列を追加するわけではなく、名前・サイズ・ファイル数・フォルダ数のまとまりを1項目として登録したいので、Addメソッドを呼び出す前にこれらの内容を含んだ項目を作成しておきます。それがListRowです。なお、項目のうち1つがメインアイテムで残りのサブアイテムという扱いになります。ここでは名前をメインアイテムとし、残りをサブアイテムとしていますので処理の方法も名前とそれ以外では少しだけ違います。
このメソッドでは第2引数のWithDetailにTrueが指定された場合だけフォルダの詳細情報を取得するために先ほどのGetFolderProperty関数を呼び出します。
サイズに関してはKB単位で表示したいので 1024 で割り算をします。ご存知だとは思いますがファイルのサイズは1024B = 1KBという関係があります。記号「\」 はわり算の答えを返す演算子です。サイズが1000KBを超える場合には「1,000KB」のように「 , 」を区切り文字として表示したいのでFormat関数(読み方:Format = フォーマット)を使って区切り文字の挿入を命令しています。
これで準備完了ですね。あとはこのメソッドを呼び出す部分を作りましょう。このメソッドもツリービューの項目が選択されたときに呼び出せばよいのでツリービューのAfterSelectメソッドに次の通り1行(コメントを含めると2行)追加してください。
'▼このノードのフォルダ一覧(lvFolder)を表示する。 Call ListFolderItems(e.Node.FullPath, chkDetail.Checked) |
■リスト12
第2引数がchkDetail.Checledになっていることに注意してください。つまり、「自動的に詳細を表示する」のチェックボックスがチェックされているときは第2引数はTrueになり、そうでないときはFalseになります。
それから、「詳細表示」ボタンをクリックしたときには強制的に詳細を表示したいのでこのボタンのクリックイベントにも次の通り追加してください。
'■[詳細表示]ボタン '■機能:一覧(lvFolder)に詳細情報を表示する。 Private Sub btnDetail_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDetail.Click ListFolderItems(StatusBar1.Text, True) End Sub |
■リスト13
ここではステータスバーに表示されているフルパスを利用してさきほごのメソッドを呼び出しています。
さぁ、ここまでの状態で実行してみましょう。一覧にフォルダの情報がちゃんと表示されますか?チェックボックスをチェックしてみたりボタンをクリックしてみたりいろいろ試してください。
ただし、フォルダの詳細情報を表示するときにはかなり計算に時間がかかる可能性があるので注意してください。
ここまでで主要な機能はすべて完成しました。今ではフォルダのサイズを一覧形式でみることができます。便利なものではありませんか。
後は細かい機能を付け足していきましょう。まずは並び替え機能です。並び替えのことを「ソート」とも言います。
並び替えのためには最初にClass1に用意したFileSorterクラスを使えばよいだけなので楽です。
まず、クラスレベルでFileSorter型の変数を宣言してください。次にフォームのLoadイベントでFileSorterをインスタンシングします。ここまでのコードは次の通りです。
Private
Sorter As
FileSorter '一覧を昇順・降順で並び替えるためのクラス '■[フォーム] Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Sorter =
New
FileSorter(lvFolder) End Sub |
■リスト14:FileSorterのインスタンシング
後はリストビューの列ヘッダ(列見出し)がクリックされたときにFileSorterのExecuteメソッドを呼び出せば完了です。列ヘッダがクリックされるとColumnClickイベント(読み方:ColumnClick = カラムクリック)が発生します。Executeメソッドにはどの列を基準に並び替えを実行するのかを指定します。クリックされた列は例によってイベントの第2引数のColumnプロパティ(読み方:Column = カラム)でわかります。
'■lvFolder_ColumnClick '■[一覧]列タイトルクリック時 '■機能:クリックされた列を基準に並び替えを行う。 Private Sub lvFolder_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lvFolder.ColumnClick
lvFolder.BeginUpdate() End Sub |
■リスト15
BeginUpdateメソッド(読み方:BeginUpdate = ビギンアップデイト)とEndUpdateメソッド(読み方:EndUpdate = エンドアップデイト)メソッドがあると描画処理を高速になります。
最後にリストビューで項目をダブルクリックしたときにその項目を開く機能をプログラムします。たとえば、フォルダをダブルクリックするとエクスプローラが起動してそのフォルダを開きます。ファイルをクリックすると関連付けられたアプリケーションが起動してファイルを開きます。テキストファイルならメモ帳が起動しますし、mp3ファイルならMedia Player等が起動します。
この処理はProcessクラス(読み方:Process = プロセス)のStartメソッド(読み方:Start = スタート)を使うと驚くほど簡単に記述できます。次の通りです。
'■lvFolder_DoubleClick '■[一覧]アイテムダブルクリック時 '■機能:アイテムを開く。 Private Sub lvFolder_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lvFolder.DoubleClick Dim Path As String
Try |
■リスト16
ここまで読んでくれた方ありがとうございます。実際に手順どおりにソフトを作ってくださった方おつかれさまです。掲示板に質問や感想などお寄せくださると嬉しいです。
このソフトを改造してオリジナルな機能を追加してみると楽しいかもしれませんね。サイズやファイル数のほかの有用な情報が表示されるようにしてみると良いかもしれません。たとえば、拡張子別ファイル数、ファイルの平均サイズ、属性別ファイル数など。いいものができたら是非投稿してください。
今回出てきたファイル処理やFor Each 〜 Nextループなどは初級講座第4章で扱う予定です。