:: MVP ::
|
|
:: RSS ::
|
|
|
Сегодня нам предстоит знакомство с одним очень интересным компонентом
Delphi - TreeView. TreeView служит для показа ветвящихся иерархических
структур, например - файловой структуры диска. TreeView содержит
основные узлы, каждый из которых может содержать пиктограмму, текст и
произвольный объект, и в свою очередь может иметь собственный список
подузлов.
Для ввода списка в режиме прогона программы можно использовать свойство
Item типа TTreeNodes, открывающее индексированный доступ ко всем узлам
списка. Ниже приведен простой пример на использование этого свойства.
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
with TreeView1 do
begin
// Добавляем корневой узел
Items.Add( nil, 'Корень' );
// Добавляем 10 вложенных узлов
for i := 1 to 10 do
Items.AddChild( Items[i-1], IntToStr( i ) );
end;
end;
|
Рассмотрим некоторые полезные свойства этого компонента:
- TreeView1.Items.BeginUpdate - блокирует обновление экрана до тех пор,
пока не будет выполнен метод EndUpdate. Используется при одновременной
вставке нескольких элементов списка для предотвращения мерцания
экрана.
- TreeView1.Items.EndUpdate - отменяет действие метода BeginUpdate.
- TreeView1.FullExpand - показывает все узлы дерева иерархии.
- TreeView1.FullCollapse - прячет все узлы, кроме узлов самого верхнего
уровня иерархии.
Вернемся к дереву каталогов. Первое, что мы сделаем при запуске программы,
выведем в TreeView список всех дисков, имеющихся на компьютере. На этом этапе
мы не станем проверять наличие каталогов на дисках, так как такая проверка
на дисководе займет много времени. Проверять наличие каталогов будем в момент
раскрытия узла. В свою очередь, в найденный каталогах мы попытаемся найти
хоть одну папку. От результата поиска зависит, появится в данном узле знак "+",
говорящий о наличии подкаталогов, или нет. Иконки для TreeView будем брать из
файла FileCtrl.res, находящемся в каталоге "Delphi6\lib".
implementation
{$R *.dfm}
{$R FileCtrl}
procedure TForm1.FormCreate(Sender: TObject);
const
IconNames: array [0..6] of string = ( 'CLOSEDFOLDER',
'OPENFOLDER',
'FLOPPY',
'HARD',
'NETWORK',
'CDROM',
'RAM' );
var
node: TTreeNode;
DriveType: integer;
bm, mask: TBitmap;
i: integer;
begin
// Запрещаем обновление TreeView
TreeView1.Items.BeginUpdate;
// Создаем список иконок
TreeView1.Images := TImageList.CreateSize( 16, 16 );
bm := TBitmap.Create;
mask := TBitmap.Create;
for i := 0 to 6 do
begin
bm.Handle := LoadBitmap( HInstance, PChar( IconNames[i] ) );
bm.Width := 16;
bm.Height := 16;
mask.Assign( bm );
mask.Mask( clBlue );
TreeView1.Images.Add( bm, mask );
end;
bm.Free;
mask.Free;
// Находим диски и выводим их в TreeView
for i := 0 to 25 do
begin
DriveType := GetDriveType( PChar( Chr( i + 65 ) + ':\' ) );
if DriveType = 1 then continue;
node := Form1.TreeView1.Items.AddChild( nil, Chr( i+65 ) + ':' );
case DriveType of
DRIVE_REMOVABLE: node.ImageIndex := 2;
DRIVE_FIXED: node.ImageIndex := 3;
DRIVE_REMOTE: node.ImageIndex := 4;
DRIVE_CDROM: node.ImageIndex := 5;
else
node.ImageIndex := 6;
end;
node.SelectedIndex := node.ImageIndex;
node.HasChildren := true;
end;
// Обновляем TreeView
TreeView1.Items.EndUpdate;
end;
|
При раскрытии узла возникает событие onExpanding, которое мы и будем
обрабатывать. Такой подход лучше, чем загружать всю структуру каталогов сразу.
Это связано с тем, что во время работы программы пользователь может изменить
структуру каталогов, и чтобы программа адекватно реагировала на подобные
изменения, нужно производить поиск каталогов следующего уровня при каждом
раскрытии узла.
procedure NextLevel(ParentNode: TTreeNode);
var
sr, srChild: TSearchRec;
node: TTreeNode;
path: string;
begin
node := ParentNode;
path := '';
repeat
path := node.Text + '\' + path;
node := node.Parent;
until node = nil;
// Находим первую директорию
if FindFirst( path + '*.*', faDirectory, sr ) = 0 then
begin
repeat
if ( sr.Name <> '.' ) and ( sr.Name <> '..' ) then
if ( sr.Attr and faDirectory ) = faDirectory then
begin
// Добавляем найденную папку в TreeView
node := Form1.TreeView1.Items.AddChild( ParentNode, sr.Name );
node.ImageIndex := 0;
node.SelectedIndex := 1;
// Утверждаем, что нет подкаталогов
node.HasChildren := false;
// Проверяем, так ли это
if FindFirst( path + sr.Name + '\*.*', faDirectory, srChild ) = 0 then
begin
repeat
if ( srChild.Name <> '.' ) and ( srChild.Name <> '..' ) then
if ( srChild.Attr and faDirectory ) = faDirectory then
node.HasChildren := true;
until ( FindNext( srChild ) <> 0 ) or node.HasChildren;
end;
FindClose( srChild );
end;
until FindNext( sr ) <> 0;
end
else
ParentNode.HasChildren := false;
FindClose( sr );
end;
procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean);
begin
TreeView1.Items.BeginUpdate;
node.DeleteChildren;
NextLevel( node );
TreeView1.Items.EndUpdate;
end;
|
Теперь, если мы захотим просмотреть все получившееся дерево, то
воспользуемся следующим кодом, который полностью раскрывает дерево.
procedure TForm1.Button1Click(Sender: TObject);
begin
with TreeView1 do
begin
Items.BeginUpdate;
FullExpand;
Items.EndUpdate;
end;
end;
|
Закрыть его вновь тоже не составит проблемы.
procedure TForm1.Button2Click(Sender: TObject);
begin
with TreeView1 do
begin
Items.BeginUpdate;
FullCollapse;
Items.EndUpdate;
end;
end;
|
Подведем итог. Задача построения структуры каталогов в виде дерева с
использованием TreeView оказалась не сложной. Разберитесь получше с
этим примером, и многие вопросы, связанные с использованием TreeView
исчезнут. Удачи.
.: Пример к данной статье :.
|
При использовании материала - ссылка на сайт обязательна
|
|