Сайт Андрея Зайчикова
|
|
Магия функций с префиксом SH (Win32 SDK)Петр Семилетов
Не так уж давно я - с упоением алхимика, обращающего свинец в золото - ваял свой собственный файловый менеджер, по образу и подобию FAR'а и DOS Навигатора. И, конечно же, потребовалось - как минимум - реализовать стандартные функции работы с файлами: копирование, перенос, удаление, и т.п. Еще пригодились бы методы доступа к системным папкам и некоторые стандартные диалоги (которые я видел в других программах). Естественно, самому мне лень было думать или искать что-либо; и я решил обратиться с беспокоящим меня вопросом в несколько эхоконференций, посвященных Delphi и программированию в Windows - где обнаружил, что данная тема вовсю обсуждается, и прочел не меньше дюжины гениальных советов.
В частности, для тривиального, на первый взгляд, копирования файлов советовали "читать блоками один файл, и писать блоками в другой". Еще один безликий голос вещал: "берешь, создаешь TMemoryStream, ‘всасываешь’ в него файл, а потом сохраняешь поток в файл назначения, вот". Ну, вариант "всасывания" файла я отбросил сразу же; а над поблочным чтением задумался. Древняя истина гласит: чем больше я знаю - тем больше я не знаю. Как лучше реализовать копирование целых папок, вместе с вложенными в них директориями? А то же для переноса, удаления?.. На ум пришли унылые алгоритмы работы со списками, и радость творчества померкла. Перспектива вырисовывалась мрачная: придется работать… Однако, если верить буддистам и закон кармы существует, в прошлой жизни я совершил нечто хорошее, потому что путь познания привел меня прямиком к мощной штуке под названием Microsoft Win32 Software Development Kit. Вот тут все и вошло в русло... Итак, далее в статье при описании функции будем сначала приводить ее прототип на C++, описанный в shellapi.h, а затем - объяснять назначение (возможно, с примером использования в Delphi). Кстати, пользователям последнего продукта надо в секцию uses вписать юнит "shellapi"; и, кроме того, под WindowsNT функции, о которых пойдет речь, не работают… Ну-с; начнем, пожалуй, с изящной Это очень, очень мощная и многофункциональная вещь, которая умеет копировать, переносить, переименовывать и удалять как отдельные файлы, так и папки вместе с их содержимым. Хуже того - поддерживаются даже маски с wild-characters. Наша задача - только заполнить перед вызовом поля структуры lpFileOp; больше всего нас волнуют следующие поля: Для наглядности - вот пример функции-оболочки для копирования файлов на Object Pascal: SHFileOperation в случае неудачи возвращает ненулевое значение; мы это учитываем, и возвращаем Result = False, если что-то не в порядке. Другая полезная функция из ShellAPI (на этот раз объявленная в shlobj.h) - SHBrowseForFolder, позволяющая культурно выбрать нужную папку (рис. 1). Эта функция часто используется программистами - например, с ее помощью выбираются директории в AVP.Итак, представляем: Пользователям Delphi придется для ее использования добавить в секцию uses shellAPI, comobj и shlobj. Вначале опишем одну callback-функцию: Это для того, чтобы вывести в окне родителя (т.е. диалога выбора папки) приглашение-подсказку (посылаем соответствующее сообщение в родительское окно). Далее, сама функция SimpleSelectFolder будет иметь вид: Вуаля! теперь вызов StrMyFolder:=SimpleSelectFolder(handle) приведет к отображению диалога выбора директории - солидно, как в лучших домах Парижа. Пожалуй, на этом обзор простых функций из ShellAPI для работы с файлами пора завершать, поскольку функций с префиксом SH гораздо больше, чем я описал (загляните-ка в help по Win32 SDK…). Первый параметр - флаг, объясняющий, что именно представляет из себя объект, который мы просим занести в Recent: обычный путь (SHARD_PATH) или PIDL (SHARD_PIDL);второй же параметр - собственно указатель на данные. Если последний равен nil, то весь список документов очищается. Вот такая полезная вещь. Ну-с, надеюсь, вы почерпнули из этого материала полезную для себя информацию. |