PureBasic

Руководство - Структурирование кода в Процедурах

Мы снова собираемся пересмотреть пример свойств файла. На этот раз представить его в процедурах и попробуем устранить некоторые ограничения, которые были найдены в предыдущих вариантах программы.

; Структура для получения информации о файле.
Structure FILEITEM
    Name.s
    Attributes.i
    Size.q
    DateCreated.i
    DateAccessed.i
    DateModified.i
EndStructure

; Это - константа для идентификации окна.
Enumeration
    #WindowFiles
EndEnumeration

; Это - перечисление, для идентификации средств управления, которые появятся в окне.
Enumeration
    #FolderButton
    #UpdateButton
    #FolderText
    #FilesList
EndEnumeration

Procedure FilesExamine(Folder.s, List Files.FILEITEM())
    ; Получает свойства файла из папки в Files.

    Protected.l Result

    ; Очистить текущее содержание.
    ClearList(Files())

    ; Открывает каталог, чтобы перечислить все его содержимое.
    Result = ExamineDirectory(0, Folder, "*.*")

    ; Если Result - истина (т.е. каталог открыть удалось), начинаем перечисление записей.
    If Result
        ; Цикл пока NextDirectoryEntry(0) не станет нулем - что означает, что больше нет записей.
        While NextDirectoryEntry(0)
            ; Если запись каталога - файл, а не папка.
            If DirectoryEntryType(0) = #PB_DirectoryEntry_File
                ; Добавить новый элемент к списку.
                AddElement(Files())
                ; И заполнить его свойствами файла.
                Files()\Name = DirectoryEntryName(0)
                Files()\Size = DirectoryEntrySize(0)
                Files()\Attributes = DirectoryEntryAttributes(0)
                Files()\DateCreated = DirectoryEntryDate(0, #PB_Date_Created)
                Files()\DateAccessed = DirectoryEntryDate(0, #PB_Date_Accessed)
                Files()\DateModified = DirectoryEntryDate(0, #PB_Date_Modified)
            EndIf
        Wend

        ; Закрыть каталог.
        FinishDirectory(0)
    EndIf

    ; Сортируем список, путём упорядочения имён файлов в возрастающем алфавитном порядке (A, B, C, D...).
    SortStructuredList(Files(), #PB_Sort_Ascending, OffsetOf(FILEITEM\Name), #PB_String)
EndProcedure

Procedure.s FolderSelect(Folder.s)
    ; Отображение запроса пути и возвращает новый путь, или старый, если пользователь нажал отмену.
    Protected.s SelectedPath

    SelectedPath = PathRequester("Choose a folder.", Folder)

    If SelectedPath = ""
        SelectedPath = Folder
    EndIf

    ProcedureReturn SelectedPath
EndProcedure

Procedure LabelUpdate(Folder.s)
    ; Обновление метки папки.
    SetGadgetText(#FolderText, Folder)
EndProcedure

Procedure ListLoad(ListView.l, List Files.FILEITEM())
    ; Загружает свойства файлов из списка Files() в представление списка #FilesList.
    Protected.s Access, Attrib, Create, Folder, Modify, Msg, Num, Size

    ; Удаляет предыдущее содержимое.
    ClearGadgetItems(ListView)

    ForEach Files()
        ; Отображение Номера позиции и имени файла.
        Num = StrU(ListIndex(Files()) + 1)

        ; Эти строки преобразовывают значения дат создания и т.д. файла в привычный вид.
        Create = FormatDate("%dd/%mm/%yyyy", Files()\DateCreated)
        Access = FormatDate("%dd/%mm/%yyyy", Files()\DateAccessed)
        Modify = FormatDate("%dd/%mm/%yyyy", Files()\DateModified)

        ; Преобразуем размер файла в строку с дополнением пробелов, так же как с индексным значением выше,
        ; но зададим размер строки для размещения максимального размера значения типа quad.
        Size = StrU(Files()\Size)

        ; Преобразуем атрибуты в строку.
        Attrib = StrU(Files()\Attributes)

        ; Создайте строку для вывода.
        ; Символ перевода строки "Chr(10)" указывает Гаджету перейти к следующему столбцу.
        Msg = Num + Chr(10) + Files()\Name + Chr(10) + Create + Chr(10) + Access + Chr(10) + Modify + Chr(10) + Attrib + Chr(10) + Size

        ; Добавляет строку к Гаджету представления списка.
        AddGadgetItem(#FilesList, -1, Msg)
    Next Files()
EndProcedure

Procedure WindowCreate()
    ; Создает окно wdwFiles.
    Protected Flags

    ; Эта строка определяет флаг для атрибутов окна, посредством объединения вместе через ИЛИ,  желаемых констант атрибута.
    Flags = #PB_Window_SystemMenu - #PB_Window_SizeGadget - #PB_Window_MinimizeGadget - #PB_Window_MaximizeGadget| #PB_Window_TitleBar

    ; Открывает окно.
    OpenWindow(#WindowFiles, 50, 50, 450, 400, "File Properties", Flags)
    ; Кнопка для выбора папки.
    ButtonGadget(#FolderButton, 5, 5, 100, 30, "Select Folder")
    ; Кнопка для обновления списка.
    ButtonGadget(#UpdateButton, 112, 5, 100, 30, "Update List")
    ; Текстовый Гаджет для отображения имени папки.
    TextGadget(#FolderText, 5, 40, 400, 25, "")
    ; Гаджет значка списка для хранения списка файлов и свойств.
    ListIconGadget(#FilesList, 5, 70, 400, 326, "#", 35)
    ; Добавляет столбцы в ListIconGadget для хранения каждого свойства.
    AddGadgetColumn(#FilesList, 1, "Name", 200)
    AddGadgetColumn(#FilesList, 2, "Created", 100)
    AddGadgetColumn(#FilesList, 3, "Accessed", 100)
    AddGadgetColumn(#FilesList, 4, "Modified", 100)
    AddGadgetColumn(#FilesList, 5, "Attributes", 150)
    AddGadgetColumn(#FilesList, 6, "Size", 100)
EndProcedure

Procedure WindowDestroy()
    ; Закрывает окно.
    ; Если нужно, сюда можно вписать и другие функции.
    CloseWindow(#WindowFiles)
EndProcedure

Procedure WindowResize()
    ; Изменяет размер Гаджета окна в соответствии с размером окна.
    ResizeGadget(#FolderText, #PB_Ignore, #PB_Ignore, WindowWidth(#WindowFiles) - 10, #PB_Ignore)
    ResizeGadget(#FilesList, #PB_Ignore, #PB_Ignore, WindowWidth(#WindowFiles) - 10, WindowHeight(#WindowFiles) - 74)
EndProcedure

;- Главный код.
; Теперь мы определяем список файлов, используя ранее указанную структуру.
NewList Files.FILEITEM()

; И некоторые переменные, которые нам понадобятся.
Define.s Folder
Define.l Event, EventWindow, EventGadget, EventType, EventMenu

; Эта функция получает корневой каталог вошедшего в систему пользователя.
Folder = GetHomeDirectory()

; Создаёт окно и задаёт начальное содержание.
WindowCreate()
WindowResize()
LabelUpdate(Folder)
FilesExamine(Folder, Files())
ListLoad(#FilesList, Files())

;- Цикл событий
Repeat
    ; Ожидание, пока не произойдёт новое событие окна или Гаджета.
    Event = WaitWindowEvent()
    EventWindow = EventWindow()
    EventGadget = EventGadget()
    EventType = EventType()

    ; Принятие мер, в зависимости от события.
    Select Event
        Case #PB_Event_Gadget
            ; Имело место событие Гаджета.
            If EventGadget = #FolderButton
                ; Была нажата кнопка папки.
                Folder = FolderSelect(Folder)
                LabelUpdate(Folder)
                FilesExamine(Folder, Files())
                ListLoad(#FilesList, Files())

            ElseIf EventGadget = #UpdateButton
                ; Была нажата кнопка обновления.
                FilesExamine(Folder, Files())
                ListLoad(#FilesList, Files())

            ElseIf EventGadget = #FolderText
                ; Здесь ничего не делать.

            ElseIf EventGadget = #FilesList
                ; Здесь ничего не делать.

            EndIf

        Case #PB_Event_SizeWindow
            ; Окно было перемещено или изменено в размерах.
            If EventWindow = #WindowFiles
                WindowResize()
            EndIf

        Case #PB_Event_CloseWindow
            ; Окно было закрыто.
            If EventWindow = #WindowFiles
                WindowDestroy()
                Break

            EndIf
    EndSelect
ForEver

Ранее, мы упомянули четыре ограничения этой программе. Эта новая версия использует процедуры, чтобы устранить три из них.

1) Вы не могли выбрать папку для просмотра.
Процедура "FolderSelect" выдаёт запрос пути, чтобы позволить пользователю выбрать папку. Переменная "Folder" обновляет своё значение от результата этой процедуры. Кнопка также вызывает "LabelUpdate", "FilesExamine" и "ListLoad", чтобы отобразить содержимое новой папки в окне.

2) Вы не могли обновить содержание списка не перезапуская программу.
Теперь при нажатии кнопки "Update List", автоматически вызываются "FilesExamine" и "ListLoad" и происходит обновление дисплея.

3) Если Вы изменяли размеры окна, Гаджеты не адаптировались под новый размер.
Теперь процедура "WindowResize" вызывается автоматически в цикле событий, когда форма изменяет размер, что позволяет автоматически изменять размеры Гаджетов. Кроме того, эту процедура вызывается после вызова "WindowCreate", чтобы быть уверенным, что Гаджеты - имеют правильный размер изначально.

Заметьте, что некоторые процедуры вызываются по несколько раз, чтобы выполнить подобные, но не идентичные функции. Это повышает эффективность программы.

В программе осталось последнее ограничение, которое мы устраним позднее.

Навигация Руководства

< Отображение графики & простых рисунков - Обзор - Директивы компилятора >