困扰良久的问题 以前做的项目 图标就不清楚  现在又碰到了  在网上搜了两天 还是没找到答案  看来还得请教各路达人了效果如下图
要如何设置才能让图标清晰显示  我获取图标的方式是通过WIN32 API分析FILEINFO得到的  应该说图标文件与资源管理器里的没有差别

解决方案 »

  1.   


    #Region "获取文件图标"
        Public Class GetItemBitmap        Private Const SHGFI_ICON As Integer = 256
            Private Const SHGFI_SMALLICON As Integer = 1
            Private Const SHGFI_LARGEICON As Integer = 0        Private Structure SHFILEINFO
                Public hIcon As IntPtr
                Public iIcon As Integer
                Public dwAttributes As UInteger
                <Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=256)> _
                Public szDisplayName As String
                <Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=80)> _
                Public szTypeName As String
            End Structure        <Runtime.InteropServices.DllImport("Shell32.dll")> _
            Private Shared Function SHGetFileInfo(ByVal pszPath As String, ByVal dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, ByVal uFlags As UInteger) As IntPtr
            End Function        <System.Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)> _
            Private Shared Function DestroyIcon(ByVal handle As IntPtr) As Boolean
            End Function        Public Shared Function GetIcon(ByVal filename As String) As Drawing.Bitmap
                Dim iconbitmap As Drawing.Bitmap
                Dim shinfo As New SHFILEINFO()
                Dim hImgSmall As IntPtr = SHGetFileInfo(filename, 0, shinfo, System.Runtime.InteropServices.Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON)
                Dim icon As Drawing.Icon = System.Drawing.Icon.FromHandle(shinfo.hIcon)
                iconbitmap = icon.ToBitmap()
                DestroyIcon(shinfo.hIcon)
                Return iconbitmap
            End Function
        End Class
    #End Region
      

  2.   

    To:wzuomin 你的方法与我的方法的唯一差别在于你返回的是bitmap 我返回的是icon 我改成bitmap也没用 图标的黑边变成蓝色的边了 你用这中方法加载的图标放在listview里不会有边框吗?To:kyle315 图标是32*32的
      

  3.   

    那看来并不是我本地环境的问题了 我觉得根源是在ListView显示图标的时候 没有按照256色透明模式现实 但不知道在什么时候 什么地方 如何设置
      

  4.   

    ICON的图像大小问题,我记得好像是32位的
      

  5.   

    取文件图标片段
            [DllImport("shell32.dll", EntryPoint = "SHGetFileInfo")]
            public static extern int GetFileInfo(string pszPath, int dwFileAttributes, ref FileInfomation psfi, int cbFileInfo, int uFlags);        [StructLayout(LayoutKind.Sequential)]
            public struct FileInfomation
            {
                public IntPtr hIcon;
                public int iIcon;
                public int dwAttributes;            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] //这里应该是256色了
                public string szDisplayName;            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
                public string szTypeName;
            }        public static Icon GetSystemIcon(string path, string sIconType) //这里传入文件位置 和 要取得图标类型(大、小图标)
            {
                FileInfomation _info = new FileInfomation();
                GetFileInfo(path, 0, ref _info, Marshal.SizeOf(_info),
                    (int)(((sIconType.ToUpper().Equals("SMALL")) ? EnumTypes.GetFileInfoFlags.SHGFI_ICON | EnumTypes.GetFileInfoFlags.SHGFI_SMALLICON : EnumTypes.GetFileInfoFlags.SHGFI_ICON | EnumTypes.GetFileInfoFlags.SHGFI_LARGEICON)));
                try
                {
                    _info.szTypeName = sIconType;
                    return Icon.FromHandle(_info.hIcon);
                }
                catch { return null; }
            }
                this.imageListLarge.ImageSize = new Size(16, 16);
                lvExplorer.SmallImageList = imageListSmall;
                this.imageListLarge.ImageSize = new Size(32, 32); //这里图标大小也设置32了
                lvExplorer.LargeImageList = imageListLarge;就是效果不对
      

  6.   

    以下条件:
    1. *.ico,*.png,
    2. 在添加图片时要求ImageList的颜色深度为32位色
    3. 图标大小为32X32
    效果图如下:
      

  7.   

    using System.Runtime.InteropServices;
    public static uint SHGFI_ICON = 0x100;                     
    public static uint SHGFI_DISPLAYNAME = 0x200;              
    public static uint SHGFI_TYPENAME = 0x400;                 
    public static uint SHGFI_ATTRIBUTES = 0x800;               
    public static uint SHGFI_ICONLOCATION = 0x1000;            
    public static uint SHGFI_EXETYPE = 0x2000;                  
    public static uint SHGFI_SYSICONINDEX = 0x4000;            
    public static uint SHGFI_LINKOVERLAY = 0x8000;             
    public static uint SHGFI_SELECTED = 0x10000;               
    public static uint SHGFI_LARGEICON = 0x0;                  
    public static uint SHGFI_SMALLICON = 0x1;                  
    public static uint SHGFI_OPENICON = 0x2;                   
    public static uint SHGFI_SHELLICONSIZE = 0x4;              
    public static uint SHGFI_PIDL = 0x8;                       
    public static uint SHGFI_USEFILEATTRIBUTES = 0x10;         
    public static uint FILE_ATTRIBUTE_NORMAL = 0x80;
    public static uint LVM_FIRST = 0x1000;
    public static uint LVM_SETIMAGELIST = LVM_FIRST + 3;
    public static uint LVSIL_NORMAL = 0;
    public static uint LVSIL_SMALL = 1;
    [DllImport("Shell32.dll")]
    public static extern IntPtr SHGetFileInfo(string pszPath,
        uint dwFileAttributes, ref SHFILEINFO psfi,
        int cbfileInfo, uint uFlags);
    public struct SHFILEINFO
    {
        public IntPtr hIcon;
        public int iIcon;
        public int dwAttributes;
        public string szDisplayName;
        public string szTypeName;
    }
    [DllImport("User32.DLL")]
    public static extern int SendMessage(IntPtr hWnd,
        uint Msg, IntPtr wParam, IntPtr lParam);
    public void ListViewSysImages(ListView AListView)
    {
        SHFILEINFO vFileInfo = new SHFILEINFO();
        IntPtr vImageList = SHGetFileInfo("", 0, ref vFileInfo,
            Marshal.SizeOf(vFileInfo), SHGFI_SHELLICONSIZE |
            SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
        SendMessage(AListView.Handle, LVM_SETIMAGELIST, (IntPtr)LVSIL_NORMAL,
            vImageList);
        vImageList = SHGetFileInfo("", 0, ref vFileInfo,
            Marshal.SizeOf(vFileInfo), SHGFI_SHELLICONSIZE |
            SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
       SendMessage(AListView.Handle, LVM_SETIMAGELIST, (IntPtr)LVSIL_SMALL,
            vImageList);
    }
    public int FileIconIndex(string AFileName)
    {
        SHFILEINFO vFileInfo = new SHFILEINFO();
        SHGetFileInfo(AFileName, 0, ref vFileInfo,
            Marshal.SizeOf(vFileInfo), SHGFI_SYSICONINDEX);
        return vFileInfo.iIcon;
    }
    private void button1_Click(object sender, EventArgs e)
    {
        ListViewSysImages(listView1);
        listView1.Items.Add("temp.txt", FileIconIndex(@"c:\temp\temp.txt"));
    }
      

  8.   

    引用地址
    http://hi.baidu.com/huanshy/blog/item/cde493deae76925ccdbf1a81.html
      

  9.   

    好像和你使用的ICON文件有关系。文件上最好不要使用任何特效。
      

  10.   

    这个问题暂时没法解释,给你来个详细的:引自网上:
     
    最近写一个   exe/dll   的图标提取器,但是在保存图标时,用自带的   image.save   方法,如:   
        
      intptr   hicon=extracticon(intptr.zero,   exefile,   index);   
      icon   sicon=icon.fromhandle(hicon);   
      bitmap   bmpicon=sicon.tobitmap();   
      bmpicon.save(filename,   imageformat.icon);   
        
      后保存的图标文件在   windows   资源管理器中   平铺/大图标/小图标/列表/详细资料   查看方式中显示为未知类型的图标,但是大小已知;如果用   缩略图   方式查看的话可以看到完美的图标;但是这个文件无法通过其他编辑图标的软件打开(acdsee   7   报告为无法识别的格式),vs.   net   的   imagelist   控件除外(显示类型为   png)。用二进制方式查看这个文件会发现它文件头根本不是图标文件的文件头(00   00   01   ......),也就是根本不是图标格式。   
        
      如果用流保存   icon.save   的话,如:   
        
      intptr   hicon=extracticon(intptr.zero,   exefile,   index);   
      icon   sicon=icon.fromhandle(hicon);   
      filestream   outsream=new   filestream(filename);   
      sicon.save(outstream);   
      outstream.flush();   
      outstream.close();   
        
      保存的图标格式正确,可以在   windows   资源管理器中任意方式下正确查看,也可以为其他程序所用。但是色深仅为   4位(16色),很多颜色都丢失了。文件的大小也小很多。   
        
      如果先保存为其他格式再改名,图标的背景就是黑的了。   
        
      连   .net   自己的函数都不行,哪为高手可以提供一个能够正确保存图标(100%质量保存)的方法?或者能看看我的代码哪里有问题(打错字的不算,因为上面代码已经成功编译过)。   
        
      用于测试的文件是   %windir%\system32\shell32.dll。 
      

  11.   

    不要用自己的imagelist,用操作系统提供的api去设置listview的imagelist(Handle),不会有问题的,相信我
      

  12.   

    你说的和我在VB中用TREEview的效果一样。
    最后没办法就找图标了。
    “通过WIN32 API分析FILEINFO”得到的图标就是那样。
    你自己做就没事了。
      

  13.   

    由于我现在在公司 项目文件在家里 现在还没有办法测试 先回复大家 感谢大家的人心支持
    同病相怜 呵呵1. 我引用的是系统图标 格式应该没问题的
    2. ImageList可以设置颜色深度吗?什么属性?
    3. 图标大小是32*32没错的能解释下SHGetFileInfo方法参数的含义吗?文件使用属性是指?我现在是想使用特效 不知道如何使用 现在图标不是256色 也没有渐变透明效果 所以很难看好象被你反问了  我也是搞不清怎么提高图标颜色深度好的 我会去试场景很简单 就是单纯的模仿windows资源管理器 获取一个目录下所有子目录及文件 将他们加入LISTVIEW控件 显示他们的图标我碰到过更郁闷的事就是自己准备的ICON也是这个效果 用WINDOWS资源管理器显示就OK 愁人再次感谢大家
      

  14.   

    引用 25 楼 hm7921936 的回复:
    我想知道LZ的应用场景  
    也许有更好的替代方案 
     
    场景很简单 就是单纯的模仿windows资源管理器 获取一个目录下所有子目录及文件 将他们加入LISTVIEW控件 显示他们的图标 
    我晕。  
    早说啊。 
    这多简单用 浏览器控件啊。  指定一个路径就完美解决了。
      

  15.   

    ListView和ImageList,都是是Windows内置窗体和对象IntPtr vImageList = SHGetFileInfo("", 0, ref vFileInfo,
            Marshal.SizeOf(vFileInfo), SHGFI_SHELLICONSIZE |
            SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
    这个是获取系统文件的大图标列表(一个ListImage的Handle)这个是设置ListView的大图标(给ListView发LVM_SETIMAGELIST的消息就可以了,告诉它大图标列表是哪个)
    SendMessage(AListView.Handle, LVM_SETIMAGELIST, (IntPtr)LVSIL_NORMAL, 
            vImageList);而.NET中的ImageList和ListView只是对这内置的对象进行操作而已
    大概是ImageList或Image的封装有点问题,导致楼主出现了那种现象
      

  16.   

    同志们  我来传喜讯来了  我找到问题根源及解决之道了  现在那小图标  很漂亮嘞  当然  也是网上搜罗地原文地址:http://www.80diy.com/home/20020717/10/880193.html懒得看原文的朋友  我就摘抄一部分关键内容  如下:----------------------------------------------------------------------
    ======================================================================
    大家对于ImageList的问题归纳了一下,主要都是关于:   
      1.ImageList里面的图片的颜色   
      2.ImageList里面的图片的大小   
        
        
      /*********   1)ImageList里面的图片的颜色的问题   ********/   
        
        
      引起ImageList里面图片颜色失真的原因是在Design-Time就在VS.NET中往ImageList里面添加了Images。   
        
      当用户一边在“Image   Collection   Editor”对话框里面添加图片,VS.NET一边就已经把这些图片装载到resource文件里面了。这样,以后程序运行时就只需要访问resource文件就可以载入所有图片而不需要依赖原始的图片文件。   
        
      但是问题在于从结果看,当VS.NET在Design-Time往resource文件里面添加图片时并没有使用用户指定的ColorDepth(例如Depth32Bit),而用了ImageList.ColorDepth的默认值(Depth8Bit)。这样,等程序运行时,即使ImageList.ColorDepth指定了Depth32Bit也无济于事,因为原始的素材本身只有8bit的颜色。这基本上就是waki的问题的原因。   
        
      因此,解决方案是:不在Design-Time用VS.NET往ImageList里面添加图片,而是在程序运行时先指定32Bit的ColorDepth,然后再添加图片,如以下例子代码:   
        
      this.imageList1.ColorDepth=ColorDepth.Depth32Bit;   
      this.imageList1.Images.Add(Image.FromFile(@"C:\Inetpub\wwwroot\winxp.gif"));   
      this.imageList1.Images.Add(Image.FromFile(@"C:\Inetpub\wwwroot\images\init_dotnet.gif"));   
      this.imageList1.Images.Add(Image.FromFile(@"C:\Inetpub\wwwroot\images\mslogo.gif"));   
      this.imageList1.Images.Add(Image.FromFile(@"C:\Inetpub\wwwroot\images\mslogo2.gif"));   
        
      这里需要注意的是,必须先指定ColorDepth,然后再添加图片。因为对ColorDepth赋值会清空所有图片。BTW,ImageList.ColorDepth的默认值是Depth8Bit,而非文档上所述Depth4Bit。这一点很容易可以通过写一段例子代码来验证,也可以通过很多Decompiler来查看ImageList的构造函数的实现来验证。   
        
        
      /**********   2)ImageList里面的图片的大小   ************/   
        
        
      的确,通过ImageList.Images[i]获得图片的大小都是统一的,都等于ImageList.ImageSize。这个问题的原因在于ImageList在返回Images[i]的过程中并没有返回原始的图片,而是按照ImageList.ImageSize创建了一个新的Bitmap,并把原始图片的内容重新绘制上去以后再返回给用户。关于这一点,可以用一些Decompiler工具如ILDASM.exe或者Anakrino通过察看私有函数ImageList.GetBitmap(int   index)来验证。我想现在paulluo0739应该能够理解为什么ImageList里面的图片都是一样大的了。   
        
      ImageSize同ColorDepth类似,也不宜在运行时改动,一旦重新赋值,就会清空所有的图片。因此,如果程序运行时需要某一图片的不同大小的版本,可以考虑使用多个不同ImageSize的ImageList。   
        
        
      希望以上这些能够对大家有帮助,感谢大家关心和使用微软的技术和产品。   
        
        
        
      Hogwarts   -   S(u)ddenly   dis@ppeared...   
      -     
      本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款(http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。       
      为了为您创建更好的讨论环境,请参加我们的用户满意度调查(http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。
    ======================================================================
    ----------------------------------------------------------------------以上就是原文的主要部分了  相信大家跟我一样恍然大悟同时再次感谢大家的关注  结贴  散分
      

  17.   

    哦 忘记了 其实我原来也有想到设置ImageList的ColorDepth属性 可是编译器告诉我是只读的 就放弃了 我也没有想狡辩的意思 只是说这个事情 呵呵 被骗了 以至于绕了个大圈子 当初要是硬着头皮去设 也就没这么多麻烦事了
      

  18.   

    问题可能复杂化了。
    这里 http://topic.csdn.net/t/20060806/20/4930815.html