
Основы программирования в среде Lazarus / Основы программирования в среде Lazarus / Основы программирования в среде Lazarus
.pdfГлава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
// Определение логических дисков
if Find_Logical_Disks() then
begin
SetAllDirectories;
SetDirWin:= true;
end
else
{Если произошла ошибка в функции Find_Logical_Disks(),
то выбираем корневой каталог текущего диска}
SetCurrentDir('\');
{$ELSE}
SetCurrentDir('/'); // корневой каталог в Linux {$ENDIF}
if not SetDirWin then begin
path:= GetCurrentDir;
if FindFirst(path + '*', faDirectory, srNode) = 0 then
begin repeat
// Показываем только каталоги
if (srNode.Attr and faDirectory <> 0) and (Real_Directory(srNode.Name)) then begin
Node:= TreeView1.Items.AddChild(nil,
SysToUTF8(srNode.Name));
Node.ImageIndex:= 0;
Node.SelectedIndex:= 0;
{$IFDEF WINDOWS}
671
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
searchMask:= path + srNode.Name + '\*'; {$ELSE}
searchMask:= path + srNode.Name + '/*'; {$ENDIF}
if FindFirst(searchMask, faDirectory, srChild) = 0 then
repeat
if (srChild.Attr and faDirectory <> 0) and Real_Directory(srChild.Name)
then Node.HasChildren:= true; until (FindNext(srChild) <> 0) or Node.HasChildren;
// Освобождение занятых ресурсов
SysUtils.FindClose(srChild);
end;
until FindNext(srNode) <> 0;
// Освобождение занятых ресурсов
SysUtils.FindClose(srNode);
end;
end;
TreeView1.EndUpdate;
end;
procedure TForm1.Show_Only_Dir(ParentNode: TTreeNode); var
srNode, srChild: TSearchRec; Node: TTreeNode;
path: string; searchMask: string;
672
Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
begin
Node:= ParentNode; path:= '';
repeat
{$IFDEF WINDOWS}
path:= UTF8ToSys(Node.Text) + '\' + path; {$ELSE}
path:= '/' + Node.Text + '/' + path; {$ENDIF}
Node:= Node.Parent; until Node = nil;
if FindFirst(path + '*', faDirectory, srNode) = 0 then repeat
if (srNode.Attr and faDirectory <> 0) and Real_Directory(srNode.Name) then
begin
Node:= TreeView1.Items.AddChild(ParentNode,
SysToUTF8(srNode.Name));
Node.ImageIndex:= 0;
Node.SelectedIndex:= 0;
{$IFDEF WINDOWS}
searchMask:= path + srNode.Name + '\*'; {$ELSE}
searchMask:= path + srNode.Name + '/*'; {$ENDIF}
if FindFirst(searchMask, faDirectory, srChild) = 0 then
repeat
if (srChild.Attr and faDirectory <> 0) and
673
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
Real_Directory(srChild.Name) then Node.HasChildren:= true;
until (FindNext(srChild) <> 0) or Node.HasChildren; SysUtils.FindClose(srChild);
end;
until FindNext(srNode) <> 0; SysUtils.FindClose(srNode);
end;
procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
if Node = nil then exit; TreeView1.BeginUpdate; Node.DeleteChildren; Show_Only_Dir(Node); Node.Expanded:= true; TreeView1.EndUpdate;
end;
procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean); begin
TreeView1.BeginUpdate;
Node.DeleteChildren;
Show_Only_Dir(Node);
TreeView1.EndUpdate;
end; initialization
674

Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
{$I unit1.lrs}
end.
Рассмотрим процедуру FormCreate. В ней, если это Windows, с помо-
щью функции Find_Logical_Disks() и процедуры
SetAllDirectories определяются имена разделов жестких дисков и выво-
дятся в TreeView1. Окно программы для Windows будет иметь вид, рис. 6.76:
Рис. 6.76. Вид окна программы в Windows
В Linux файловая система организована совсем по-другому. Поэтому мы оператором SetCurrentDir('/');
устанавливаем корневой каталог и программа сканирует каталоги только верх-
него уровня, рис. 6.77.
675

6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
Рис. 6.77. Вид окна программы в Linux
Таким образом, наша программа не сканирует все диски и каталоги. Про-
грамма вначале лишь определяет буквы дисков и разделов дисков (если это
Windows) или сканирует только каталоги самого верхнего уровня, расположен-
ные в корневом каталоге (если это Linux).
Лишь при нажатии пользователем на какой-либо узел или на кнопку рас-
крытия этого узла, программа начнет сканировать каталоги, расположенные на один уровень ниже и только для текущего каталога. Поясню примером. Пусть мы находимся в каталоге C:\lazarus\components\lazreport или
/usr/lib/lazarus/components/lazreport.
При нажатии на узел с именем 'lazreport' программа просканирует этот каталог и найдет пять подкаталогов doc, images, samples, source, tools.
При этом эти подкаталоги имеют в свою очередь еще вложенные подкаталоги,
но всех их программа в данный момент сканировать не будет! Для того чтобы определить, что, например, каталог samples имеет вложенные подкаталоги,
программе достаточно найти только один подкаталог (первый попавшийся!). В
нашем случае это будет каталог barcode.
Это позволяет значительно ускорить работу программы.
676
Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
Рассмотрим процедуру Show_Only_Dir, которая и реализует изложен-
ный алгоритм. Процедура вызывается в обработчиках OnChange и OnExpanding. Вначале, процедура определяет полный путь к текущему ката-
логу, двигаясь снизу вверх от дочернего узла к родительскому и до корневого.
Затем запускается цикл поиска FindFirst – FindNext с помощью которо-
го находятся все подкаталоги текущего каталога. Вложенный цикл
FindFirst – FindNext позволяет определить, имеются ли у найденных подкаталогов вложенные подкаталоги. Этот внутренний цикл завершается, как только вложенный каталог найден, а его родитель помечается признаком
Node.HasChildren:= true.
Отметим еще, что перед вызовом процедуры Show_Only_Dir мы опера-
тором
Node.DeleteChildren
удаляем все потомки текущего узла, поскольку процедура заново формирует их.
Точно по такому же алгоритму сканируется корневой каталог в обработчике
OnCreate.
Вот, собственно и все! Осталось пояснить, для чего предназначена функция
Real_Directory().
Как известно, в каждом каталоге имеются две особые записи. Одна из них обозначается просто точкой и является ссылкой на текущий каталог, а вторая запись, обозначаемая двумя точками (по стандарту так и читается точка-точка)
является ссылкой на родительский каталог. Функции FindFirst–FindNext
их находят и идентифицируют как каталоги. Но, обычно, в дереве каталогов их не принято показывать. Поэтому функция Real_Directory()проверяет, не является ли имя найденного каталога точкой или точкой-точкой и возвращает
677
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
true, если это не так.
Компонент TListView
В отличие от TListBox компонент TListView позволяет отображать данные в разных стилях или режимах. Так, данные могут отображаться в виде списка, крупных или мелких пиктограмм и, наконец, в виде таблицы. Стиль отображения задается свойством ViewStyle, табл. 6.5.
Элементы списка содержатся в свойстве Items объекта TListItem.
Компонент можно заполнять как вручную, во время проектирования, так и про-
граммно. Для ручного заполнения имеется редактор, похожий на редактор
TTreeView. В нем точно так же задаются "Новый элемент" и "Новый подэле-
мент". В отличие от TTreeView в TListView допускается не более одного уровня вложенности подэлементов.
|
Таблица 6.5 |
Значение |
Стиль отображения данных |
|
|
vsIcon |
Элементы списка появляются в виде больших знач- |
|
ков с надписью под ними. Картинки для больших |
|
значков хранятся в компоненте TImageList ука- |
|
занном в свойстве LargeImages. Возможно их |
|
перетаскивание. |
|
|
vsSmallIcon |
Элементы списка появляются в виде маленьких |
|
значков с надписью справа. Картинки для малень- |
|
ких значков хранятся в компоненте TImageList |
|
указанном в свойстве SmallImages. Возможно их |
|
перетаскивание |
|
|
vsList |
Элементы списка появляются в колонке один под |
|
другим с надписью справа. Перетаскивание невоз- |
|
можно |
|
|
678

Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
vsReport |
Элементы списка появляются в нескольких колон- |
|
ках один под другим. В первой содержится малень- |
|
кий значок и надпись, в остальных — определенная |
|
программистом информация. Если свойство Show- |
|
ColumnHeaders установлено в значение true, |
|
колонки снабжаются заголовками |
|
|
Как и в TTreeView изображения необходимо предварительно занести в
TImageList, затем указывать индекс нужного изображения в свойстве
ImageIndex, рис. 6.78.
|
Рис. 6.78. Редактор элементов TListView |
|
|
|||
Но |
подэлементы |
будут |
видны |
только |
в |
режиме |
vsReport. Для того чтобы информация, введенная на рис. 6.78. была видна,
необходимо создать четыре колонки (столбца). Для этого в Инспекторе объек-
тов нажмите кнопку с многоточием напротив свойства Columns, появится ре-
дактор колонок рис. 6.79. Чтобы добавить колонку нажмите кнопку "Добавить".
В Инспекторе объектов появятся свойства этой колонки, рис. 6.80. Свойст-
во Caption задает заголовок колонки, свойство Width ширину колонки. Ус-
679

6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
тановите необходимые свойства для каждого из четырех колонок и запустите программу, рис. 6.81.
Рис. 6.79. Редактор колонок Рис. 6.80. Свойства колонки
Рис. 6.81. Окно программы
Рассмотрим основные свойства компонента:
Columns – содержит объекты – колонки (столбцы). Колонки видны только для стиля отображения ViewStyle = vsReport. При этом должна быть оп-
ределена хотя бы одна колонка. Иначе элементы не будут видны;
Column[Index: integer] – открывает доступ к колонкам элементов по их индексам;
ColumnClick: boolean – разрешает или запрещает генерацию события
680