Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


Листинг 5.1. Приложение Mini-Registry-browser, главный модуль




unit main;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, Grids, Outline, ComCtrls, ImgList, ExtCtrls;

type

TForml = class(TForm)

TreeViewl: TTreeView;

ListViewl: TListView;

ImageListl: TImageList;

Splitterl: TSplitter;

procedure FormCreate(Sender: TObject);

procedure TreeViewlChange(Sender: TObject; Node: TTreeNode);

procedure FormDestroy(Sender: TObject);

procedure TreeViewlExpanded(Sender: TObject; Node: TTreeNode);

procedure TreeViewlGetlmagelndex(Sender: TObject; Node: TTreeNode);

private

{ Private declarations }

public

{ Public declarations }

procedure ShowSubKeys(ParentNode: TTreeNode;depth: Integer);

function GetFullNodeName(Node: TTreeNode):string;

end;

var

Forml: TForml;

implementation

uses registry;

{$R *.DFM}

var reg : TRegistry;

procedure TForml.FormCreate(Sender: TObject);

var root : TTreeNode;

begin

Reg := TRegistry.Create;

ListViewl.ViewStyle := vsReport;

with ListViewl do

begin

with Columns.Add do

begin

Width := ListViewl.Width div 3-2;

Caption := 'Name';

end;

with Columns.Add do

begin

Width := ListViewl.Width div 3*2-2;

Caption := 'Value';

end;

end;

TreeViewl.Items.Clear;

Reg.RootKey := HKEY_LOCAL_MACHINE;

Root := TreeViewl.Items.Add(nil,'HKEY_LOCAL_MACHINE');

TreeViewl.Items.AddChildtroot,'');

end;

procedure TForml.FormDestroy(Sender: TObject);

begin

Reg.Free;

end;

function TForml.GetFullNodeName(Node: TTreeNode):string;

var CurNode : TTreeNode;

begin

Result:=''; CurNode := Node;

while CurNode.Parentonil do

begin

Result:= '\'+CurNode.Text + Result;

CurNode := CurNode.Parent;

end;

end;

procedure TForml.TreeViewlChange(Sender: TObject; Node: TTreeNode);

var s: string;

Keylnfo : TRegKeylnfo;

ValueNames : TStringList;

i : Integer;

DataType : TRegDataType;

begin

ListViewl.Items.Clear;

s:= GetFullNodeName(Node);

if not Reg.OpenKeyReadOnly(s) then Exit;

Reg.GetKeylnfo(Keylnfo);

if Keylnfo.NumValues<=0 then Exit;

ValueNames := TStringList.Create;

Reg.GetValueNames(ValueNames);

for i := 0 to ValueNames.Count-1 do

with ListViewl.Items.Add do

begin

Caption := ValueNames[i];

DataType := Reg.GetDataType(ValueNames[i]);

Case DataType of

rdString: s := Reg.ReadString(ValueNames[i]);

rdlnteger: s:= '0x'+IntToHex(Reg.Readlnteger(ValueNames[i]),8);

rdBinary: s:='Binary';

else s:= '???';

end;

Subltems.Add(s);

Imagelndex :=1;

end;

ValueNames.Free;

end;

procedure TForml.ShowSubKeys(ParentNode: TTreeNode;depth: Integer);

var ParentKey: string;

KeyNames : TStringList;

KeyInfo : TRegKeylnfo;

CurNode : TTreeNode; i : Integer;

begin

Cursor := crHourglass;

TreeViewl.Items.BeginUpdate;

ParentKey := GetFullNodeName(ParentNode);

if ParentKeyO1' then

Reg.OpenKeyReadOnly(ParentKey)

else

