• hIcon (типа HICON) – дескриптор значка заданного путем объекта (первый параметр функции SHGetFilelnfo);
• iIcon (типа Integer) – номер значка в системном компоненте ImageList;
• dwAttributes (типа DWORD) – атрибуты заданного путем объекта;
• szDisplayName (типа array [0. МАХ_РАТН-1] of AnsiChar) – буфер для имени заданного объекта (например, сочетание имени и метки диска, отображаемое в Проводнике Windows);
• szTypeName (типа array [0..79] of AnsiChar) – буфер для названия типа файла (например, Документ Microsoft Word).
На полях dwAttributes и ilcon подробно останавливаться не будем, зато рассмотрим, как заставить функцию SHGetFilelnfo заполнить остальные поля структуры (их проще всего использовать в Delphi). Вот используемые для этого флаги (имена целочисленных констант):
• SHGFIICON – поле hlcon заполняется дескриптором значка, ассоциированного с объектом; если при использовании дескриптор не сохраняется в каком-либо контейнере или прочем объекте, автоматически удаляющем ненужные значки (как в листинге 4.36), то после использования значок нужно удалить вручную (API-функция Destroylcon);
• SHGFI_LARGEICON, SHGFI_SMALLICON – ОНИ применяются В комбинации с SHGFIICON для получения большого или малого значков соответственно; использование флагов вместе не имеет смысла (будет получен малый значок);
• SHGFI_DISPLAYNAME—при наличии этого флага поле szDisplayName будет содержать дружественное пользователю имя объекта (например, System (С:));
• SHGFI_EXETYPE – при наличии этого атрибута полез zTypeName будет заполнено текстовым описанием типа файла.
Значения в приведенном списке можно, если не сказано иное, комбинировать при помощи операции битового ИЛИ (or).
Извлечение значков из ЕХЕ– и DLL-файлов
Наверняка вы знаете, что исполняемый файл, помимо кода программы, данных и прочей системной информации, может содержать также ресурсы. Так, из секции ресурсов берутся значки для ЕХЕ-файлов. Также в ЕХЕ– или DLL-файлах помещаются значки, используемые для ассоциированных с приложениями документов. Итак, в завершение главы рассмотрим еще один графический пример: создадим программу, способную извлекать упомянутые значки из DLL– или ЕХЕ-файлов (работает также и для ICO-файлов).
Пусть мы имеем путь файла, а также два списка (TImageList) для больших и малых значков соответственно. Тогда процедура, заполняющая списки значками, извлеченными из файла, может выглядеть следующим образом (листинг 4.37).
...
Листинг 4.37.
Составление списков значков
procedure LoadIcons(filename: String; lgImages,
smImages: TImageList);
var
icon: TIcon;
smIconHandle, lgIconHandle: HICON;
i: Integer;
begin
//Загрузка каждого значка (неоптимально, но просто)
i := 0;
while Integer(
ExtractIconEx(PAnsiChar(filename), i, lgIconHandle,
smIconHandle, 1)
) > 0 do
begin
Inc(i);
//Большой значок
icon := TIcon.Create;
icon.Handle := lgIconHandle;
lgImages.AddIcon(icon);
//Малый значок
icon := TIcon.Create;
icon.Handle := smIconHandle;
smImages.AddIcon(icon);
end;
end;
В листинге 4.37 для извлечения значков из файла используется очередная полезная функция модуля ShellApi – Extract IconEx. Прототип функции таков:
...
function ExtractIconEx(lpszFile: PChar; nIconIndex: Integer;
var phiconLarge, phiconSmall: HICON;
nIcons: UINT): UINT;
Функция ExtractlconEx принимает следующие параметры:
• lpszFile – путь файла, из которого извлекаются значки;
• nIconlndex – номер первого извлекаемого значка; нумерация начинается с нуля (если номер равен -1 и параметры piconLarge и piconSmall нулевые, то функция возвращает количество значков в файле);
• piconLarge, piconSmall – ссылки на переменные типа HI CON (либо на первые элементы массива array. of HICON) для помещения в них дескрипторов больших и малых значков соответственно;
• nIcons – количество извлекаемых значков (по сути, может быть количество элементов в передаваемых в функцию массивах: лишние элементы не будут заполнены).
Функция возвращает количество значков, извлеченных из файла, или количество значков в файле при соответствующем значении параметра nlconlndex.
В листинге 4.36 используется не совсем оптимальный способ извлечения значков из файла – по одному. Однако он подойдет для большинства случаев. Другой (но не единственный) вариант – использование массива. Тогда функцииЕх^асИсопЕх передаются первые элементы массивов для дескрипторов значков (функции нужен адрес начала массива), а в качестве последнего параметра – количество элементов в массиве. Таким образом, если количество значков в файле превзойдет количество элементов в массиве, то вызов функции ExtractlconEx можно будет повторить, передав в качестве параметра nlconlndex значение, возвращенное функцией ExtractlconEx, умноженное на номер вызова функции (начиная с нуля).