Как я могу получить значок типа файла, который показывает проводник Windows? - PullRequest
18 голосов
/ 20 сентября 2008

первый вопрос здесь. Я разрабатываю программу на C # (.NET 3.5), которая отображает файлы в виде списка. Мне бы хотелось, чтобы в представлении «большой значок» отображался значок, который Windows Explorer использует для этого типа файла, в противном случае мне придется использовать некоторый существующий код, подобный этому:

        private int getFileTypeIconIndex(string fileName)
    {
        string fileLocation = Application.StartupPath + "\\Quarantine\\" + fileName;
        FileInfo fi = new FileInfo(fileLocation);
        switch (fi.Extension)
        {
            case ".pdf":
                return 1;
            case ".doc": case ".docx": case ".docm": case ".dotx":case ".dotm": case ".dot":case ".wpd": case ".wps":
                return 2;
            default:
                return 0;
        }

    }

Приведенный выше код возвращает целое число, которое используется для выбора значка из списка изображений, который я заполнил некоторыми общими значками. Это прекрасно работает, но мне нужно добавить каждое расширение под солнцем! Есть ли способ лучше? Спасибо!

Ответы [ 4 ]

11 голосов
/ 29 января 2009

Возможно, вы найдете Icon.ExtractAssociatedIcon гораздо более простым (управляемым) подходом, чем использование SHGetFileInfo. Но будьте осторожны: два файла с одинаковым расширением могут иметь разные значки.

8 голосов
/ 20 сентября 2008

Иконки файлов хранятся в реестре. Это немного запутанно, но работает что-то вроде

  • Возьмите расширение файла и ищите запись реестра для него, для пример .DOC Получить значение по умолчанию для этого параметра реестра, "Word.Document.8"
  • Теперь посмотри, что значение в реестре.
  • Посмотрите на значение по умолчанию для «значка по умолчанию» ключ реестра, в этом случае, C: \ Windows \ Installer {91120000-002E-0000-0000-0000000FF1CE} \ wordicon.exe, 1
  • Откройте файл и получите значок, используя любое число после запятой, как индексатор.

Есть некоторый пример кода на CodeProject

7 голосов
/ 20 сентября 2008

Я использовал следующее решение из codeproject в одном из недавних моих проектов

Получение (и управление) значков файлов и папок с помощью SHGetFileInfo в C #

Демонстрационный проект довольно понятен, но в основном вам просто нужно сделать:

private System.Windows.Forms.ListView FileView;

private ImageList _SmallImageList = new ImageList();
private ImageList _LargeImageList = new ImageList();
private IconListManager _IconListManager;

в конструкторе:

_SmallImageList.ColorDepth = ColorDepth.Depth32Bit;
_LargeImageList.ColorDepth = ColorDepth.Depth32Bit;

_SmallImageList.ImageSize = new System.Drawing.Size(16, 16);
_LargeImageList.ImageSize = new System.Drawing.Size(32, 32);

_IconListManager = new IconListManager(_SmallImageList, _LargeImageList);

FileView.SmallImageList = _SmallImageList;
FileView.LargeImageList = _LargeImageList;

и, наконец, при создании ListViewItem:

ListViewItem item = new ListViewItem(file.Name, _IconListManager.AddFileIcon(file.FullName));

Отлично сработало для меня.

4 голосов
/ 20 сентября 2008

Редактировать: Здесь - версия без PInvoke.

[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;
};

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("User32.dll")]
public static extern int DestroyIcon(IntPtr hIcon);

public static System.Drawing.Icon GetSystemIcon(string sFilename)
{
    //Use this to get the small Icon
    IntPtr hImgSmall; //the handle to the system image list
    //IntPtr hImgLarge; //the handle to the system image list
    APIFuncs.SHFILEINFO shinfo = new APIFuncs.SHFILEINFO();
    hImgSmall = APIFuncs.SHGetFileInfo(sFilename, 0, ref shinfo,
        (uint)Marshal.SizeOf(shinfo), APIFuncs.SHGFI_ICON | APIFuncs.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
    System.Drawing.Icon myIcon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shinfo.hIcon).Clone();
    DestroyIcon(shinfo.hIcon); // Cleanup
    return myIcon;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...