Reg.OpenKeyReadOnly('\') ;

Reg.GetKeylnfo(Keylnfo) ;

if KeyInfo.NumSubKeys<=0 then Exit;

KeyNames := TStringList.Create;

Reg.GetKeyNames(KeyNames);

While ParentNode.GetFirstChildonil do ParentNode.GetFirstChild.Delete;

if (KeyNames.Count>0) then for i:=0 to KeyNames.Count-1 do

begin

Reg.OpenKeyReadOnly(ParentKey+'\'-t-KeyNames[ i ]) ;

Reg.GetKeylnfo(Keylnfo);

CurNode := TreeViewl.Items.AddChild(ParentNode,KeyNames[i];

if KeyInfo.NumSubKeys>0 then

begin

TreeViewl.Items.AddChild(CurNode, '');

end;

end;

KeyNames.Free;

TreeViewl.Items.EndUpdate;

Cursor := crDefault;

end;

procedure TForml.TreeViewlExpanded(Sender: TObject; Node: TTreeNode);

begin

ShowSubKeys(Node,1);

end;

procedure TForml.TreeViewlGetlmagelndex(Sender: TObject; Node: TTreeNode);

begin

with Node do

begin

if Expanded then Imagelndex := 2

else Imagelndex := 3;

end;

end;

end.

Для работы с системным реестром используется объект VCL TRegistry, удачно инкапсулирующий все предназначенные для этого функции Windows API. В обработчике события OnCreate главной формы создается объект Reg, а также к списку Listview1 добавляются два заголовка (свойство Columns).

Пояснений требует принцип построения дерева ключей. Во-первых, это приложение отображает только один из системных ключей (а именно HKEY_LOCAL_MACHINE); при желании его можно заменить или добавить остальные. Во-вторых, попытка построить все "развесистое" дерево ключей сразу займет слишком много времени и наверняка не понравится пользователям. Вспомним, ведь утилита Registry Editor работает довольно быстро. Значит, придется строить дерево динамически — создавать и показывать дочерние узлы в момент развертывания родительского узла. Для этого используется событиеOnExpand компонента TreeView1.

Остановимся на секунду. А какие узлы помечать кнопкой разворачивания (с пометкой "+"), ведь у родительского узла еще нет потомков? Выход из положения такой — в момент построения ключа проверить, есть ли у него дочерние. Если да, то к нему добавляется один (фиктивный) пустой ключ. Его единственная роль — дать системе поставить "+" против родительского узла.

Когда же пользователь щелкнул на кнопке, отмеченной знаком "+", и родительский узел разворачивается, фиктивный дочерний узел удаляется и вместо него создаются узлы настоящие, полученные путем сканирования реестра (см. метод ShowSubKeys).

Снабдим узлы картинками. Для этого в компонент imageList1 поместим картинки, соответствующие открытой и закрытой папкам. Напомним, что для отрисовки и смены картинок есть специальные события — OnGetlmageIndex И OnGetSelectedIndex. В данном примере у двух ЭТИХ событий один обработчик: развернутому узлу он сопоставляет картинку раскрытой папки, а свернутому — закрытой.

В заключение нужно сказать об очень важной особенности компонента TListview. Когда он отображает большой объем информации, обработка данных может затянуться очень и очень надолго и занять слишком много памяти. Выход — перевести список в так называемый виртуальный режим. Он применяется для тех случаев, когда элементов в списке слишком много и хранить их там невозможно из соображений экономии времени или памяти. Выход из положения прост:

1. Переводим компонент в виртуальный режим установкой свойства OwnerData в значение True.

2. Сообщаем списку сколько в нем должно быть элементов установкой нужного значения items.Count.

3. Чтобы предоставить нужные данные, программист должен предусмотреть обработку событий OnData, OnDataFind, OnDataHint и OnDataStateChange. Как минимум нужно описать обработчик события OnData.

TLVOwnerDataEvent = procedure(Sender: TCbject; Item: TListltem) of object;

Вам передается объект TListitem, и внутри обработчика события OnData необходимо динамически "оформить" его — полностью, от заголовка до картинок.

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

Borland прилагает к Delphi 7 прекрасный пример к вышесказанному — Virtual Listview. К нему и отсылаем заинтересованного читателя.


Поделиться:

Дата добавления: 2014-12-03; просмотров: 127; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.006 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты