Построение дерева реестра

  • Автор темы NetDigger
  • Дата начала
Статус
Закрыто для дальнейших ответов.
N

NetDigger

#1
Здравствуйте, уважаемые! Вот встала задача создать аналог РегЕдита для Вин. Все работает, просто замечательно, но долго =) Приведу примеры рекурсивной процедурыпостроения дерева реестра, а Вы, если вдруг кто знает посоветуйте - как оптимизировать данное или вообще может не стоит делать таким способом

Const
THKEYs : Array[1..6] of HKEY = ( HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE,
HKEY_USERS, HKEY_CURRENT_CONFIG, HKEY_DYN_DATA );
THKEYStrings: Array[1..6] of String = ( 'HKEY_CLASSES_ROOT', 'HKEY_CURRENT_USER', 'HKEY_LOCAL_MACHINE',
'HKEY_USERS', 'HKEY_CURRENT_CONFIG', 'HKEY_DYN_DATA' );


procedure ShowRegister( Key: HKEY; Node: TTreeNode; NextToAdd: String; NKey: Integer);

Var
Index : LongInt;
Buffer: Array[0..100] of Char;
Node1 : TTreeNode;
Key1: HKEY;
Ind1: Integer;
NextToAdd1: String; // следующий ключ для открытия (для поиска всех его подразделов

Begin
Index := 0;
While RegEnumKey(key, Index, Buffer,sizeof(Buffer)) = 0 do Begin
NextToAdd1 := NextToAdd + StrPas(Buffer) + '\';
Node1 := Form1.TreeView1.Items.AddChild( Node, Buffer );
If not( NKey < 4 ) then begin // поставил специально - иначе комп думает ну ооочень долго
// потому как HKLM, HKCR очень объемны

RegOpenKeyEx( THKEYs[NKey], PChar(NextToAdd1), 0, KEY_ALL_ACCESS, key1 );
ShowRegister( key1, Node1, NextToAdd1, NKey );
End;
inc (index );
End;
End;

procedure TForm1.FormShow(Sender: TObject);
Var
I : Integer;
Node: TTreeNode;
begin
For i := 1 to 6 do begin
Node := Form1.TreeView1.Items.Add(nil, THKEYStrings );
ShowRegister( THKEYs, Node, '',i );

End;


Вроде все правильно перенес.
Кроме того возникает еще один вопрос - как вывывести значения ключей (параметр - значение) -как в регедите при щелчке на узле? Проблема возникает с типами и как их выводить - пример далее: (полностью процедуру выводить не буду - только ключевой момент, который в принципе не работает =)

procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);

Var
BufData: DWORD;
Key, Key1: HKey;
Index: Integer;
Buffer: Array[0..100] of Char;
ValueType: DWORD;
BufSize, BufDataSize: DWORD;
ListItem: TListItem;
Begin
// открываем все ключи, находим хэндлэ и т.п. - все работает правильно, нужно лишь понять
как это дело правильно выводить
RegOpenKeyEx( key, PChar(PathToKey), 0, KEY_ALL_ACCESS, key1 );
While RegEnumValue( Key1, Index, Buffer,
BufSize, nil, @ValueType, @BufData{nil}, @BufDataSize ) = ERROR_SUCCESS do Begin
// ShowMessage( StrPas(Buffer)+ IntToStr(BufData) );

ListItem := ListView1.Items.Add;
ListItem.Caption := StrPas(Buffer);
BufSize := sizeof(BufSize);
inc(Index)
End;

Хммм, странные проблемы возникли со вставкой кода - все черное получается

Большое спасибо за внимание, уважаемые
 
B

Barmutik

#2
Всё нормально ... НО .. одно БОЛЬШОЕ НО!!!

Реестр обладает огромным количеством записей а Вы используете стандартный компонент TTreeView.. Для небольших объёмов, если Вы к примеру строили бы какую-то одну сабветку, всё работало бы замечательно.. но для полного реестра такой вариант абсолютно не приемлим.

Задчи такого плана решаются с помощью так называемых виртуальных контролов. В качестве такого контрола по-умолчанию входящего в поставку с Delphi можно привести TListView в режиме OwnerData = True. Для более полного понимания механизама рекомендую посмотреть пример находящийся в папке с экзамплами Delphi, называется что-то там VirtualListView...

Если количество элементов в дереве превышает 1000... то уже имеет смысл использовать виртульный подход.. не говоря уже о миллионах записей..

К примеру попробуйте вставить 1.000.000 записей в Ваше дерево, это займёт достаточно продолжительное время, для вставки такого же количества элементов в виртуальный контрол потребуется менее 0.1 секунды...

Если что-то не понятно.. уточняйте...
 
N

NetDigger

#3
Здравствуйте, уважаемый Barmutik!
Спасибо за ответ. Как вы и предполагали вопросы возникли. Использование VirtualListView действительно очень удобно и быстро - я взял данный пример на заметку как основная альтернатива. Но вопрос в другом - нужно построить именно древовидную структуру. Возможно ли это сделать?
Спасибо
 
B

Barmutik

#4
Вопроса ожидал :)

Есть ОЧЕНЬ (реально очень) замечательный контрол TVirtualTreeView выполняющий нужную вам + огромное количество других функций... Он обладает многими достоинствами.. но для меня главные:

1. Практически 100% безглючность
2. Потрясающая скорость работы
3. Огромное количество возможностей
4. Бесплатность (использовать в своих шареварных программах)
5. Поддержка автором и комьюнити людей им пользующимся.

Посмотреть, почитать и скачать по адресу: www.lischke-online.de

Я его использовал и использую уже наверно в десятке проектов .. и никаких нареканий...

Что бы не создалось ложного мнения.. я к этому контролу не имею никакого отношения :) Просто он меня впечатлил качеством своей идеи и мощностью реализации...

Сходу он трудноват для понимания но в комплект входят примеры + на сайт есть хелп файл.. правда всё конечно на английском :)

Если возникнут вопросы то пишите попытаюсь ответить...
 
N

NetDigger

#5
Уважаемый Barmutik!

Моя благодарность не знает границ! Большое спасибо!

С уважением, я!
 
B

Barmutik

#6
Ну спасибо :)

Сначала следует попробовать с ним разобраться :) И я думаю последуют новые вопросы :) Ждёмс ...
 
N

NetDigger

#7
Здравствуйте, уважаемые!
Хехе, на самом-то деле ларчик просто открывался - сам алгоритм рекурсивного поиска по реестру очень долог - я посадил его в консольку и просто запустил на пробег по реестру и по окончании его выдавал сообщение. Все это дело на моей П2-266 старушке заняло 12 мин, с построением дерева - 14 мин =) И тут как Менделеева во сне (правда-правда) осенило - зачем строить сразу весь реестр - буду показывать те ветки, которые развертываются (OnExpanding у TreeView) - все просто летает. Склепал полный аналог RegEdit, разве что пока не подключил переименование разделов - а все остальное -поиск, добавление разделов и параметров-значений - замечательно работает. Если кому понадобиться, то могу выложить исходник, чуть погодя

С уважением
 
B

Barmutik

#8
В принципе вариант очень грамотный ... гораздо быстрее чем весь строить :)
 
Статус
Закрыто для дальнейших ответов.