http://sulfurzona.com/
News
Service
Magazine
Dune Game (Dune III, Dune IV, Cheats, Forum, ..)
Games free
Turbo Pascal (Assembler, Docs, Sources, Debbugers, ..)
Books (Docs for developers)
Компьютерная диагностика двигателя автомобиля (адаптер К-линии)Компьютерная диагностика двигателя автомобиля (адаптер К-линии)
 
 
 
 
 

Советы по работе с компонентом TTreeView в среде разработки Delphi

 
Что и говорить, одним из ярчайших и весьма полезных из плеяды компонентов Delphi является визуальный компонент TTreeView. Он позволяет осуществить построение иерархического дерева из списка и сделать это весьма просто и быстро.
 
Но не каждый начинающий программист догадается, как правильно с ним работать, чтобы скорость выполнения операций была максимально быстрой.
 
Например, в своем 3D-аниматоре для построения иерархической структуры виртуальной сцены я использую компонент TTreeView. И довольно часто сталкиваюсь с ситуациями, когда 3D-сцена содержит тысячи деталей, составляющих список дерева в TreeView. Особенно чувствуется замедление работы программы при загрузке модели из формата OBJ, когда в ней содержатся тысячи деталей.
 
Советы по работе с компонентом TTreeView в среде разработки Delphi
 

Быстрое создание узлов TTreeNode в TTreeView

 
Изучив документацию по компоненту TTreeView, многие программисты составляют примерно следующий код, который успешно добавляет узел.
 
var Node, NewNode : TTreeNode;
begin
Tree.Items.AddChildObject( Node, Model.Name, Model );
NewNode := Tree.Items[Count-1];
NewNode.ImageIndex := …;
NewNode.SelectedIndex := …;
 
Такой код кажется логичным, если опираться лишь на документацию. Но если подобный код использовать в цикле с тысячами итераций, то станет ощутимо заметно замедление работы программы. И для ускорения не поможет даже заключение этого кода в блок Tree.Items.BeginUpdate ... Tree.Items.EndUpdate.
 
Гораздо большей (и, по сути, оптимальной) скорости работы программы можно добиться, немного изменив код:
 
var Node, NewNode : TTreeNode;
begin
NewNode := Tree.Items.AddChildObject( Node, Model.Name, Model );
NewNode.ImageIndex := …;
NewNode.SelectedIndex := …;
 
Поскольку метод Tree.Items.AddChildObject в качестве результата возвращает созданный узел, то получать его через жутко медленно работающую комбинацию Tree.Items[Count-1] (для получения последнего узла) нет необходимости.
 

Быстрый поиск узла TTreeNode

 
Предположим, что у нас возникла необходимость перебрать весь список узлов, чтобы найти некий узел по конкретному критерию. Допустим, будем искать по его тексту. Тогда совершенно логично и в соответствии с документацией напрашивается следующий код для решения нашей задачи:
 
var j : integer;
      Node : TTreeNode;
begin
Result:=nil;
j:=0;
while j do begin
         Node := Tree.Items[j];
         if Node.Text = … then begin
            Result := Node;
            Exit;
            end;
        inc(j);
        end; // while
 
 
 
 
 
Такой код будет работать успешно, но в случае с наличием в дереве огромного количества узлов поиск затянется многократно.
 
Разгадка кроется в исходном коде компонента, который не мешало бы просмотреть, примерно, по такому пути: c:/Program Files/Borland/Delphi/SOURCE/VCL/comctrls.pas
 
Дело в том, что комбинация Tree.Items[j] всякий раз осуществляет прогон списка узлов с самого начала. В итоге, с каждой итерацией нашего цикла очередная итерация выполняется всё дольше и дольше, то есть тем дольше, чем ближе индекс узла к концу списка.
 
Внимательное изучение исходного кода компонента учит нас делать правильно. А именно – мы самостоятельно можем и должны обратиться к первому узлу, а далее просто перебирать следующие, не забегая в начало.
 
Так, в случае с 10 000 узлами в дереве поиск при помощи предыдущего кода затянулся бы на несколько минут. А вот следующий код сделает всё мгновенно:
 
var j : integer;
      Node : TTreeNode;
begin
Result:=nil;
j:=0;
Node := Tree.Items.GetFirstNode;
while (Node <> nil) do begin
         if Node.Text = … then begin
            Result := Node;
            Exit;
            end;
         Node := Node.GetNext;
         end; // while
 

Отключаем подсказки в TTreeView

 
По умолчанию, в компоненте активна такая опция, при которой при наведении курсора мышки на узел выскакивает подсказка (Hint) и остается видна довольно долго.
 
Отключаем подсказки в TTreeView
 
При работе с деревом это может ужасно мешать и раздражать. Советов по отключению подсказки в TTreeView в Интернете хватает, но самый действенный и универсальный для всех версий Delphi, на мой взгляд, следующий. Особенно, если возникает необходимость создать свой потомок класса TTreeView:
 
Всего лишь надо перекрыть обработчик для уведомительного сообщения при описании нашего нового класса компонента:
 
type
        TMyTreeView = class (TCustomTreeView)
        private
        { Private declarations }
         procedure WMNotify(var Message: TWMNotify); message WM_NOTIFY;
        protected
        …
 
implementation
 
procedure TMyTreeView.WMNotify( var Message: TWMNotify );
begin
// следующую строку не выполняем, чтобы выключить автоподсказку при наведении курсора на ветку дерева
//inherited;
end;
 
Вот, собственно, и всё.
Желаю успешного программирования!
 
 
 
© Владислав Демьянишин
 
 
Вы находитесь на официальном сайте Владислава Демьянишина - разработчика игры Dune IV (Dune 4). На нашем сайте Вы можете бесплатно скачать игры Dune IV (Dune 4), Battle City (Танчики с Dendy/Nintendo), читы к играм и многое другое. Также Вы можете скачать бесплатно программы и полезные утилиты. Все программы чистые, т.е. не содержат вирусов и иного вредоносного ПО. Предлагаю также посетить Марья искусница - сайт о рукоделии (http://mariya-iskusnica.ru).
 
 
 

Журнал > Программирование > Советы по работе с компонентом TTreeView в среде разработки Delphi
 
 
 
2250
 
ВКонтакте
Facebook
 
 
 
На главную страницу На предыдущую страницу На начало страницы
 
 
Рейтинг@Mail.ru Рейтинг Сайтов YandeG