C# 获得系统文件图片的 改进方式

这是在网上看到的一段代码 用来获得系统文件对应的图标  ,仅以获得小图标为列  
        
        #region DLLIMPORT
        // Retrieves information about an object in the file system,
        // such as a file, a folder, a directory, or a drive root.
        [DllImport("shell32",
          EntryPoint = "SHGetFileInfo",
          ExactSpelling = false,
          CharSet = CharSet.Auto,
          SetLastError = true)]
        private static extern IntPtr SHGetFileInfo(
         string pszPath,      //指定的文件名
         FILE_ATTRIBUTE dwFileAttributes, //文件属性
         ref SHFILEINFO sfi,     //返回获得的文件信息,是一个记录类型
         int cbFileInfo,      //文件的类型名
         SHGFI uFlags);
        #endregion

        #region STRUCTS
        // Contains information about a file object
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct SHFILEINFO
        {
            public IntPtr hIcon;    //文件的图标句柄
            public IntPtr iIcon;    //图标的系统索引号
            public uint dwAttributes;   //文件的属性值
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;  //文件的显示名
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;   //文件的类型名
        };
        #endregion
        #region Enums
        // Flags that specify the file information to retrieve with SHGetFileInfo
        [Flags]
        public enum SHGFI : uint
        {
            ADDOVERLAYS = 0x20,
            ATTR_SPECIFIED = 0x20000,
            ATTRIBUTES = 0x800,   //获得属性
            DISPLAYNAME = 0x200,  //获得显示名
            EXETYPE = 0x2000,
            ICON = 0x100,    //获得图标
            ICONLOCATION = 0x1000,
            LARGEICON = 0,    //获得大图标
            LINKOVERLAY = 0x8000,
            OPENICON = 2,
            OVERLAYINDEX = 0x40,
            PIDL = 8,
            SELECTED = 0x10000,
            SHELLICONSIZE = 4,
            SMALLICON = 1,    //获得小图标
            SYSICONINDEX = 0x4000,
            TYPENAME = 0x400,   //获得类型名
            USEFILEATTRIBUTES = 0x10
        }
        // Flags that specify the file information to retrieve with SHGetFileInfo
        [Flags]
        public enum FILE_ATTRIBUTE
        {
            READONLY = 0x00000001,
            HIDDEN = 0x00000002,
            SYSTEM = 0x00000004,
            DIRECTORY = 0x00000010,
            ARCHIVE = 0x00000020,
            DEVICE = 0x00000040,
            NORMAL = 0x00000080,
            TEMPORARY = 0x00000100,
            SPARSE_FILE = 0x00000200,
            REPARSE_POINT = 0x00000400,
            COMPRESSED = 0x00000800,
            OFFLINE = 0x00001000,
            NOT_CONTENT_INDEXED = 0x00002000,
            ENCRYPTED = 0x00004000
        }
        #endregion
        #region Variables
        //保存小图标列表
        private static System.Windows.Forms.ImageList smallImageList;


        private static List<string> FileExtList = new List<string>();
        static SystemFileIcon()
        {
            smallImageList = new System.Windows.Forms.ImageList();
             //将 ImageList中的图标设置为32位色图标,这样可以得到较好的显示效果
            smallImageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit;
            addForderIcon();
        }
        #endregion
        #region PrivateMethods
        /// <summary>
        /// 获取系统图标
        /// </summary>
        /// <param name="path">文件名</param>
        /// <param name="dwAttr">文件信息</param>
        /// <param name="dwFlag">获取信息控制字</param>
        /// <returns></returns>
        private static Icon GetIcon(string path, FILE_ATTRIBUTE dwAttr, SHGFI dwFlag)
        {
            SHFILEINFO fi = new SHFILEINFO();
            Icon ic = null;
            int iTotal = (int)SHGetFileInfo(path, dwAttr, ref fi, 0, dwFlag);
            ic = Icon.FromHandle(fi.hIcon);
            return ic;
        }
        /// <summary>
        /// 向smallInamgeList和largeImageList中
        /// 加入相应文件对应的图标
        /// </summary>
        /// <param name="fileName"></param>
        private static void addFileIcon(string fileName)
        {
            smallImageList.Images.Add(GetIcon(fileName,
             FILE_ATTRIBUTE.NORMAL,
             SHGFI.USEFILEATTRIBUTES | SHGFI.ICON | SHGFI.LARGEICON));
            
        }
        private static void addForderIcon()
        {
            smallImageList.Images.Add(GetIcon("dic",
             FILE_ATTRIBUTE.DIRECTORY,
             SHGFI.USEFILEATTRIBUTES | SHGFI.ICON | SHGFI.LARGEICON));
           
        }
        #endregion
        #region PublicMethods
        /// <summary>
        /// 获取系统的小图标列表
        /// </summary>
        public static System.Windows.Forms.ImageList SmallImageList
        {
            get
            {
                return smallImageList;
            }

        }
      
        /// <summary>
        /// 文件对应的图标在ImageList中的索引号
        /// (在SmallImageList,LargeImageList中的索引号是相同的)
        /// </summary>
        /// <param name="fileName">扩展名 如 .docx</param>
        /// <returns>索引号</returns>
        public static int ImageIndex(string fileName)
        {
            int index = 0;
            int extIndex = fileName.LastIndexOf('.');
            if (extIndex < 0)//没有扩展名的文件当作文件夹处理
            {
                extIndex = 2;
            }
            else//文件图标索引获取
            { 
                    addFileIcon(fileName);//装载图标到ImageList中
                    index = smallImageList.Images.Count - 1;
                     
            }
            return index;
        }
        #endregion
    }


分析上述代码发现 每次传递一个文件的时候都是获得该文件的图标,然后添加到集合中,返回集合最后一个index,即获得了该文件的图标!可是想一想,如果文件量很大呢?
10000个文件,这个ImageList得占多大的内存,由于这里有重复的文件格式,所以应该做如下处理!

思路是:用List<string> List记录已经添加到ImageList的文件类型,如果已经添加,直接返回该文件在List中的索引,如果没有添加,添加到ImageList和List中,返回ImageList
最后一个元素的索引

经验证后,确实不会报出内存不足!

        /// <summary>
        /// 文件对应的图标在ImageList中的索引号
        /// (在SmallImageList,LargeImageList中的索引号是相同的)
        /// </summary>
        /// <param name="fileName">扩展名 如 .docx</param>
        /// <returns>索引号</returns>
        public static int ImageIndex(string fileName)
        {
            int index = 0;
            int extIndex = fileName.LastIndexOf('.');
            if (extIndex < 0)//没有扩展名的文件当作文件夹处理
            {
                extIndex = 2;
            }
            else//文件图标索引获取
            {
                 
       
        for(int i =0;i<FileExtList.Count;i++)
                {
                    if (fileName == FileExtList[i])
                    {
                        index = i;
                        break;
                    }
                }
                if (index > 0)
                {

                }
                else 
                { 
                    addFileIcon(fileName);//装载图标到ImageList中
                    index = smallImageList.Images.Count - 1;
                    FileExtList.Add(fileName); 
                } 
            }
            return index;
        }

转载于:https://www.cnblogs.com/WuLong/archive/2011/03/01/1967707.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值