Смекни!
smekni.com

Файловый менеджер (стр. 2 из 7)

Функция DeleteChild выполняет обратную операцию – удаляет внуков сворачиваемого узла, тем самым предостерегается возможность двукратного дополнения узла в дерево.

Из этих правил есть одно исключение – ситуация, когда среди потомков сворачиваемого узла есть развернутые ветви. Удаление внуков в этом случае приведет к нарушению структуры дерева (развернутые внутри сворачиваемого узла узлы будут свернуты). Проверку такой ситуации осуществляет функция CheckExpandedChild – она возвращает true в случае наличия хотя бы одного развернутого потомка у переданного в качестве параметра узла.

V. Функция формирования списка файлов и каталогов: void ViewFailAndFolderInListView (AnsiString dir).

Задача функции проста: вывести на экран содержание переданной по параметру папки dir. Порядок ее осуществления: очистка списка, поиск файлов (папок) в указанном каталоге функциями FindFirst, FindNext, FindClose, добавление соответствующих найденным файлам записей вышеописанной функцией AddItemInListView, сохранение текущего каталога, обновление статусной панели информации.

VI. Функция выполнения операций над файлами intFileAndFolderOperation(char *frombuf, char *tobuf, unsignedintoperation) и вспомогательная функция формирования строки-списка файлов void PrepareBufForOperationInListView(char * &).

Функция FileAndFolderOperationвыполняет простую операцию – согласно полученным данным: символьному массиву «откуда копировать» frombufи массиву «куда копировать» tobuf, а также коду операции заполняет структуру SHFILEOPSTRUCT и передает ее на обработку API функции SHFileOperation, а также возвращает результат ее выполнения.

Самой сложной частью выполнения операций над файлами является заполнение символьной строки frombuf, особенно для ListView, т.к. позволяется выделение целой группы файлов и папок. Буфер же frombuf должен содержать пути ко всем объектам, разделенные символом ‘\0’ и заканчивающиеся двойным символом нуля. Именно для этого введена процедура PrepareBufForOperationInListView. В данной процедуре осуществляется анализ выделенных объектов в ListView и соответствующее заполнение буфера frombuf. Для этого используется ряд вспомогательных процедур: strcat0 и finstr. Первая соединяет две строки, оставляя между ними символ нуля, вторая финализирует строку – добавляет в конце два символа двойного нуля.

VII. Функции обновления дерева, списка, меток: void UpdateTreeView(bool UpdateAllways), void UpdateListView(bool UpdateAllways), void UpdateLabel(), void UpdateAll(bool UpdateAllways) и вспомогательная функция void RecursTree(TTreeNode *node,bool UpdateAllways).

Обновление дерева каталогов осуществляется двумя функциями – UpdateTreeView и RecursTree. Первая – бутафорская и осуществляет лишь запуск рекурсивной функции RecursTree. Ее основная задача – найти вершину дерева и передать ее в RecursTree.

Функция RecursTree осуществляет подсчет числа папок в переданной ее директории и сравнивает с числом детей, соответствующего директории узла. Несовпадение этих переменных запускает цикл проверки. В случае большего количества узлов-потомков проверяется наличие-отсутствие соответствующих им папок. Отсутствие папки приводит к удалению узла, сопоставленного ей, и всех его потомков. В обратной ситуации, перебираются папки, и выясняется какой из соответствующих им узлов нужно добавить. Рекурсивная функция запускает себя вновь, если текущий узел раскрыт – соответственно начинается обход потомков потомков. Отсутствие раскрытия приводит к рекурсивному возврату.

Обновление списка файлов аналогично и даже проще. Отпадает необходимость использования рекурсивных функций – уровень только один. В функции UpdateListView аналогично осуществляется сравнение количества папок в текущем каталоге с количеством записей, их несоответствие приводит к ряду проверок, описанных выше. Добавляется еще одна проверка на наличие текущего каталога. Его отсутствие означает простую очистку списка и указания текущей пустой папки.

В задачу функции UpdateLabel входит просмотр меток всех приводов и переформирование заголовков дисков дерева в соответствии с найденной информацией.

Объединение всех функций обновления осуществляется процедурой UpdateAll, помимо вызовов вышеперечисленных функций обновляется и панель статуса - пересчитываются элементы списка, переопределяется свободное место на диске.

Во все функции обновления передается в качестве параметра булева переменная UpdateAllways. Установка этой переменной в true означает принудительную проверку списка и дерева даже в том случае, если количество записей совпадает с числом сопоставленных элементов. Это полезно например при переименовании – число записей не меняется, но меняются их имена.

VIII. ФункцияпереименованияAnsiString RenameFileOrFolder(AnsiString NewName).

Данная функция получает параметром новое имя для находящегося в фокусе объекта. Путем проверки состояния ListViewи TreeView и определения находящегося в фокусе узла, определяется текущий объект и путь к нему (по свойству Data). Затем формируются символьные массивы » frombuf, исходя из бывшего пути, и tobuf, по новому имени. Осуществление попытки переименования заканчивается возвратом либо нового имени, в случае ее удачи, либо прежнего, если переименование не удалось. Это полезно в функция редактирования имен узлов – узлу назначается имени, возвращенное функцией.

