注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Hao的博客

I'm on my way……

 
 
 

日志

 
 
 
 

C# 获取系统默认图标  

2010-07-12 19:43:20|  分类: 编程杂记 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

       每个文件类型都有自己的默认图标,可以通过Icon icon = Icon.ExtractAssociatedIcon(filePath)来获得,但是这里的参数filePath必须是文件的完整路径,如果是文件夹的话就没有办法处理了。还有另一种方法就是使用SHGetFileInfo函数来获取与文件相关联的图标,该函数是由shell32.dll提供的,函数原型为
DWORD_PTR SHGetFileInfo(
     LPCTSTR pszPath, 
     DWORD dwFileAttributes,
     SHFILEINFO *psfi,
     UINT cbSizeFileInfo,
     UINT uFlags
);
pszPath用于指定文件或文件夹的路径;dwFileAttributes是文件属性的组合;psfi是指向SHFILEINFO结构的指针,用于接收返回的文件信息;cbSizeFileInfo是SHFILEINFO结构的大小;uFlags指定了需要提取文件信息的标志。调用该函数之后,与文件图标有关的信息将会保存在psfi->hIcon中。实现代码如下:

class CommonWin32
{
    //file attributes categories
    [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
    } 

    //contains information about a file object
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct SHFILEINFO
    {
        private const int MAX_PATH = 260;

        public IntPtr hIcon;
        public int iIcon;
        public uint dwAttributes;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
        public string szDisplayName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
        public string szTypeName;
    }

    //file information categories
    [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
    }  

    [DllImport("shell32.dll")]
    private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttribute, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);

    /// <summary>
    /// Gets the icon of the file or folder relative to the given path
    /// </summary>
    /// <param name="fullPath">full path of the file or folder</param>
    /// <param name="isLarge">needs large icon or not</param>
    /// <returns>return icon needed</returns>

    public static Icon GetIcon(string fullPath, bool isLarge) {
        SHFILEINFO shinfo = new SHFILEINFO();
        SHGFI flags;
        if (isLarge)
        {
            flags = SHGFI.ICON | SHGFI.LARGEICON;
        }
        else {
            flags = SHGFI.ICON | SHGFI.SMALLICON;
        }

        //without SHGFI.USEFILEATTRIBUTES flag, dwFileAttribute will be ignore
        SHGetFileInfo(fullPath, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), (uint)flags);

        return Icon.FromHandle(shinfo.hIcon);
    }
}


1. FILE_ATTRIBUTE、SHFILEINFO、SHGFI、SHGetFileInfo都是与API中对应类型或函数的C#版本,原版本的声明可以通过msdn或其他文档查阅。

2. [Flags]称为位域,如果枚举类型的声明前标记了该特性,则该枚举类型支持“|”和“&”两个操作来组合多个状态(SHGFI.ICON | SHGFI.LARGEICON)或从多个状态中去除一种状态(flags&(~SHGFI.ICON))。

3. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]允许控制类或结构的数据字段的物理布局。其中LayoutKind枚举用于控制当导出到非托管代码时对象的布局,包括Sequential(顺序布局)、Explicit(精确布局,每个成员必须使用FieldOffsetAttribute指示该字段在类型中的位置)和Auto(自动布局)。

4. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]用于指定如何在托管堆和非托管堆之间的传递数据,SizeConst指定了大小。

5. 由于托管和非托管数据在组织形式上存在差异,所以在很多时候都需要我们来指定如何在托管和非托管堆间转换数据以及采用何种组织形式,这就是3和4的作用。

6. [DllImport("shell32.dll")]用于导入shell.dll库,然后才能使用里面的SHGetFileInfo函数。

  评论这张
 
阅读(2539)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017