c# - 获取图标 128*128 文件类型 C#

标签 c# c#-2.0

我需要获取文件类型doc或txt的图标

它的大小应该是128*128,并保存为质量好的png或ico文件。

我用过

Icon ico = Icon.ExtractAssociatedIcon(@"d:\\1.txt");
pictureBox1.Image = ico.ToBitmap();

然后保存pictureBox1中的图片,但是那个尺寸是32*32。

我真的想要一个 128*128 的尺寸。

我该怎么做?

最佳答案

Shell API 没有可用的图标大小 128x128 SHGetImageList .尺寸范围从 Win95 时代的 16x16 和 32x32 到 XP 的 48x48 和最后添加 256x256 尺寸的 Vista。

要从任何可用的图标尺寸中获取 png 文件,我遵循了 blog How do I get a high resolution icon for a file来自 Raymond Chen .我将他的代码移植到 c# 中,我从 this answer 中借用了一些片段。 .

要遵循 Raymond 的文章,这里是您需要的主要两个函数:

    int GetIconIndex(string pszFile)
    {
        SHFILEINFO sfi = new SHFILEINFO();
        Shell32.SHGetFileInfo(pszFile
            , 0
            , ref sfi
            , (uint)System.Runtime.InteropServices.Marshal.SizeOf(sfi)
            , (uint)  (SHGFI.SysIconIndex | SHGFI.LargeIcon | SHGFI.UseFileAttributes));
        return sfi.iIcon;
    }

    // 256*256
    IntPtr GetJumboIcon(int iImage)
    {
        IImageList spiml = null;
        Guid guil = new Guid(IID_IImageList2);//or IID_IImageList

        Shell32.SHGetImageList(Shell32.SHIL_JUMBO, ref guil, ref spiml);
        IntPtr hIcon = IntPtr.Zero;
        spiml.GetIcon(iImage, Shell32.ILD_TRANSPARENT | Shell32.ILD_IMAGE, ref hIcon); //

        return hIcon;
    }

GetIconIndex 方法调用 native SHGetFileIfo获取您在名称参数中提供的文件(或扩展名)的图标索引。

要获取实际图标,方法 GetJumboIcon 调用 native SHGetImageList具有尺寸属性。

为了让它全部正常工作,您可以像这样组合调用:

IntPtr hIcon = GetJumboIcon(GetIconIndex("*.txt"));

// from native to managed
using (Icon ico = (Icon)System.Drawing.Icon.FromHandle(hIcon).Clone())
{
    // save to file (or show in a picture box)
    ico.ToBitmap().Save("txticon.png", ImageFormat.Png);
}
Shell32.DestroyIcon(hIcon); // don't forget to cleanup

要获得 48x48 图标,您可以使用此方法扩展代码:

    // 48X48
    IntPtr GetXLIcon(int iImage)
    {
        IImageList spiml = null;
        Guid guil = new Guid(IID_IImageList);//or IID_IImageList

        Shell32.SHGetImageList(Shell32.SHIL_EXTRALARGE, ref guil, ref spiml);
        IntPtr hIcon = IntPtr.Zero;
        spiml.GetIcon(iImage, Shell32.ILD_TRANSPARENT | Shell32.ILD_IMAGE, ref hIcon); //

        return hIcon;
    }

由于与非托管代码交互,您需要在启用/unsafe 选项的情况下编译项目。您可以通过更改项目属性从 visual studio 进行设置,转到“构建”选项卡并勾选允许不安全代码选项。参见 this question为什么需要和here is the official MSDN documentation

原生包装器

要调用 native win32 api,函数和结构被包装在一个静态类中,您也需要将其包含在您的项目中。大多数包装器和结构都可以在 Pinvoke.net 找到。

const string IID_IImageList = "46EB5926-582E-4017-9FDF-E8998DAA0950";
const string IID_IImageList2 = "192B9D83-50FC-457B-90A0-2B82A8B5DAE1";

public static class Shell32
{

    public const int SHIL_LARGE =0x0;
    public const int SHIL_SMALL =0x1;
    public const int SHIL_EXTRALARGE =0x2;
    public const int SHIL_SYSSMALL =0x3;
    public const int SHIL_JUMBO = 0x4;
    public const int SHIL_LAST = 0x4;

    public const int ILD_TRANSPARENT = 0x00000001;
    public const int ILD_IMAGE = 0x00000020;

    [DllImport("shell32.dll", EntryPoint = "#727")]
    public extern static int SHGetImageList(int iImageList, ref Guid riid, ref IImageList ppv);

    [DllImport("user32.dll", EntryPoint = "DestroyIcon", SetLastError = true)]
    public static unsafe extern int DestroyIcon(IntPtr hIcon);

    [DllImport("shell32.dll")]
    public static extern uint SHGetIDListFromObject([MarshalAs(UnmanagedType.IUnknown)] object iUnknown, out IntPtr ppidl);

    [DllImport("Shell32.dll")]
    public static extern IntPtr SHGetFileInfo(
        string pszPath,
        uint dwFileAttributes,
        ref SHFILEINFO psfi,
        uint cbFileInfo,
        uint uFlags
    );
}

原生结构

