哪个图标对应一个暂定的文件名?

时间:2014-11-12 15:41:43

标签: c# wpf winapi icons

我在数据库中的二进制文件上有一个文件,在用户双击该项目之前我没有加载它(带有它的图标)

ExtractAssociatedIcon应该解决这个问题(我在这里看过:ExtractAssociatedIcon returns null

但是这要求在路径上存在文件,(我没有),我如何关联到暂定文件的扩展名(例如:{{1} })用户在他的电脑上将哪个扩展名与我应该显示的图标相关联?

@Edit:我可以从数据库中提取内容(byte []),如果这对于获取与图像相关的图标很有用。 (但是,为了设置图标图像,传输每个文件字节[]也可能需要永远。)

同样this example of @MatthewWatson是我们实际使用它来获取它的,但每条"something.docx"行需要8秒,其中有8.4k项要迭代。

@@编辑:也试过

object value = rkFileIcon.GetValue("");

没有成功。

@@@编辑:上面的这个给我一个文件的图标。(当它获得.docx时不是docx图标)

    public static Icon GetIconOldSchool(string fileName)
    {
        ushort uicon;
        StringBuilder strB = new StringBuilder(fileName);
        IntPtr handle = ExtractAssociatedIcon(IntPtr.Zero, strB, out uicon);
        Icon ico = Icon.FromHandle(handle);

        return ico;
    }

@@@@编辑:@AlexK的结果。溶液

enter image description here

FileToImage Converter是我正在做的魔术。

    [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;
    };
    static SHFILEINFO shinfo = new SHFILEINFO();
    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);
    }
    public static Icon YetAnotherAttempt(string fName)
    {

        //Use this to get the small Icon
        var hImgSmall = Win32.SHGetFileInfo(fName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON);

        //Use this to get the large Icon
        //hImgLarge = SHGetFileInfo(fName, 0, 
        //  ref shinfo, (uint)Marshal.SizeOf(shinfo), 
        //  Win32.SHGFI_ICON | Win32.SHGFI_LARGEICON);

        //The icon is returned in the hIcon member of the shinfo struct
        return System.Drawing.Icon.FromHandle(shinfo.hIcon);
    }

1 个答案:

答案 0 :(得分:1)

到你的Win32类添加:

public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; // better as private enum

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DestroyIcon(IntPtr hIcon);

您的通话将变为:

var hImgSmall = Win32.SHGetFileInfo(fName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), 
                Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON | Win32.SHGFI_USEFILEATTRIBUTES);

要返回图标,您应该复制它然后销毁API返回的图标:

var icon = (Icon)Icon.FromHandle(shinfo.hIcon).Clone();    
Win32.DestroyIcon(shinfo.hIcon);
return icon;

示例(WindowsForm项目)

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1() {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) {
            var shinfo = new Win32.SHFILEINFO();
            Win32.SHGetFileInfo("0000000000.DOCX", 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON | Win32.SHGFI_USEFILEATTRIBUTES);
            var icon = (Icon)Icon.FromHandle(shinfo.hIcon).Clone();
            Win32.DestroyIcon(shinfo.hIcon);
            this.BackgroundImage = icon.ToBitmap();
            icon.Dispose();
        }

        private class Win32 {
            internal const uint SHGFI_ICON = 0x100;
            internal const uint SHGFI_SMALLICON = 0x1;
            internal const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;

            [DllImport("user32.dll", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            internal static extern bool DestroyIcon(IntPtr hIcon);

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

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