Как создать расширение оболочки Icon
Расширение Icon позволяет динамически определять иконку файла.
В библиотеке Shell Ace обработчик Icon реализует следующие интерфейсы:
- IExtractIconW
- IExtractIconA
- IInitializeWithStream
- IInitializeWithItem
- IInitializeWithFile
- IPersistStream
- IParentAndItem
- IPersistFile
После создания проекта расширения необходимо добавить в проект модуль с обработчиком Icon. Для этого выберите соответствующую иконку на вкладке Shell extension:
Появится окно с предложением ввести имя класса и выбрать перекрываемые методы:
После нажатия на кнопку OK в проект будет добавлен модуль с каркасом обработчика. При включении опции Create sample помимо каркаса обработчика будут создан пример готового расширения оболочки, который можно использовать для изучения библиотеки. Рекомендуется перекрывать метод CreateIconInfoFromStream и CreateIconFromStream, поскольку это даст возможность Проводнику передавать в расширение не только реальные объекты файловой системы, но и виртуальные объекты, например, файл из zip архива.
В обработчике можно перекрывать следующие виртуальные процедуры и функции:
procedure Initialize;
Процедура инициализации обработчика, вызывается один раз при создании экземпляра обработчика.
procedure Clear;
Процедура вызывается при завершении работы с текущим файлом или потоком, переданным в обработчик.
class function GetClassID: TCLSID;
Функция должна возвращать уникальный идентификатор обработчика. Библиотека Shell Ace изначально генерирует уникальный идентификатор при генерации шаблона обработчика, поэтому менять его нет необходимости.
class function GetDescription: UnicodeString;
Функция должна возвращать описание обработчика.
procedure FillProgIDList(AList: TStrings);
В процедуре должно происходить заполнение списка AList ключами реестра, в которые будет прописан обработчик при регистрации расширения. Регистрация происходит в раздел реестра HKEY_CLASSES_ROOT. Например, если будет добавлен ключ .bmp, то расширение будет прописано в ветку HKEY_CLASSES_ROOT\.bmp\ShellEx\IconHandler и будет соответствовать всем файлам, имеющим расширение bmp, а если будет добавлен ключ SystemFileAssociations\Audio, то расширение будет прописано в ветку HKEY_CLASSES_ROOT\SystemFileAssociations\Audio\ShellEx\IconHandler и будет соответствовать всем файлам, расширения которых имеют PerceivedType Audio.
При добавлении ключа реестра нужно учитывать, что в Windows определен порядок приоритета обработчиков. И если в системе зарегистрирован обработчик с более высоким приоритетом, то ваш обработчик не будет вызываться.
Порядок приоритета типов объектов, в порядке уменьшения приоритета, может отличаться в различных версиях Windows:
Ключ реестра | Примечание |
---|---|
HKCR\ProgID | Если для расширения файла определено значение Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.Расширение\UserChoice |
HKCR\ProgID | Если для расширения файла определено значение ProgID |
HKCR\.Расширение | Расширение файла |
HKCR\SystemFileAssociations\.Расширение | Системное расширение файла |
HKCR\SystemFileAssociations\PerceivedType | Если для расширения файла определено значение PerceivedType |
HKCR\Kind.Kind | Если для расширения файла определено значение Kind |
HKCR\Unknown | Файл, не имеющий описанного в реестре расширения |
HKCR\* | Любой файл |
В общем случае рекомендуется регистрировать расширение на ProgID расширения файла.
function CreateIconInfoFromStream(AStream: TStream; AOpenMode: DWORD; ADefault: Boolean; AFlags: TdecIconFlags; var AIconFileName: UnicodeString; var AIconIndex: Integer; var AOutFlags: TdecIconOutFlags; var AShield: TdecIconShield): Boolean;
Функция должна на основании потока с данными AStream сформировать информацию о иконке, вызывается в реализации метода GetIconLocation интерфейса IExtractIcon.
Параметр OpenMode определяет режим работы с потоком. Он может быть равен следующим величинам:
- STGM_READ – поток может быть использован только для чтения
- STGM_READWRITE – поток может быть использован как для чтения, так и для записи.
Параметр ADefault определяет, что оболочка запрашивает информацию о иконке по умолчанию, т.е. о иконке, которая будет отображаться во время извлечения полноценной иконки. Параметр равен True при передаче в метод GetIconLocation флага GIL_DEFAULTICON.
Для формирования информации о иконке можно дополнительно анализировать флаги AFlags. Тип TdecIconFlags определен следующим образом:
TdecIconFlag = (ifForShell, ifForShortCut, ifOpenIcon);
TdecIconFlags = set of TdecIconFlag;
Каждый из элементов множества соответствует одному из флагов, переданных в метод GetIconLocation интерфейса IExtractIcon.
Значение | WinAPI флаг | Описание |
---|---|---|
ifForShell | GIL_FORSHELL | The icon is displayed in a Shell folder. |
ifForShortCut | GIL_FORSHORTCUT | Оболочка запрашивает информацию об иконке для объекта, который является ссылкой. Обработчик не должен добавлять оверлейную иконку на создаваемую обработчиком иконку, это будет сделано самим Проводником. |
ifOpenIcon | GIL_OPENICON | Оболочка запрашивает информацию о иконке для объекта в состоянии "открыто" в ситуации, когда доступны состояния "открыто" и "закрыто". Если флаг не определен, то запрашивается информацию о иконке для объекта в состоянии "закрыто". Флаг используется для таких объектов, как папка. |
Флаги GIL_ASYNC и GIL_CHECKSHIELD библиотека Shell Ace обрабатывает самостоятельно.
Параметры AIconFileName и AIconIndex будут переданы в дальнейшем в функцию CreateIconFromStream или CreateIconFromFileName.
Параметр AOutFlags позволяет передать в оболочку дополнительны параметры. Тип TdecIconOutFlags определен следующим образом:
TdecIconOutFlag = (iofSlow, iofDontCache, iofNotFileName, iofPerClass, iofPerInstance, iofSimulateDoc);
TdecIconOutFlags = set of TdecIconOutFlag;
Каждый из элементов множества, кроме iofSlow, соответствует одному из флагов, возвращаемых в оболочку методом GetIconLocation интерфейса IExtractIcon.
Значение | WinAPI флаг | Описание |
---|---|---|
iofSlow | Создание иконки занимает продолжительное время. | |
iofDontCache | GIL_DONTCACHE | Оболочка не должна кэшировать полученную иконку. |
iofNotFileName | GIL_NOTFILENAME | Параметры AIconFileName и AIcon не является корректным именем файла и индексом иконки и не могут быть переданы в функции ExtractIcon или ExtractIconEx. |
iofPerClass | GIL_PERCLASS | Все объекты этого класса имеют одну и туже иконку. В общем случае обработчик Icon не использует этот флаг, поскольку он обозначает, что данный обработчик не будет использоваться для получения иконок других объектов данного класса. |
iofPerInstance | GIL_PERINSTANCE | Каждый объект этого класса имеет собственную иконку. |
iofSimulateDoc | GIL_SIMULATEDOC | Оболочка должна создать иконку документа с использованием полученной иконки. |
Флаги GIL_SHIELD и GIL_FORCENOSHIELD библиотека Shell Ace обрабатывает самостоятельно.
Параметр AShield позволяет определить необходимость отображения иконки UAC поверх полученной иконки.
Тип TdecIconShield определен следующим образом:
TdecIconShield = (isNoShield, isShield);
По умолчанию AShield имеет значение isNoShield.
function CreateIconInfoFromFile(const AFileName: UnicodeString; AOpenMode: DWORD; ADefault: Boolean; AFlags: TdecIconFlags; var AIconFileName: UnicodeString; var AIconIndex: Integer; var AOutFlags: TdecIconOutFlags; var AShield: TdecIconShield): Boolean;
Метод аналогичен методу CreateIconInfoFromStream за исключением того, что вместо потока передается имя файла. Для создания потока для чтения данных из файла можно воспользоваться следующей функцией:
function CreateStream(const AFileName: UnicodeString; AOpenMode: DWORD = DefaultOpenMode): TStream;
После использования полученного потока его нужно удалить.
function CreateIconFromStream(AStream: TStream; AOpenMode: DWORD; const AIconFileName: UnicodeString; AIconIndex: Integer; ASize: Integer): HICON;
Функция должна на основании потока с данными AStream создать иконку и вернуть ее идентификатор (handle), вызывается в реализации метода Extract интерфейса IExtractIcon.
Параметр OpenMode определяет режим работы с потоком. Он может быть равен следующим величинам:
- STGM_READ – поток может быть использован только для чтения
- STGM_READWRITE – поток может быть использован как для чтения, так и для записи.
Параметры AIconFileName и AIconIndex равны одноименным параметрам, ранее полученным в функциях CreateIconInfoFromStream или CreateIconInfoFromFileName.
Параметр ASize определяет ширину и высоту запрашиваемой иконки в пикселях. В нормальных условиях оболочка может запрашивать иконки с размерами 16x16, 32x32, 48x48 и 256x256. Если будет создана иконка с размерами, отличающимися от запрашиваемых, то библиотека Shell Ace самостоятельно преобразует ее к нужным размерам. Если в среде разработки установлен пакет Graphics32, то рекомендуется добавлять в список используемых модулей модуль decShellExtensionGraphics32. Это позволит библиотеке Shell Ace использовать более плавные процедуры сглаживания иконок при увеличении или уменьшении их размеров. Если библиотека обнаружит установленный пакет Graphics32, то модуль decShellExtensionGraphics32 будет автоматически добавлен в список используемых модулей при создании каркаса обработчика.
Если нужно, что бы оболочка самостоятельно извлекла иконку на основе параметров AIconFileName и AIconIndex, ранее полученных в функциях CreateIconInfoFromStream или CreateIconInfoFromFileName, вместо идентификатора иконки нужно вернуть ноль.
function CreateIconFromFile(const AFileName: UnicodeString; AOpenMode: DWORD; const AIconFileName: UnicodeString; AIconIndex: Integer; ASize: Integer): HICON;
Метод аналогичен методу CreateIconFromStream за исключением того, что вместо потока передается имя файла. Для создания потока для чтения данных из файла можно воспользоваться следующей функцией:
function CreateStream(const AFileName: UnicodeString; AOpenMode: DWORD = DefaultOpenMode): TStream;
После использования полученного потока его нужно удалить.
Обязательными для реализации в обработчике Icon являются следующие методы:
- GetClassID
- FillProgIDList
- CreateIconInfoFromStream или CreateIconInfoFromFile
- CreateIconFromStream или CreateIconFromFile
Смотрите также:
- Что такое расширение оболочки
- Какие бывают расширения оболочки
- Как создать расширение оболочки
- Инициализация расширений оболочки
- Как создать расширение оболочки Context menu
- Как создать расширение оболочки Drag and drop context menu
- Как создать расширение оболочки Drop target
- Как создать расширение оболочки Icon
- Как создать расширение оболочки Info tip
- Как создать расширение оболочки Overlay icon
- Как создать расширение оболочки Preview
- Как создать расширение оболочки Property sheet
- Как создать расширение оболочки Property store
- Как создать расширение оболочки Thumbnail
- Как зарегистрировать расширение оболочки
- Как отлаживать расширение оболочки
- Использование логов