【轉】 C# ListView實例:文件圖標顯示 shell
說明:本例將目錄中的文件顯示在窗體的ListView控件中,並定義了多種視圖瀏覽。經過調用Win32庫函數實現圖標數據的提取。函數
public partial class Form1 : Form { FileInfoList fileList; public Form1() { InitializeComponent(); } private void 加載文件ToolStripMenuItem_Click(object sender, EventArgs e) { FolderBrowserDialog dlg = new FolderBrowserDialog(); if (dlg.ShowDialog() == DialogResult.OK) { string[] filespath = Directory.GetFiles(dlg.SelectedPath); fileList = new FileInfoList(filespath); InitListView(); } } private void InitListView() { listView1.Items.Clear(); this.listView1.BeginUpdate(); foreach (FileInfoWithIcon file in fileList.list) { ListViewItem item = new ListViewItem(); item.Text = file.fileInfo.Name.Split('.')[0]; item.ImageIndex = file.iconIndex; item.SubItems.Add(file.fileInfo.LastWriteTime.ToString()); item.SubItems.Add(file.fileInfo.Extension.Replace(".","")); item.SubItems.Add(string.Format(("{0:N0}"), file.fileInfo.Length)); listView1.Items.Add(item); } listView1.LargeImageList = fileList.imageListLargeIcon; listView1.SmallImageList = fileList.imageListSmallIcon; listView1.Show(); this.listView1.EndUpdate(); } private void 大圖標ToolStripMenuItem_Click(object sender, EventArgs e) { listView1.View = View.LargeIcon; } private void 小圖標ToolStripMenuItem_Click(object sender, EventArgs e) { listView1.View = View.SmallIcon; } private void 平鋪ToolStripMenuItem_Click(object sender, EventArgs e) { listView1.View = View.Tile; } private void 列表ToolStripMenuItem_Click(object sender, EventArgs e) { listView1.View = View.List; } private void 詳細信息ToolStripMenuItem_Click(object sender, EventArgs e) { listView1.View = View.Details; } }
class FileInfoList { public List<FileInfoWithIcon> list; public ImageList imageListLargeIcon; public ImageList imageListSmallIcon; /// <summary> /// 根據文件路徑獲取生成文件信息,並提取文件的圖標 /// </summary> /// <param name="filespath"></param> public FileInfoList(string[] filespath) { list = new List<FileInfoWithIcon>(); imageListLargeIcon = new ImageList(); imageListLargeIcon.ImageSize = new Size(32, 32); imageListSmallIcon = new ImageList(); imageListSmallIcon.ImageSize = new Size(16, 16); foreach (string path in filespath) { FileInfoWithIcon file = new FileInfoWithIcon(path); imageListLargeIcon.Images.Add(file.largeIcon); imageListSmallIcon.Images.Add(file.smallIcon); file.iconIndex = imageListLargeIcon.Images.Count - 1; list.Add(file); } } } class FileInfoWithIcon { public FileInfo fileInfo; public Icon largeIcon; public Icon smallIcon; public int iconIndex; public FileInfoWithIcon(string path) { fileInfo = new FileInfo(path); largeIcon = GetSystemIcon.GetIconByFileName(path, true); if (largeIcon == null) largeIcon = GetSystemIcon.GetIconByFileType(Path.GetExtension(path), true); smallIcon = GetSystemIcon.GetIconByFileName(path, false); if (smallIcon == null) smallIcon = GetSystemIcon.GetIconByFileType(Path.GetExtension(path), false); } }
public static class GetSystemIcon { /// <summary> /// 依據文件名讀取圖標,若指定文件不存在,則返回空值。 /// </summary> /// <param name="fileName">文件路徑</param> /// <param name="isLarge">是否返回大圖標</param> /// <returns></returns> public static Icon GetIconByFileName(string fileName, bool isLarge = true) { int[] phiconLarge = new int[1]; int[] phiconSmall = new int[1]; //文件名 圖標索引 Win32.ExtractIconEx(fileName, 0, phiconLarge, phiconSmall, 1); IntPtr IconHnd = new IntPtr(isLarge ? phiconLarge[0] : phiconSmall[0]); if (IconHnd.ToString() == "0") return null; return Icon.FromHandle(IconHnd); } /// <summary> /// 根據文件擴展名(如:.*),返回與之關聯的圖標。 /// 若不以"."開頭則返回文件夾的圖標。 /// </summary> /// <param name="fileType">文件擴展名</param> /// <param name="isLarge">是否返回大圖標</param> /// <returns></returns> public static Icon GetIconByFileType(string fileType, bool isLarge) { if (fileType == null || fileType.Equals(string.Empty)) return null; RegistryKey regVersion = null; string regFileType = null; string regIconString = null; string systemDirectory = Environment.SystemDirectory + "\\"; if (fileType[0] == '.') { //讀系統註冊表中文件類型信息 regVersion = Registry.ClassesRoot.OpenSubKey(fileType, false); if (regVersion != null) { regFileType = regVersion.GetValue("") as string; regVersion.Close(); regVersion = Registry.ClassesRoot.OpenSubKey(regFileType + @"\DefaultIcon", false); if (regVersion != null) { regIconString = regVersion.GetValue("") as string; regVersion.Close(); } } if (regIconString == null) { //沒有讀取到文件類型註冊信息,指定爲未知文件類型的圖標 regIconString = systemDirectory + "shell32.dll,0"; } } else { //直接指定爲文件夾圖標 regIconString = systemDirectory + "shell32.dll,3"; } string[] fileIcon = regIconString.Split(new char[] { ',' }); if (fileIcon.Length != 2) { //系統註冊表中註冊的標圖不能直接提取,則返回可執行文件的通用圖標 fileIcon = new string[] { systemDirectory + "shell32.dll", "2" }; } Icon resultIcon = null; try { //調用API方法讀取圖標 int[] phiconLarge = new int[1]; int[] phiconSmall = new int[1]; uint count = Win32.ExtractIconEx(fileIcon[0], Int32.Parse(fileIcon[1]), phiconLarge, phiconSmall, 1); IntPtr IconHnd = new IntPtr(isLarge ? phiconLarge[0] : phiconSmall[0]); resultIcon = Icon.FromHandle(IconHnd); } catch { } return resultIcon; } } /// <summary> /// 定義調用的API方法 /// </summary> class Win32 { [DllImport("shell32.dll")] public static extern uint ExtractIconEx(string lpszFile, int nIconIndex, int[] phiconLarge, int[] phiconSmall, uint nIcons); }