有時候我們需要根據不同的副檔名顯示不同的表徵圖,比如用C#做一個資源管理員。在C#中可以使用 Icon icon = System.Drawing.Icon.ExtractAssociatedIcon(fileFullName) 來得到指定檔案表徵圖。但是Icon.ExtractAssociatedIcon 只能擷取大表徵圖,要擷取小表徵圖還是要使用 API。
using System;
using System.Runtime.InteropServices;
using System.Drawing;
namespace MyNamespace
{
public class FileIcon
{
/// <summary>
/// 擷取檔案的預設表徵圖
/// </summary>
/// <param name="fileName">檔案名稱。
/// 可以只是檔案名稱,甚至只是檔案的副檔名(.*);
/// 如果想獲得.ICO檔案所表示的表徵圖,則必須是檔案的完整路徑。
/// </param>
/// <param name="largeIcon">是否大表徵圖</param>
/// <returns>檔案的預設表徵圖</returns>
public static Icon GetFileIcon(string fileName, bool largeIcon)
{
SHFILEINFO info = new SHFILEINFO(true);
int cbFileInfo = Marshal.SizeOf(info);
SHGFI flags;
if (largeIcon)
flags = SHGFI.Icon | SHGFI.LargeIcon | SHGFI.UseFileAttributes;
else
flags = SHGFI.Icon | SHGFI.SmallIcon | SHGFI.UseFileAttributes;
SHGetFileInfo(fileName, 256, out info, (uint)cbFileInfo, flags);
return Icon.FromHandle(info.hIcon);
}
[DllImport("Shell32.dll")]
private static extern int SHGetFileInfo
(
string pszPath,
uint dwFileAttributes,
out SHFILEINFO psfi,
uint cbfileInfo,
SHGFI uFlags
);
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon = IntPtr.Zero; iIcon = 0; dwAttributes = 0; szDisplayName = ""; szTypeName = "";
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 80)]
public string szTypeName;
};
private enum SHGFI
{
SmallIcon = 0x00000001,
LargeIcon = 0x00000000,
Icon = 0x00000100,
DisplayName = 0x00000200,
Typename = 0x00000400,
SysIconIndex = 0x00004000,
UseFileAttributes = 0x00000010
}
}
}