Класс TdecShellFileList
Расширения оболочки, такие как Context menu или Property Sheet, в общем случае работают не с одним файлом, а с несколькими. В ОС Windows существуют несколько форматов представления списка файлов, основанных на интерфейсе IDataObject, которые и используются при передаче списка в расширение оболочки. В каждой новой версии ОС Windows количество форматов растет, новые форматы позволяют производить более быструю навигацию, позволяют передавать "виртуальные" файлы, например, объекты Корзины или файлы из состава zip-архива. В целях обратной совместимости даже в Windows 8 в дополнение к новым форматам все также используются и старые. Но расширением оболочки также может пользоваться не только сама ОС Windows, но и любая другая программа, и нет гарантий, что эта программа будет также использовать старые форматы. Поэтому идеальное расширение должно поддерживать все форматы представления списка файлов, как старые, так и новые. Именно это и реализовано в библиотеке Shell Ace через класс TdecShellFileList.
В библиотека Shell Ace вся работа с форматами происходит незаметно для разработчика. Разработчик получает для работы объект класса TdecShellFileList, в недрах которого скрыта вся работа по обработке всех форматов списков файлов.
В классе TdecShellFileList поддерживаются следующие форматы списков файлов:
- CF_FILENAMEA, CF_FILENAMEW
- CF_FILEDESCRIPTORA, CF_FILEDESCRIPTORW, CF_FILECONTENTS
- CF_HDROP
- CF_IDLIST
Класс TdecShellFileList предоставляет унифицированный интерфейс получения списка файлов, не зависящий от формата. Интерфейс представляет собой следующие методы класса TdecShellFileList:
function FindFirst(var ASearchRec: TdecSearchRec): TdecSearchHandle;
Функция ищет первый файл в списке. В случае удачи функция вернет идентификатор перечисления, отличный от нуля, а параметр ASearchRec будет заполнен информацией о файле. Если файл не найден, то возвращаемый идентификатор будет равен нулю, а значение параметра ASearchRec будет не определено.
Тип TdecSearchRec представляет собой запись:
TdecSearchRec = record
FileName: UnicodeString;
Attr: DWORD;
CreationTime: TFileTime;
LastAccessTime: TFileTime;
LastWriteTime: TFileTime;
FileSize: Int64;
end;
В поле FileName записано имя файла, включая путь (при его наличии). В поле Attr записаны атрибуты файла. В поля CreationTime, LastAccessTime и LastWriteTime записаны даты создания, последнего доступа и модификации файла. В поле FileSize записан размер файла.
function FindNext(ASearchHandle: TdecSearchHandle; var ASearchRec: TdecSearchRec): Boolean;
Функция ищет следующий файл в списке. В параметре ASearchHandle передается полученный в методе FindFirst идентификатор. В случае, если следующий файл в списке найден успешно, то функция вернет True, а параметр ASearchRec будет заполнен информацией о файле. В случае, если файлов в списке более нет, то функция вернет False, а значение параметра ASearchRec будет не определено.
procedure FindClose(ASearchHandle: TdecSearchHandle);
Функция освобождает все ресурсы, связанные с перечислением файлов.
function CreateFileStream(ASearchHandle: TdecSearchHandle; const ASearchRec: TdecSearchRec; AOpenMode: DWORD = DefaultOpenMode; ASeekSupport: Boolean = True): TStream;
Функция предназначена для создания потока с данными файла, описанного в параметре ASearchRec. В параметре ASearchHandle передается полученный в методе FindFirst идентификатор. В параметре ASearchRec передается запись, полученная в методе FindFirst или FindNext. Параметр AOpenMode определяет режим открытия файла. Доступны следующие значения:
- STGM_READ – файл открывается только для чтения, константа DefaultOpenMode имеет именно это значение.
- STGM_READWRITE – файл открывается как для чтения, так и для записи, поддерживается не всеми форматами списков файлов.
При передаче списка файлов в формате CF_FILEDESCRIPTOR ОС Windows создает потоки данных, которые не поддерживают функцию Seek. При использовании такого потока при вызове данного метода возникнет исключение. Для предотвращения такой ситуации можно определить параметр ASeekSupport в значение True. При этом библиотека Shell Ace при необходимости создаст временный поток, в который будет скопировано все содержимое оригинального потока, и этот временный поток будет поддерживать функцию Seek. Нужно учитывать, что это влечет за собой дополнительный расход памяти, поэтому если функциональность метода Seek не требуется, то лучше установить параметр ASeekSupport в значение False.
function CreateFolderFileList(ASearchHandle: TdecSearchHandle; const ASearchRec: TdecSearchRec): TdecShellFileList;
Функция предназначена для создания нового объекта класса TdecShellFileList, который будет перечислять содержимое директории, описанной в параметре ASearchRec. В параметре ASearchHandle передается полученный в методе FindFirst идентификатор. В параметре ASearchRec передается запись, полученная в методе FindFirst или FindNext.
function CreateFileList: TStrings;
Функция создает объект класса TStrings, который будет содержать имена всех файлов и директорий списка. В списке могут быть как имена реальных файлов, так и виртуальных. В версиях Delphi вплоть до версии 2009, в которых тип string равен типу AnsiString, имена файлов в списке хранятся в формате UTF8. После работы со списком он должен быть удален. Для перевода имени файла из сроки, хранящейся в TStrings в UnicodeString можно воспользоваться функцией StringToUnicodeString. Эта функция в версиях Delphi вплоть до версии 2009 производит преобразование строки из UTF8 в UnicodeString, в более старших версиях просто возвращает переданное значение.
function IsSingleFile: Boolean;
Функция вернет True, если список состоит из одного файла.
function GetCount: Integer;
Функция вернет количество файлов и директорий в списке.
В общем случае работа со объектом класса TdecShellFileList происходит следующим образом:
procedure Work(AFileList: TdecShellFileList);
var SearchHandle: THandle;
SearchRec: TdecSearchRec;
begin
SearchHandle := AFileList.FindFirst(SearchRec);
if SearchHandle <> 0 then
try
repeat
// Process file or folder
until not AFileList.FindNext(SearchHandle, SearchRec);
finally
AFileList.FindClose(SearchHandle);
end;
end;
Содержимое списка в общем случае может быть совершенно разным. В списке могут быть файлы из разных директорий. В списке могут быть не только файлы, но и директории. В списке могут быть не только реальные файлы и директории, но и виртуальные. Это может быть, например, вложение из электронного письма или файл из zip-архива.
Определить, что в параметре SearchRec возвращена директория можно по наличию флага FILE_ATTRIBUTE_DIRECTORY в поле Attr, а определить, что объект является виртуальным можно по наличию флага FILE_ATTRIBUTE_VIRTUAL.
Смотрите также:
- Что такое расширение оболочки
- Какие бывают расширения оболочки
- Как создать расширение оболочки
- Инициализация расширений оболочки
- Как создать расширение оболочки Context menu
- Как создать расширение оболочки Drag and drop context menu
- Как создать расширение оболочки Drop target
- Как создать расширение оболочки Icon
- Как создать расширение оболочки Info tip
- Как создать расширение оболочки Overlay icon
- Как создать расширение оболочки Preview
- Как создать расширение оболочки Property sheet
- Как создать расширение оболочки Property store
- Как создать расширение оболочки Thumbnail
- Как зарегистрировать расширение оболочки
- Как отлаживать расширение оболочки
- Использование логов