C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Отобразить иконку находящуюся в system image list, SHGetFileInfo может вернуть index иконки
Grigoriy
Отправлено: 25.07.2006, 05:47


Мастер участка

Группа: Участник
Сообщений: 381



Есть в АПИ функция
CODE

WINSHELLAPI DWORD WINAPI SHGetFileInfo(
   LPCTSTR pszPath,  
   DWORD dwFileAttributes,  
   SHFILEINFO FAR *psfi,  
   UINT cbFileInfo,  
   UINT uFlags
  );


pszPath — полное имя файла;
dwFileAttributes — массив атрибутов файла (учитывается при включенном флаге SHGFI_USEFILEATTRIBUTES);
psfi — адрес структуры SHFILEINFO, которую заполнит в случае успеха функция;
cbFileInfo — размер SHFILEINFO;
uFlags — флаги, указывающие на тип извлекаемой информации.
CODE

typedef struct _SHFILEINFO { // shfi  
   HICON hIcon;
   int   iIcon;
   DWORD dwAttributes;
   char  szDisplayName[MAX_PATH];
   char  szTypeName[80];
} SHFILEINFO;

Здесь hIcon — дескриптор возвращаемой иконки, а
iIcon — индекс этой же иконки в системном хранилище изображений

Дело в том, что я хочу рисовать иконки для файлов.
Я знаю как это сделать функцией DrawIconEx.
Функция SHGetFileInfo выделяет память для иконки файла и возвращает отдельный ХЕНДЛ иконки. Затем иконку можно нарисовать в нужном масштабе и в нужной позиции функцией DrawIconEx.
Но важно то, что при этом увеличивается количество ХЕНДЛов и оно может стать огромным, если в каталоге очень много файлов.

И при очень большом количестве иконок процесс копирования иконок затягивается, а этого не хотелось бы.
Кроме того, я обнаружил, что если очень много иконок копирует система и для каждой из них выдает отдельный HANDLE, то наступит такой момент, когда система просто откажет в выделении ХЕНДЛов иконок для программы и программа заглючит. Я не буду приводить здесь кода моей программы, поскольку он уже просто для меня лично огромный. Надеюсь, что будет понятно и так.

У меня вопрос.
Можно ли использовать возвращаемый индекс иконки в системном хранилище изобжений для рисования иконки и как в таком случае нарисовать ее ?

Заранее спасибо, если мне хорошо ответят.
Kuks
Отправлено: 25.07.2006, 08:33


Станционный диспетчер

Группа: Участник
Сообщений: 108



CODE
SHFILEINFO shfi;
TIcon *Icon = new TIcon;
SHGetFileInfo(OpenDialog->FileName.c_str(),FILE_ATTRIBUTE_NORMAL,&shfi, sizeof(shfi),SHGFI_ICON|SHGFI_USEFILEATTRIBUTES);
Icon->Handle  = shfi.hIcon;


Так не пойдет?
Grigoriy
Отправлено: 25.07.2006, 09:09


Мастер участка

Группа: Участник
Сообщений: 381



В таком случае вообще не нужно создавать в своей программе

CODE

TIcon *Icon = new TIcon;

Достаточно просто
CODE

TIcon *Icon;

потому что объект Иконку Windows создает сама.

Да я и использую это сейчас.
И я же об этом сообщил.
Этот метод имеет недостаток в том, что создаются копии иконок системой и это занимает время и есть некий предел количества дескрипторов иконок, выделяемых программе.
А мне нужно использовать
shfi.iIcon.

В общем есть такая функция
CODE

BOOL ImageList_DrawEx(
   HIMAGELIST himl,  // handle to the image list
   int i,  // index of the image to draw
   HDC hdcDst,  // handle to the destination device context
   int x,  // x-coordinate to draw at
   int y,  // y-coordinate to draw at
   int dx,  // width of image
   int dy,  // height of image
   COLORREF rgbBk,  // background color of image
   COLORREF rgbFg,  // foreground color of image
   UINT fStyle // drawing style
  );

Только я не знаю HANDLE системного ImageList

Отредактировано Grigoriy — 25/07/2006, 09:41
Grigoriy
Отправлено: 25.07.2006, 09:55


Мастер участка

Группа: Участник
Сообщений: 381



Нашел решение.
Сама функция SHGetFileInfo возвращает дескриптор системного хранилища изображений.
Grigoriy
Отправлено: 26.07.2006, 07:28


Мастер участка

Группа: Участник
Сообщений: 381



Только не масштабирует чего-то
функция

ImageList_DrawEx

некоторые иконки, в часности
иконки от исполняемых файлов. В этих иконках изображение получается из ресурса самого исполняемого файла.
Grigoriy
Отправлено: 30.07.2006, 13:47


Мастер участка

Группа: Участник
Сообщений: 381



Для каких расширений файлов могут быть для разных файлов разные иконки ?
Вот например, для всех EXE-файлов иконки разные, потому что изображение берется из ресурса исполняемого файла. Ещё для ICO иконки разные. Для большинства же файлов иконки одинаковые.

Мне это нужно для правильного отбражения иконок для файлов. Для ускорения вывода иконок я объявил так называемый список
CODE

TStringList* IconExtList;
/*Список расширений файлов и соответствующих им номеров иконок в системном ImageList*/

Сначала программа проверяет, есть ли строка с расширением файла в этом списке. Если есть, то программа выбирает номер иконки по (int)IconExtList->Objects[indexico]
Если нет, то добавляет строку и номер иконки, возвращенный функцией SHGetFileInfo
Ускорение действительно работает.

Вернуться в Вопросы программирования в C++Builder