building a treeview

Heres an EZ 1: all I want to do is take a registry key and
all its subkeys and represent them in a Ttreeview.
I just need a snippit or a relative example of recursion
I could incorporate.
Please dont just point me to some crummy component.
timbroAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
freterConnect With a Mentor Commented:
Ok, here we go:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, registry, StdCtrls;

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure EnumKeys(aNode: TTreeNode; aKey:HKEY; aPath: string);
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}


procedure EnumSubKeys(aKey: HKEY; const Path:String; var aValue: TStringList);
var
  aRegistry: TRegistry;
begin
  aRegistry:=TRegistry.Create;
  try
    with aRegistry do
    begin
      RootKey:=aKey;
      OpenKey(Path,True);
      GetKeyNames(aValue);
    end;
  finally
    aRegistry.Free;
  end;
end;

procedure TForm1.EnumKeys(aNode: TTreeNode; aKey:HKEY; aPath: string);
var aReg: TRegistry;
    aSubKeys: TStringList;
    i: integer;
    newNode: TTreeNode;
begin

  aSubKeys := TStringList.Create;
  EnumSubKeys(aKey, aPath,aSubKeys);

  if aSubKeys.Count > 0 then begin
    for i := 0 to aSubKeys.Count - 1 do begin
      newNode := TreeView1.Items.AddChildObject(aNode, aSubKeys[i], Pointer(aPath + '\' + aSubKeys[i]));
      EnumKeys(newNode, aKey, String(newNode.Data));
    end;
    aSubKeys.Free;

  end;

end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  EnumKeys(nil, HKEY_CURRENT_USER, 'Software');
end;

end.

You will need a TreeView named TreeView1 and a button named Button1. Don't forget to assign the correct events!

Have fun,
Freter

0
 
freterCommented:
Hi!
The following code fills a node with it's subkeys. It is NOT recommendable to browse the entire registry tree at once (you know how large the REG is!!!). So, one should call this piece of code every time the user expands a node, for example in the OnExpand event.

procedure TForm1.FillSubTree(aPath: string; aNode: TTreeNode);
var aReg: TRegistry;
    aSubKeys: TStringList;
    i: integer;
begin

  aReg := TRegistry.Create;
  try
    with aReg do begin
      RootKey := HKEY_LOCAL_MACHINE;
      OpenKey(aPath);
      aSubKeys := TStringList.Create;
      GetValueName(aSubKeys);
    end;
  finally
    aReg.Free;
  end;

  if aSubKeys.Count > 0 then begin
    for i := 0 to aSubKeys.Count - 1 do
      TreeView1.Items.AddChildObject(aNode, aSubKeys[i], nil)
  end;
  aSubKeys.Free;

end;

0
 
timbroAuthor Commented:
Thanks, freter for your response!
I guess this would be fine for displaying a key and its
value names but I would like to display a key with its
subkeys and their subkeys etc... initially fully expanded
hence the need for a looping recursion type procedure.
I suppose one could use the GetKeyNames in the same example
but I absolutely need the recursion. The reg keys I'm
working with only go a few levels deep so theres no fear of
a long consuming process. Even though, one should be able to
treeview an entire root key if wanted. regedit does it...
I really need a recursion example.
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
MatveyCommented:
For another question I wrote a recursive procedure that fills a treeview with directory structure and files. You can replace it with registry - very easy. (it lists PCX files in the given directory)



    procedure TForm1.ListPCX(path: AnsiString; Node: TTreeNode);
    var
      srRes : TSearchRec;
      iFound : Integer;
    begin
      if path[Length(path)] <> '\' then path := path +'\';

        iFound := FindFirst( path + '*.*', faAnyfile, srRes );
        while iFound = 0 do
        begin
          if ( srRes.Name <> '.' ) and ( srRes.Name <> '..' ) then
            if srRes.Attr and faDirectory > 0 then
              ListPCX(path+srRes.Name, TreeViewGroupsAndFiles.Items.AddChild(Node, {path+}srRes.Name));
          iFound := FindNext(srRes);
        end;
        FindClose(srRes);

      iFound := FindFirst(path+'*.bmp', faAnyFile-faDirectory, srRes);
      while iFound = 0 do
      begin
        if ( srRes.Name <> '.' ) and ( srRes.Name <> '..' ) and ( srRes.Name <> '' ) then
          TreeViewGroupsAndFiles.Items.AddChild(Node,srRes.Name);
        iFound := FindNext(srRes);
      end;
      FindClose( srRes );
    end;
0
 
timbroAuthor Commented:
Thanx, Matvey, that gets me a little closer! I can see how the recursion works only I cant use any FindNext functions with the
registry. and you cant use any GetKeyNames.count because the
count var gets mixed up in the recurse. What was that about being
'very easy'? I'm sorry for being dense but I need a version of
your code aimed at the registry. I didnt think it would be this
tough! In-between sessions of self-induced hair extraction I have
to stop and think - with something this common there should be
something in a textbook somewhere! But alas, another Delphi mystery. What the hey, heres another 50 points...


0
 
MatveyCommented:
Took the words out of my mouth:)
Don't mean anything, nevermind...
0
 
timbroAuthor Commented:
Thanx freter!
Precisely, exactly what I needed. I can regrow my hair now!
Your code is an absolutely textbook-quality example!
I really appreciate your time and efforts!

Actually your first response did answer my question (as it
was worded) and I could have used it as-is, only I knew
I could do it all at once thru recursion. And it was driving me
batty that I couldnt apply to the registry!

I've seen recursive procedures and functions used before with
file stuff like in the example by Matvey (thank-you!) but am
not real familiar with them. [anybody know what having to
declare a recursive procedure 'forward' is all about?]

I really appreciate your help guys!
Good luck and thanks again all!
-Tim
0
 
freterCommented:
To understand recursion, we must first understand recursion.
;-)
Freter
0
 
timbroAuthor Commented:
Could you repeat that? 8^D
0
 
amber45Commented:
You can say that again!!! hehe
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.