C#Winform开发,Listview根据文件路径或扩展名显示系统文件图标

来源:互联网 发布:网络小说 毒 知乎 编辑:程序博客网 时间:2024/06/08 15:17

在Winform开发中,大家普遍利用Listview来显示文件列表。 但是Listview本身并不具备显示当前系统图标的功能。所以要想实现类似的功能,需要利用Icon和Imagelist来辅助。

1, 实例一个imagelist作为图标管理容器。

2, 根据文件绝对路径将对应的系统图标加入imagelist

3, 将listview的显示属性View修改为:SmallIcon

4, 获取对应图标的index 并赋值给ListViewItem


源代码如下:

using System.Linq;using System.Text;using System.Windows.Forms;using System.IO;namespace ListViewDemo{    public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();        }        private void button1_Click(object sender, EventArgs e)        {            listView1.Items.Clear();            string DemoFolder = "c:\\listview";            DirectoryInfo  di = new DirectoryInfo(DemoFolder);            //get all fileinfo in the demo folder            foreach (FileInfo f in di.GetFiles())            {                //add system icon of current file into imagelist                if (!imageList1.Images.Keys.Contains(f.Extension))                {                    imageList1.Images.Add(f.Extension, Icon.ExtractAssociatedIcon(f.FullName));                }                ListViewItem lvi = new ListViewItem();                lvi.Text = f.Name;                //get imageindex from imagelist according to the file extension                lvi.ImageIndex = imageList1.Images.Keys.IndexOf(f.Extension);                listView1.Items.Add(lvi);            }        }    }}
效果图:



对于一些非当前系统中的文件,如果没有文件绝对路径,只知道文件扩展名,就需要再添加一个自定义的类。 根据文件扩展名来获取对应的图标。

1, 获取文件扩展名,

2,根据文件扩展名来获取系统图标,

3, 将listview的显示属性View修改为:SmallIcon

4, 获取对应图标的index 并赋值给ListViewItem

首先是自定义的类:

using System;using System.Drawing;using System.Runtime.InteropServices;using Microsoft.Win32;using System.Reflection;using System.Collections.Generic;namespace ALM_Resource_Sync.Lib{    public static class Icons    {        #region Custom exceptions class        public class IconNotFoundException : Exception        {            public IconNotFoundException(string fileName, int index)                : base(string.Format("Icon with Id = {0} wasn't found in file {1}", index, fileName))            {            }        }        public class UnableToExtractIconsException : Exception        {            public UnableToExtractIconsException(string fileName, int firstIconIndex, int iconCount)                : base(string.Format("Tryed to extract {2} icons starting from the one with id {1} from the \"{0}\" file but failed", fileName, firstIconIndex, iconCount))            {            }        }        #endregion        #region DllImports        /// <summary>        /// Contains information about a file object.         /// </summary>        struct SHFILEINFO        {            /// <summary>            /// Handle to the icon that represents the file. You are responsible for            /// destroying this handle with DestroyIcon when you no longer need it.             /// </summary>            public IntPtr hIcon;            /// <summary>            /// Index of the icon image within the system image list.            /// </summary>            public IntPtr iIcon;            /// <summary>            /// Array of values that indicates the attributes of the file object.            /// For information about these values, see the IShellFolder::GetAttributesOf            /// method.            /// </summary>            public uint dwAttributes;            /// <summary>            /// String that contains the name of the file as it appears in the Microsoft            /// Windows Shell, or the path and file name of the file that contains the            /// icon representing the file.            /// </summary>            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]            public string szDisplayName;            /// <summary>            /// String that describes the type of file.            /// </summary>            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]            public string szTypeName;        };        [Flags]        enum FileInfoFlags : int        {            /// <summary>            /// Retrieve the handle to the icon that represents the file and the index             /// of the icon within the system image list. The handle is copied to the             /// hIcon member of the structure specified by psfi, and the index is copied             /// to the iIcon member.            /// </summary>            SHGFI_ICON = 0x000000100,            /// <summary>            /// Indicates that the function should not attempt to access the file             /// specified by pszPath. Rather, it should act as if the file specified by             /// pszPath exists with the file attributes passed in dwFileAttributes.            /// </summary>            SHGFI_USEFILEATTRIBUTES = 0x000000010        }        /// <summary>        ///     Creates an array of handles to large or small icons extracted from        ///     the specified executable file, dynamic-link library (DLL), or icon        ///     file.         /// </summary>        /// <param name="lpszFile">        ///     Name of an executable file, DLL, or icon file from which icons will        ///     be extracted.        /// </param>        /// <param name="nIconIndex">        ///     <para>        ///         Specifies the zero-based index of the first icon to extract. For        ///         example, if this value is zero, the function extracts the first        ///         icon in the specified file.        ///     </para>        ///     <para>        ///         If this value is �1 and <paramref name="phiconLarge"/> and        ///         <paramref name="phiconSmall"/> are both NULL, the function returns        ///         the total number of icons in the specified file. If the file is an        ///         executable file or DLL, the return value is the number of        ///         RT_GROUP_ICON resources. If the file is an .ico file, the return        ///         value is 1.         ///     </para>        ///     <para>        ///         Windows 95/98/Me, Windows NT 4.0 and later: If this value is a         ///         negative number and either <paramref name="phiconLarge"/> or         ///         <paramref name="phiconSmall"/> is not NULL, the function begins by        ///         extracting the icon whose resource identifier is equal to the        ///         absolute value of <paramref name="nIconIndex"/>. For example, use -3        ///         to extract the icon whose resource identifier is 3.         ///     </para>        /// </param>        /// <param name="phIconLarge">        ///     An array of icon handles that receives handles to the large icons        ///     extracted from the file. If this parameter is NULL, no large icons        ///     are extracted from the file.        /// </param>        /// <param name="phIconSmall">        ///     An array of icon handles that receives handles to the small icons        ///     extracted from the file. If this parameter is NULL, no small icons        ///     are extracted from the file.         /// </param>        /// <param name="nIcons">        ///     Specifies the number of icons to extract from the file.         /// </param>        /// <returns>        ///     If the <paramref name="nIconIndex"/> parameter is -1, the        ///     <paramref name="phIconLarge"/> parameter is NULL, and the        ///     <paramref name="phiconSmall"/> parameter is NULL, then the return        ///     value is the number of icons contained in the specified file.        ///     Otherwise, the return value is the number of icons successfully        ///     extracted from the file.         /// </returns>        [DllImport("Shell32", CharSet = CharSet.Auto)]        extern static int ExtractIconEx(            [MarshalAs(UnmanagedType.LPTStr)]             string lpszFile,            int nIconIndex,            IntPtr[] phIconLarge,            IntPtr[] phIconSmall,            int nIcons);        [DllImport("Shell32", CharSet = CharSet.Auto)]        extern static IntPtr SHGetFileInfo(            string pszPath,            int dwFileAttributes,            out SHFILEINFO psfi,            int cbFileInfo,            FileInfoFlags uFlags);        #endregion        /// <summary>        /// Two constants extracted from the FileInfoFlags, the only that are        /// meaningfull for the user of this class.        /// </summary>        public enum SystemIconSize : int        {            Large = 0x000000000,            Small = 0x000000001        }        /// <summary>        /// Get the number of icons in the specified file.        /// </summary>        /// <param name="fileName">Full path of the file to look for.</param>        /// <returns></returns>        static int GetIconsCountInFile(string fileName)        {            return ExtractIconEx(fileName, -1, null, null, 0);        }        #region ExtractIcon-like functions        public static void ExtractEx(string fileName, List<Icon> largeIcons,            List<Icon> smallIcons, int firstIconIndex, int iconCount)        {            /*             * Memory allocations             */            IntPtr[] smallIconsPtrs = null;            IntPtr[] largeIconsPtrs = null;            if (smallIcons != null)            {                smallIconsPtrs = new IntPtr[iconCount];            }            if (largeIcons != null)            {                largeIconsPtrs = new IntPtr[iconCount];            }            /*             * Call to native Win32 API             */            int apiResult = ExtractIconEx(fileName, firstIconIndex, largeIconsPtrs, smallIconsPtrs, iconCount);            if (apiResult != iconCount)            {                throw new UnableToExtractIconsException(fileName, firstIconIndex, iconCount);            }            /*             * Fill lists             */            if (smallIcons != null)            {                smallIcons.Clear();                foreach (IntPtr actualIconPtr in smallIconsPtrs)                {                    smallIcons.Add(Icon.FromHandle(actualIconPtr));                }            }            if (largeIcons != null)            {                largeIcons.Clear();                foreach (IntPtr actualIconPtr in largeIconsPtrs)                {                    largeIcons.Add(Icon.FromHandle(actualIconPtr));                }            }        }        public static List<Icon> ExtractEx(string fileName, SystemIconSize size,            int firstIconIndex, int iconCount)        {            List<Icon> iconList = new List<Icon>();            switch (size)            {                case SystemIconSize.Large:                    ExtractEx(fileName, iconList, null, firstIconIndex, iconCount);                    break;                case SystemIconSize.Small:                    ExtractEx(fileName, null, iconList, firstIconIndex, iconCount);                    break;                default:                    throw new ArgumentOutOfRangeException("size");            }            return iconList;        }        public static void Extract(string fileName, List<Icon> largeIcons, List<Icon> smallIcons)        {            int iconCount = GetIconsCountInFile(fileName);            ExtractEx(fileName, largeIcons, smallIcons, 0, iconCount);        }        public static List<Icon> Extract(string fileName, SystemIconSize size)        {            int iconCount = GetIconsCountInFile(fileName);            return ExtractEx(fileName, size, 0, iconCount);        }        public static Icon ExtractOne(string fileName, int index, SystemIconSize size)        {            try            {                List<Icon> iconList = ExtractEx(fileName, size, index, 1);                return iconList[0];            }            catch (UnableToExtractIconsException)            {                throw new IconNotFoundException(fileName, index);            }        }        public static void ExtractOne(string fileName, int index,            out Icon largeIcon, out Icon smallIcon)        {            List<Icon> smallIconList = new List<Icon>();            List<Icon> largeIconList = new List<Icon>();            try            {                ExtractEx(fileName, largeIconList, smallIconList, index, 1);                largeIcon = largeIconList[0];                smallIcon = smallIconList[0];            }            catch (UnableToExtractIconsException)            {                throw new IconNotFoundException(fileName, index);            }        }        #endregion        //this will look throw the registry         //to find if the Extension have an icon.        public static Icon IconFromExtension(string extension,                                                SystemIconSize size)        {            // Add the '.' to the extension if needed            if (extension[0] != '.') extension = '.' + extension;            //opens the registry for the wanted key.            RegistryKey Root = Registry.ClassesRoot;            RegistryKey ExtensionKey = Root.OpenSubKey(extension);            ExtensionKey.GetValueNames();            RegistryKey ApplicationKey =                Root.OpenSubKey(ExtensionKey.GetValue("").ToString());            //gets the name of the file that have the icon.            string IconLocation =                ApplicationKey.OpenSubKey("DefaultIcon").GetValue("").ToString();            string[] IconPath = IconLocation.Split(',');            if (IconPath[1] == null) IconPath[1] = "0";            IntPtr[] Large = new IntPtr[1], Small = new IntPtr[1];            //extracts the icon from the file.            ExtractIconEx(IconPath[0],                Convert.ToInt16(IconPath[1]), Large, Small, 1);            return size == SystemIconSize.Large ?                Icon.FromHandle(Large[0]) : Icon.FromHandle(Small[0]);        }        public static Icon IconFromExtensionShell(string extension, SystemIconSize size)        {            //add '.' if nessesry            if (extension[0] != '.') extension = '.' + extension;            //temp struct for getting file shell info            SHFILEINFO fileInfo = new SHFILEINFO();            SHGetFileInfo(                extension,                0,                out fileInfo,                Marshal.SizeOf(fileInfo),                FileInfoFlags.SHGFI_ICON | FileInfoFlags.SHGFI_USEFILEATTRIBUTES | (FileInfoFlags)size);            return Icon.FromHandle(fileInfo.hIcon);        }        public static Icon IconFromResource(string resourceName)        {            Assembly assembly = Assembly.GetCallingAssembly();            return new Icon(assembly.GetManifestResourceStream(resourceName));        }        /// <summary>        /// Parse strings in registry who contains the name of the icon and        /// the index of the icon an return both parts.        /// </summary>        /// <param name="regString">The full string in the form "path,index" as found in registry.</param>        /// <param name="fileName">The "path" part of the string.</param>        /// <param name="index">The "index" part of the string.</param>        public static void ExtractInformationsFromRegistryString(            string regString, out string fileName, out int index)        {            if (regString == null)            {                throw new ArgumentNullException("regString");            }            if (regString.Length == 0)            {                throw new ArgumentException("The string should not be empty.", "regString");            }            index = 0;            string[] strArr = regString.Replace("\"", "").Split(',');            fileName = strArr[0].Trim();            if (strArr.Length > 1)            {                int.TryParse(strArr[1].Trim(), out index);            }        }        public static Icon ExtractFromRegistryString(string regString, SystemIconSize size)        {            string fileName;            int index;            ExtractInformationsFromRegistryString(regString, out fileName, out index);            return ExtractOne(fileName, index, size);        }    }}

然后是示例代码:
 private void button2_Click(object sender, EventArgs e)        {            listView1.Items.Clear();            //demo file list            string [] DemoFiles = {"demo.doc","demo.xls","demo.txt"};            foreach (string fileName in DemoFiles)            {                //get file extention                string[] arrtempFileName = fileName.Split(new char[] { '.' });                string tempFileExtension = "." + arrtempFileName[arrtempFileName.Length - 1];                //add system icon of current file into imagelist                if (!imageList1.Images.Keys.Contains(tempFileExtension))                {                    imageList1.Images.Add(tempFileExtension, Icons.IconFromExtension(tempFileExtension, Icons.SystemIconSize.Small));                }                ListViewItem lvi = new ListViewItem();                lvi.Text = fileName;                //get imageindex from imagelist according to the file extension                lvi.ImageIndex = imageList1.Images.Keys.IndexOf(tempFileExtension);                listView1.Items.Add(lvi);            }

显示效果如下:



原创粉丝点击