Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [VC#] TreeView - Файловый проводник, Извлечение иконок объектов 
:(
    Опции темы
MuForum
  Дата 5.9.2008, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: 2
Всего: 4



Доброе время суток!
- Столкнулся со следующей проблемой, мне необходимо реализовать 'файловый проводник', чтобы одновременно отображались иконки объектов.
- С самой системой считывания директорий и раскрытия дерева проблем нету, проблема возникла с привязкой иконок к дереву.

# Класс для извлечения иконок:
Код

using System;
using System.Drawing; // Icon;
using System.IO; // File;
using System.Runtime.InteropServices; // StructLayout; LayoutKind;
// ----------------------------------------------------------------------
namespace MIS
{
    public static class TShellIcon
    {
        [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 static 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 GetSmallIcon(string fileName)
        {
            Icon ic = null;
            IntPtr hImgSmall; //the handle to the system image list
            // ----
            try
            {
                SHFILEINFO shinfo = new SHFILEINFO();
                //Use this to get the small Icon;
                hImgSmall = 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;
                ic = Icon.FromHandle(shinfo.hIcon);
            }
            catch (Exception) { ic = null; }
            // ----
            return ic;
        }
        // ----------------------------------------------------------------------

        public static Icon GetLargeIcon(string fileName)
        {
            Icon ic = null;
            IntPtr hImgLarge; //the handle to the system image list;
            // ----
            try
            {
                SHFILEINFO shinfo = new SHFILEINFO();
                //Use this to get the large Icon;
                hImgLarge = Win32.SHGetFileInfo(fileName, 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;
                ic = Icon.FromHandle(shinfo.hIcon);
            }
            catch (Exception) { ic = null; }
            // ----
            return ic;
        }
        // ----------------------------------------------------------------------

    }
}


- Иконки объектов извлекаются, с этим проблем нету.
- Меня интересует другое, в компоненте 'TreeView' Используется класс 'ImageList' для отображения иконок, по началу я решил, что это глупо, но затем хорошо обдумав ситуации, когда объектов будет много понял, что это экономия ресурсов(Правильная!).
- Следовательно возникает разумный вопрос: Как правильная сверять, присутствует уже эта иконка или нет в нашем классе 'ImageList'. (Добавлять все иконки - это маразм)
- Сверять иконки по пиксельно тоже считаю не очень разумно (Хотя пока лучшего способа не придумал)
- Меня интересует чисто алгоритм, как будет рациональнее сделать проверку на наличие иконки в классе 'ImageList'.
- Реализовать алгоритм на уровне кода проблем не составит.

P.S. -> То есть мой вариант: Это при добавление какого-либо объекта, извлекать иконку и по пиксельно сверять её с теми, что уже присутствуют в классе 'ImageList', если такая иконка уже есть, то извлекаем индекс и присваеваем его ноду. (Если во время проверки хотябы один пиксель не совпадает, то переходим к следующей иконки из списка 'ImageList')

Это сообщение отредактировал(а) MuForum - 5.9.2008, 15:53


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
Partizan
Дата 5.9.2008, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 8
Всего: 67



вообще говоря существует некий "imagelist системы" его можно получить(на самом деле можно получить его хэндл) и назначить нужному контролу. 
Причём из каждого файла опять же через shell можно получить индекс иконки в этом imagelist...

в моей реализации файлового менеджера использовался именно этот подход.


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
MuForum
Дата 5.9.2008, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: 2
Всего: 4



Цитата(Partizan @ 5.9.2008,  16:27)
вообще говоря существует некий "imagelist системы" его можно получить(на самом деле можно получить его хэндл) и назначить нужному контролу. 
Причём из каждого файла опять же через shell можно получить индекс иконки в этом imagelist...

в моей реализации файлового менеджера использовался именно этот подход.

Если не затруднит, можно немного больше информации. (Пару ключевых слов, чтобы можно было на MSDN поискать и в google)


# Добавлено: Немного помучившись, и правильно сформулировал запрос, нашел статью про системный 'как бы ImageList'.
- Пока тяжело разобраться, так что помощь приветствую.


P.S. -> Нашел статью на MSDN, правда объяснения и примеры на C++: Посетить;


# Добавлено: Я нашел статью, в которой описывается как на C# обращаться к этому системному 'ImageList' и не только, но в данной статье есть неточности.
Код

            SHGetFileInfoConstants dwFlags = SHGetFileInfoConstants.SHGFI_USEFILEATTRIBUTES | SHGetFileInfoConstants.SHGFI_SYSICONINDEX;
            // ----
            if (size == SysImageListSize.smallIcons) // size - что это за переменная и откуда она берётся? | SysImageListSize.smallIcons - это ещё что за переменная или константа?
            {
                dwFlags |= SHGetFileInfoConstants.SHGFI_SMALLICON;
            }
            // ----
            // Get image list
            SHFILEINFO shfi = new SHFILEINFO();
            uint shfiSize = (uint)Marshal.SizeOf(shfi.GetType());
            // ----
            // Call SHGetFileInfo to get the image list handle
            // using an arbitrary file:
            _SystemImageList = SHGetFileInfo(".txt", (int)FileAttributes.Normal, ref shfi, shfiSize, (uint)dwFlags);


Это сообщение отредактировал(а) MuForum - 6.9.2008, 21:36


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0524 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.