[Flags]
enum SHGFI : uint
{
    /// <summary>get icon</summary>
    Icon = 0x000000100,
    /// <summary>get display name</summary>
    DisplayName = 0x000000200,
    /// <summary>get type name</summary>
    TypeName = 0x000000400,
    /// <summary>get attributes</summary>
    Attributes = 0x000000800,
    /// <summary>get icon location</summary>
    IconLocation = 0x000001000,
    /// <summary>return exe type</summary>
    ExeType = 0x000002000,
    /// <summary>get system icon index</summary>
    SysIconIndex = 0x000004000,
    /// <summary>put a link overlay on icon</summary>
    LinkOverlay = 0x000008000,
    /// <summary>show icon in selected state</summary>
    Selected = 0x000010000,
    /// <summary>get only specified attributes</summary>
    Attr_Specified = 0x000020000,
    /// <summary>get large icon</summary>
    LargeIcon = 0x000000000,
    /// <summary>get small icon</summary>
    SmallIcon = 0x000000001,
    /// <summary>get open icon</summary>
    OpenIcon = 0x000000002,
    /// <summary>get shell size icon</summary>
    ShellIconSize = 0x000000004,
    /// <summary>pszPath is a pidl</summary>
    PIDL = 0x000000008,
    /// <summary>use passed dwFileAttribute</summary>
    UseFileAttributes = 0x000000010,
    /// <summary>apply the appropriate overlays</summary>
    AddOverlays = 0x000000020,
    /// <summary>Get the index of the overlay in the upper 8 bits of the iIcon</summary>
    OverlayIndex = 0x000000040,
}   

[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
    public const int NAMESIZE = 80;
    public IntPtr hIcon;
    public int iIcon;
    public uint dwAttributes;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string szDisplayName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
    public string szTypeName;
};


[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int left, top, right, bottom;
}

[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
    int x;
    int y;
}

[StructLayout(LayoutKind.Sequential)]
public struct IMAGELISTDRAWPARAMS
{
    public int cbSize;
    public IntPtr himl;
    public int i;
    public IntPtr hdcDst;
    public int x;
    public int y;
    public int cx;
    public int cy;
    public int xBitmap;    // x offest from the upperleft of bitmap
    public int yBitmap;    // y offset from the upperleft of bitmap
    public int rgbBk;
    public int rgbFg;
    public int fStyle;
    public int dwRop;
    public int fState;
    public int Frame;
    public int crEffect;
}

[StructLayout(LayoutKind.Sequential)]
public struct IMAGEINFO
{
    public IntPtr hbmImage;
    public IntPtr hbmMask;
    public int Unused1;
    public int Unused2;
    public RECT rcImage;
}
[ComImportAttribute()]
[GuidAttribute("46EB5926-582E-4017-9FDF-E8998DAA0950")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IImageList
{
    [PreserveSig]
    int Add(
    IntPtr hbmImage,
    IntPtr hbmMask,
    ref int pi);

    [PreserveSig]
    int ReplaceIcon(
    int i,
    IntPtr hicon,
    ref int pi);

    [PreserveSig]
    int SetOverlayImage(
    int iImage,
    int iOverlay);

    [PreserveSig]
    int Replace(
    int i,
    IntPtr hbmImage,
    IntPtr hbmMask);

    [PreserveSig]
    int AddMasked(
    IntPtr hbmImage,
    int crMask,
    ref int pi);

    [PreserveSig]
    int Draw(
    ref IMAGELISTDRAWPARAMS pimldp);

    [PreserveSig]
    int Remove(
int i);

    [PreserveSig]
    int GetIcon(
    int i,
    int flags,
    ref IntPtr picon);

    [PreserveSig]
    int GetImageInfo(
    int i,
    ref IMAGEINFO pImageInfo);

    [PreserveSig]
    int Copy(
    int iDst,
    IImageList punkSrc,
    int iSrc,
    int uFlags);

    [PreserveSig]
    int Merge(
    int i1,
    IImageList punk2,
    int i2,
    int dx,
    int dy,
    ref Guid riid,
    ref IntPtr ppv);

    [PreserveSig]
    int Clone(
    ref Guid riid,
    ref IntPtr ppv);

    [PreserveSig]
    int GetImageRect(
    int i,
    ref RECT prc);

    [PreserveSig]
    int GetIconSize(
    ref int cx,
    ref int cy);

    [PreserveSig]
    int SetIconSize(
    int cx,
    int cy);

    [PreserveSig]
    int GetImageCount(
ref int pi);

    [PreserveSig]
    int SetImageCount(
    int uNewCount);

    [PreserveSig]
    int SetBkColor(
    int clrBk,
    ref int pclr);

    [PreserveSig]
    int GetBkColor(
    ref int pclr);

    [PreserveSig]
    int BeginDrag(
    int iTrack,
    int dxHotspot,
    int dyHotspot);

    [PreserveSig]
    int EndDrag();

    [PreserveSig]
    int DragEnter(
    IntPtr hwndLock,
    int x,
    int y);

    [PreserveSig]
    int DragLeave(
    IntPtr hwndLock);

    [PreserveSig]
    int DragMove(
    int x,
    int y);

    [PreserveSig]
    int SetDragCursorImage(
    ref IImageList punk,
    int iDrag,
    int dxHotspot,
    int dyHotspot);

    [PreserveSig]
    int DragShowNolock(
    int fShow);

    [PreserveSig]
    int GetDragImage(
    ref POINT ppt,
    ref POINT pptHotspot,
    ref Guid riid,
    ref IntPtr ppv);

    [PreserveSig]
    int GetItemFlags(
    int i,
    ref int dwFlags);

    [PreserveSig]
    int GetOverlayImage(
    int iOverlay,
    ref int piIndex);
};

关于c# - 获取图标 128*128 文件类型 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28525925/

相关文章:

c# - Web 服务和轮询

c# - 当其他表单处于事件状态时更新表单

c# - 为什么内联方法不等同于显式声明它?

c# - 如何指定打开excel文件的字符串路径?

c# - ExecuteScalar() 与 ExecuteReader() 相比有什么优势吗?

c# - 如何在调用构造函数之前初始化 F# 中的字段?

C# UML 类图

c# - 以编程方式从 GridLayoutGroup 获取计数的列和行

c# - 在 C#/.NET 中获取 url 的域名

sql-server - 插入前检查现有记录