根據擴展名, 從註冊表中取得文件的圖標

好久沒上傳文章了,因爲太忙!在網上得到過無數程序人的幫助,希望我的文章也能幫助一些象我一樣的程序人!

        最近在寫一個嵌入的文檔版本管理軟件,要用到系統文件圖標,上網找了許久,竟沒找到一個合適的解決方法,只好自已動手寫了。在寫這個東西的過程中,得到了以下文章的啓發,在些向文章的作者表示萬份感謝!

http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-vb/22674/Icons-in-DLL-s

http://www.z4.cn/bbs/showthread.php?threadid=1794

 

using System;
using System.IO;
using System.Drawing;
using Microsoft.Win32;


using System.Runtime.InteropServices;

 

namespace Deep.DBFile.DataCommunicate
{
 /// <summary>
 /// 提供從操作系統讀取圖標的方法
 /// </summary>
 public class GetSystemIcon
 {
  /// <summary>
  /// 依據文件名讀取圖標,若指定文件不存在,則返回空值。
  /// </summary>
  /// <param name="fileName"></param>
  /// <returns></returns>
  public static Icon GetIconByFileName(string fileName)
  {
   if(fileName == null || fileName.Equals(string.Empty)) return null;
   if(!File.Exists(fileName)) return null;

   SHFILEINFO shinfo = new SHFILEINFO();
   //Use this to get the small Icon
   Win32.SHGetFileInfo(fileName, 0, ref shinfo,(uint)Marshal.SizeOf(shinfo),Win32.SHGFI_ICON|Win32.SHGFI_SMALLICON);
   //The icon is returned in the hIcon member of the shinfo struct
   System.Drawing.Icon myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
   return myIcon;
  }

  /// <summary>
  /// 給出文件擴展名(.*),返回相應圖標
  /// 若不以"."開頭則返回文件夾的圖標。
  /// </summary>
  /// <param name="fileType"></param>
  /// <param name="isLarge"></param>
  /// <returns></returns>
  public static Icon GetIconByFileType(string fileType,bool isLarge)
  {
   if(fileType == null || fileType.Equals(string.Empty)) return null;

   RegistryKey regVersion = null;
   string regFileType = null;
   string regIconString = null;
   string systemDirectory = Environment.SystemDirectory + "//";

   if(fileType[0] == '.')
   {
    //讀系統註冊表中文件類型信息
    regVersion = Registry.ClassesRoot.OpenSubKey(fileType, true);
    if(regVersion != null)
    {
     regFileType = regVersion.GetValue("") as string;
     regVersion.Close();
     regVersion = Registry.ClassesRoot.OpenSubKey(regFileType + @"/DefaultIcon" , true);
     if(regVersion != null)
     {
      regIconString = regVersion.GetValue("") as string ;
      regVersion.Close(); 
     }
    }
    if(regIconString == null)
    {
     //沒有讀取到文件類型註冊信息,指定爲未知文件類型的圖標
     regIconString = systemDirectory +"shell32.dll,0";
    }
   }
   else
   {
    //直接指定爲文件夾圖標
    regIconString = systemDirectory +"shell32.dll,3";
   }
   string[] fileIcon = regIconString.Split(new char[]{','});
   if(fileIcon.Length != 2)
   {
    //系統註冊表中註冊的標圖不能直接提取,則返回可執行文件的通用圖標
    fileIcon = new string[]{systemDirectory +"shell32.dll","2"};
   }
   Icon resultIcon = null;
   try
   {
    //調用API方法讀取圖標
    int[] phiconLarge = new int[1];
    int[] phiconSmall = new int[1];
    uint count = Win32.ExtractIconEx(fileIcon[0],Int32.Parse(fileIcon[1]),phiconLarge,phiconSmall,1);
    IntPtr IconHnd = new IntPtr(isLarge?phiconLarge[0]:phiconSmall[0]);
    resultIcon = Icon.FromHandle(IconHnd);
   }
   catch{}
   return resultIcon;
  }
 


 
 [StructLayout(LayoutKind.Sequential)]
 public 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;
 }

 /// <summary>
 /// 定義調用的API方法
 /// </summary>
 class Win32
 {
  public const uint SHGFI_ICON = 0x100;
  public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
  public const uint SHGFI_SMALLICON = 0x1; // 'Small icon

  [DllImport("shell32.dll")]
  public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
  [DllImport("shell32.dll")]
  public static extern uint ExtractIconEx(string lpszFile, int nIconIndex, int[] phiconLarge, int[] phiconSmall, uint nIcons);

 }
}

 

原作: saswp
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=334421

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章