IX. Функцияудаленияvoid DeleteFileOrFolder().

Работа функции довольно проста – необходимо определить какой из элементов в фокусе (ListViewили TreeView), заполнить массив frombuf путями, соответствующими выделенным там узлам (согласно свойству узлов Data), передать все это на обработку функции FileAndFolderOperation с указанием операции – FO_DELETE.

X. Функция создания папки void CreateFol().

Идея построения данной функции такова – создается папка с произвольным именем, но после создания фокус немедленно передается записи, отображающей ее, с указанием редактирования. Тем самым пользователь получает возможность немедленно изменить ее имя на любое другое. Таким образом задействуется вышеописанная функция переименования. Формирование имени папки осуществляется из сочетания «Новая папка» и числа, которое подбирается таким образом, чтобы соответствующая папка отсутствовала в системе.

XI. СлужебныефункцииListView: void ExpandTreeForFile(AnsiString FileName) иvoid OpenFileOrFolder().

Функция OpenFileOrFolder вызывается при клике на элементе списка ListView и осуществляет соответствующую операцию: при клике на папке – открывает ее, при клике на файле – запускает его. По щелчку на папке происходит вызов ViewFailAndFolderInListView с указанием пути к ней для отображения содержимого, по щелчку на файле предпринимается попытка запустить его функцией ShellExecute. Если попытка запуска неудачна, на экран выводится сообщение об ошибке, возвращаемое GetLastError.

Вызов функции ExpandTreeForFileосуществляется лишь из процедуры OpenFileOrFolder и предназначен для раскрытия ветвей дерева до текущей папки, при ее изменении. Новая текущая папка передается в функцию в качестве параметра, где этот путь последовательно разбивается на части и сопоставляется различным узлам дерева. Последовательным проходом сверху-вниз осуществляется раскрытие узлов, соответствующих родительским директориям, содержащим данную папку, и выделение новой текущей директории в дереве TreeView. Так становится возможной связь компонента ListViewс TreeView: изменение текущей директории в ListView приводит к изменению выделения текущего контейнера в TreeView.

XII. Функции работы с буфером: void PasteFileFromClipboard(), void CopyFileToClipboard(bool Copy).

При включении возможности работы с буфером была поставлена задача полной совместимости формата передаваемых файлов с форматом, используемым файловыми менеджерами Windows, например, «Проводником». Этим форматом является CF_HDROP, предполагающий наличие в буфере указателя на структуру DROPFILES и следующую за ней строку последовательно перечисленных путей к объектам, помещенным в буфер.

Исходя из этого, реализация операции по вставке файлов из буфера была осуществлена в следующем порядке: открытие буфера OpenClipboard, проверка наличия в буфере данных нужного формата функцией IsClipboardFormatAvailable; получение указателя на данные GetClipboardData и, наконец, определение их количества и последовательное извлечение строк API функцией DragQueryFile. На основании полученных строк формируется массив frombuf передаваемый на обработку.

Еще одной проблемой стало получение информации о необходимости копирования, либо перемещения файла. Стандартом является получение указателя из буфера по регистрируемому формату CFSTR_PREFERREDDROPEFFECT. Указатель содержит адрес в памяти, по которому находится четыре байта информации о типе перемещения/копирования. Сравнением этих данных с константами и вызовом функции FileAndFolderOperation и завершается вставка файлов (папок) из буфера. Закрытие буфера по окончании функции разрешает доступ к нему для других программ.

Функция voidCopyFileToClipboard(boolCopy) универсальная и в зависимости от переданного ей параметра осуществляет либо копирование, либо перемещение файла в буфер (точнее, лишь указание на перемещение или копирование). Результатом анализа переданного параметра является выделением памяти под двойное слово и помещение в нее соответствующей константы DROPEFFECT_COPY или DROPEFFECT_MOVE. Передача информации о копируемых файлах осуществляется последовательным заполнением структуры DROPFILES, построением буфера frombuf и перемещения этих данных в память. После открывается буфер, функцией SetClipboardData в буфере размещаются данные о фалах и типе операции, буфер закрывается – данные готовы к копированию (перемещению).


3.Конструкторская часть

файловый менеджер система пользовательский

I. TreeView1 : TTreeView

Данный визуальный объект изображает дерево каталогов и настраивается динамически в процессе работы путем добавления/удаления узлов. Основные события, участвующие в формировании дерева – OnExpanded и OnCollapsing, возникающие соответственно при раскрытии и свертывании некоторого узла. По первому событию осуществляется помещение в дерево внуков раскрываемого узла посредством функции ViewChild, по последнему – удаление внуков сворачиваемого узла процедурой DeleteChild. Пользователь полностью скрыт от информации об изменении структуры дерева.