• C#获取文件与文件夹默认图标(2006-3-22 新增示例代码与程序)


    本文与《 C#实现带图标菜单 》为同一系列,请参考阅读。

      上篇关于带图标显示菜单的实现办法中大家可以看到我把文件以及文件夹的图标显示在菜单项上,就像在资源管理器中一样。
      那个图标是怎么获取的呢,我在MSDN中搜索了一下,找到了SHGetFileInfo函数,这是Shell32.dll中的一个函数,具体功能大家还是看MSDN中Platform SDK部分对SHGetFileInfo函数的说明,在这里很难全部都做说明。一下只介绍下我的做法,以及对所遇到的问题的解决方式。
      阅读以下部分前请先浏览:
     
      SHGetFileInfo函数的大部分参数都是简单的数值类型参数,唯一让我不太明白的是psfi参数,这个参数是一个SHFILEINFO结构体指针,C#中要怎么传这样一个结构体进去呢?我查看了MSDN中.NET框架部分关于封送类、结构和联合的资料,里面提到了使用ref关键字进行结构体的引用传递,所以我将SHGetFileInfo函数声明为如下格式:

     
    [DllImport("shell32.dll", EntryPoint="SHGetFileInfo")] 
    public static extern int GetFileInfo
    (string pszPath, int dwFileAttributes, ref FileInfomation psfi, int cbFileInfo,int uFlags); 

    并根据MSDN中对SHFILEINFO结构体的定义声明了它的C#版本:

      [ StructLayout( LayoutKind.Sequential)] 
     public   struct  FileInfomation 
     
          public  IntPtr hIcon; 
          public   int  iIcon; 
          public   int  dwAttributes; 

         [ MarshalAs( UnmanagedType.ByValTStr, SizeConst = 260 )] 
          public   string  szDisplayName; 

         [ MarshalAs( UnmanagedType.ByValTStr, SizeConst = 80 )] 
          public   string  szTypeName; 
     }

    MarshalAs( UnmanagedType.ByValTStr, SizeConst=260)标签可以在MSDN关于封送类、结构和联合的资料中找到。
    搜索了一下Platform SDK的头文件,在ShellApi.h中找到了uFlags的定义,我将这些值声明为GetFileInfoFlags枚举类型(详细代码在后面),我目前只用到了SHGFI_ICON和SHGFI_SMALLICON,SHGFI_ICON表示要获取文件大图标,SHGFI_SMALLICON表示要获取小图标,我第一次用SHGFI_SMALLICON时程序出现了异常,后来仔细看MSDN才知道SHGFI_SMALLICON和SHGFI_ICON必须要连用
     
    最后我把这些API函数声明、结构体声明、枚举类型声明等东西总的放在一个FileInfo类中,代码我会放在文章的最后部分以防止大家阅读文章不便。
     
    最后我在我的文件浏览菜单项中定义了一个静态方法来获取文件夹或者文件的小图标,代码如下:

       ///   <summary>  
      ///  通过路径获取小图标 
      ///   </summary>  
      ///   <param name="path"> 文件或文件夹路径 </param>  
      ///   <returns> 获取的图标 </returns>  
       public   static  Icon GetSmallIcon( string  path) 
     
         FileInfo.FileInfomation _info  = new  System.FileInfo.FileInfomation(); 

         FileInfo.GetFileInfo(path,  0 ,  ref  _info, Marshal.SizeOf(_info), 
         ( int )(FileInfo.GetFileInfoFlags.SHGFI_ICON | FileInfo.GetFileInfoFlags.SHGFI_SMALLICON)); 
          try
           
              return  Icon.FromHandle(_info.hIcon); 
         }
          catch
           
              return   null ; 
         }
     }


    大家可以拿一段代码时候试试看,比图将C盘根目录图标显示在PictureBox里:

    pictureBox.Image = GetSmallIcon("C:\");
     
    FileInfo类代码
     ///   <summary>  
      ///  获取文件系统中对象的信息,例如:文件、文件夹、驱动器根目录 
      ///   </summary>  
       public   class  FileInfo 
     
         [DllImport( " shell32.dll " , EntryPoint = " SHGetFileInfo " )] 
         publicstaticexternint GetFileInfo( string  pszPath,  int  dwFileAttributes, 
          ref  FileInfomation psfi,  int  cbFileInfo, int  uFlags); 

     private  FileInfo() {}

         [ StructLayout( LayoutKind.Sequential)] 
          public   struct  FileInfomation 
          
              public  IntPtr hIcon; 
              public   int  iIcon; 
              public   int  dwAttributes; 
             [ MarshalAs( UnmanagedType.ByValTStr, SizeConst = 260 )] 
              public   string  szDisplayName; 
             [ MarshalAs( UnmanagedType.ByValTStr, SizeConst = 80 )] 
              public   string  szTypeName; 
         }
          public   enum  FileAttributeFlags :  int
           
             FILE_ATTRIBUTE_READONLY  = 0x00000001 , 
             FILE_ATTRIBUTE_HIDDEN  = 0x00000002 , 
             FILE_ATTRIBUTE_SYSTEM  = 0x00000004 , 
             FILE_ATTRIBUTE_DIRECTORY  = 0x00000010 , 
             FILE_ATTRIBUTE_ARCHIVE  = 0x00000020 , 
             FILE_ATTRIBUTE_DEVICE  = 0x00000040 , 
             FILE_ATTRIBUTE_NORMAL  = 0x00000080 , 
             FILE_ATTRIBUTE_TEMPORARY  = 0x00000100 , 
             FILE_ATTRIBUTE_SPARSE_FILE  = 0x00000200 , 
             FILE_ATTRIBUTE_REPARSE_POINT  = 0x00000400 , 
             FILE_ATTRIBUTE_COMPRESSED  = 0x00000800 , 
             FILE_ATTRIBUTE_OFFLINE  = 0x00001000 , 
             FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  = 0x00002000 , 
             FILE_ATTRIBUTE_ENCRYPTED  = 0x00004000  
         }
          public   enum  GetFileInfoFlags :  int
           
             SHGFI_ICON  = 0x000000100 ,  //  get icon
              SHGFI_DISPLAYNAME  = 0x000000200 ,  //  get display name
              SHGFI_TYPENAME  = 0x000000400 ,  //  get type name
              SHGFI_ATTRIBUTES  = 0x000000800 ,  //  get attributes
              SHGFI_ICONLOCATION  = 0x000001000 ,  //  get icon location
              SHGFI_EXETYPE  = 0x000002000 ,  //  return exe type
              SHGFI_SYSICONINDEX  = 0x000004000 ,  //  get system icon index
              SHGFI_LINKOVERLAY  = 0x000008000 ,  //  put a link overlay on icon
              SHGFI_SELECTED  = 0x000010000 ,  //  show icon in selected state
              SHGFI_ATTR_SPECIFIED  = 0x000020000 ,  //  get only specified attributes
              SHGFI_LARGEICON  = 0x000000000 ,  //  get large icon
              SHGFI_SMALLICON  = 0x000000001 ,  //  get small icon
              SHGFI_OPENICON  = 0x000000002 ,  //  get open icon
              SHGFI_SHELLICONSIZE  = 0x000000004 ,  //  get shell size icon
              SHGFI_PIDL  = 0x000000008 ,  //  pszPath is a pidl
              SHGFI_USEFILEATTRIBUTES  = 0x000000010 ,  //  use passed dwFileAttribute
              SHGFI_ADDOVERLAYS  = 0x000000020 ,  //  apply the appropriate overlays
              SHGFI_OVERLAYINDEX  = 0x000000040   //  Get the index of the overlay
          }
     }


    本文与《 C#实现带图标菜单 》为同一系列,请参考阅读。

    示例代码下载地址:http://www.cnblogs.com/Files/BG5SBK/[2005-12-13-01]%20XView.rar
    示例程序下载地址:http://www.cnblogs.com/Files/BG5SBK/XView_Bin.rar

    https://www.cnblogs.com/bg5sbk/archive/2005/12/18/GetFileInfo.html

  • 相关阅读:
    从TCP三次握手说起——浅析TCP协议中的疑难杂症
    动态绑定是如何实现的?
    C++对象的内存模型
    C/C++关键字
    libevent库介绍--事件和数据缓冲
    libevent编程疑难解答
    大型工程多个目录下的Makefile写法
    C++中的RAII机制
    C++中的智能指针
    二叉树的非递归遍历
  • 原文地址:https://www.cnblogs.com/waw/p/14061868.html
Copyright © 2020-2023  润新知