using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// DllImportに必要
using System.Runtime.InteropServices;
namespace Explorer
{
public partial class Form1 : Form
{
///
/// ファイル情報を取得
///
///
///
///
///
///
///
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint uFlags);
///
/// イメージリストを登録
///
///
///
///
///
///
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
///
/// SHGetFileInfo関数で使用する構造体
///
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
// ファイル情報用
private const int SHGFI_LARGEICON = 0x00000000;
private const int SHGFI_SMALLICON = 0x00000001;
private const int SHGFI_USEFILEATTRIBUTES = 0x00000010;
private const int SHGFI_OVERLAYINDEX = 0x00000040;
private const int SHGFI_ICON = 0x00000100;
private const int SHGFI_SYSICONINDEX = 0x00004000;
private const int SHGFI_TYPENAME = 0x000000400;
// TreeView用
private const int TVSIL_NORMAL = 0x0000;
private const int TVSIL_STATE = 0x0002;
private const int TVM_SETIMAGELIST = 0x1109;
// ListView用
private const int LVSIL_NORMAL = 0;
private const int LVSIL_SMALL = 1;
private const int LVM_SETIMAGELIST = 0x1003;
// 選択された項目を保持
private String selectedItem = "";
public Form1()
{
InitializeComponent();
// イメージリストの設定
SHFILEINFO shFileInfo = new SHFILEINFO();
IntPtr imageListHandle = SHGetFileInfo(String.Empty, 0, out shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_SMALLICON | SHGFI_SYSICONINDEX);
// TreeView
SendMessage(treeView1.Handle, TVM_SETIMAGELIST, new IntPtr(TVSIL_NORMAL), imageListHandle);
// ListView
SendMessage(listView1.Handle, LVM_SETIMAGELIST, new IntPtr(LVSIL_SMALL), imageListHandle);
// ドライブ一覧を走査してツリーに追加
foreach (String drive in Environment.GetLogicalDrives())
{
// アイコンの取得
int iconIndex = 0;
IntPtr hSuccess = SHGetFileInfo(drive, 0, out shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_SYSICONINDEX);
if (hSuccess != IntPtr.Zero)
{
iconIndex = shFileInfo.iIcon;
}
// 新規ノード作成
// プラスボタンを表示するため空のノードを追加しておく
TreeNode node = new TreeNode(drive, iconIndex, iconIndex);
node.Nodes.Add(new TreeNode());
treeView1.Nodes.Add(node);
}
// 初期選択ドライブの内容を表示
setListItem(Environment.GetLogicalDrives().First());
}
///
/// ファイルサイズを単位付きに変換して返します.
///
///
///
private String getFileSize(long fileSize)
{
String ret = fileSize + " バイト";
if (fileSize > (1024f * 1024f * 1024f))
{
ret = Math.Round((fileSize / 1024f / 1024f / 1024f), 2).ToString() + " GB";
}
else if (fileSize > (1024f * 1024f))
{
ret = Math.Round((fileSize / 1024f / 1024f), 2).ToString() + " MB";
}
else if (fileSize > 1024f)
{
ret = Math.Round((fileSize / 1024f)).ToString() + " KB";
}
return ret;
}
///
/// リストビューの項目を設定します.
///
private void setListItem(String filePath)
{
// リストビューのヘッダーを設定
listView1.View = View.Details;
listView1.Clear();
listView1.Columns.Add("名前");
listView1.Columns.Add("種類");
listView1.Columns.Add("更新日時");
listView1.Columns.Add("サイズ");
try
{
// フォルダ一覧
DirectoryInfo dirList = new DirectoryInfo(filePath);
foreach (DirectoryInfo di in dirList.GetDirectories())
{
ListViewItem item = new ListViewItem(di.Name);
// フォルダ種類、アイコンの取得
String type = "";
int iconIndex = 0;
SHFILEINFO shFileInfo = new SHFILEINFO();
IntPtr hSuccess = SHGetFileInfo(di.FullName, 0, out shFileInfo, (uint)Marshal.SizeOf(shFileInfo),
SHGFI_ICON | SHGFI_LARGEICON | SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
if (hSuccess != IntPtr.Zero)
{
type = shFileInfo.szTypeName;
iconIndex = shFileInfo.iIcon;
}
// 各列の内容を設定
item.ImageIndex = iconIndex;
item.SubItems.Add(type);
item.SubItems.Add(String.Format("{0:yyyy/MM/dd HH:mm:ss}", di.LastAccessTime));
item.SubItems.Add("");
// リストに追加
listView1.Items.Add(item);
}
// ファイル一覧
List files = Directory.GetFiles(filePath).ToList();
foreach (String file in files)
{
FileInfo info = new FileInfo(file);
ListViewItem item = new ListViewItem(info.Name);
// ファイル種類、アイコンの取得
String type = "";
int iconIndex = 0;
SHFILEINFO shinfo = new SHFILEINFO();
IntPtr hSuccess = SHGetFileInfo(info.FullName, 0, out shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON | SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
if (hSuccess != IntPtr.Zero)
{
type = shinfo.szTypeName;
iconIndex = shinfo.iIcon;
}
// 各列の内容を設定
item.ImageIndex = iconIndex;
item.SubItems.Add(type);
item.SubItems.Add(String.Format("{0:yyyy/MM/dd HH:mm:ss}", info.LastAccessTime));
item.SubItems.Add(getFileSize(info.Length));
listView1.Items.Add(item);
}
}
catch (IOException ie)
{
MessageBox.Show(ie.Message, "選択エラー");
}
// 列幅を自動調整
listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
}
///
/// ツリービュー項目展開時(前)のイベントハンドラ.
///
///
///
private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
TreeNode node = e.Node;
node.Nodes.Clear();
try
{
DirectoryInfo dirList = new DirectoryInfo(node.FullPath);
foreach (DirectoryInfo di in dirList.GetDirectories())
{
// フォルダのアイコンを取得
SHFILEINFO shinfo = new SHFILEINFO();
int iconIndex = 0;
IntPtr hSuccess = SHGetFileInfo(di.FullName, 0, out shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON | SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
if (hSuccess != IntPtr.Zero)
{
iconIndex = shinfo.iIcon;
}
// 子を追加してノードを展開
TreeNode child = new TreeNode(di.Name, shinfo.iIcon, shinfo.iIcon);
child.ImageIndex = iconIndex;
child.Nodes.Add(new TreeNode());
node.Nodes.Add(child);
}
}
catch (IOException ie)
{
MessageBox.Show(ie.Message, "選択エラー");
}
}
///
/// ツリービュー項目選択時(前)のイベントハンドラ.
///
///
///
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
setListItem(e.Node.FullPath);
}
}
}