PDF File Parser Instance Browser for .NET Assemblies
Apr 20

Printer Friendly Version

Download Source Code: RegistryBrowser.zip - 25.33KB

Implementation of the Registry Browser

Let's start with the step-by-step implementation of the UI framework, presented in such detail just because there are so many types of browsers that use this kind of interface, with a hierarchy of nodes and list of related objects or property values, when one specific node is selected. Looking at RegEdit or RegEdt32, it's clear that we have to populate the tree with RegKey objects, and the list with related RegValue instances, for the selected node.

Registry Browser
Registry Browser

There are usually two main approaches to associate a TreeNode or ListViewItem with a business object:

  1. We either create specialization of nodes and items, derived from the classes mentioned before, and encapsulate as field the business object.
  2. Or we simply set the Tag property of the node or item to our instance. We'll take here this second approach.

Create a new RegistryBrowser Windows Application project. Save it under a RegistryBrowser folder, with a separate folder for the project files. This will allow you to later create extensibility projects within the same solutions, and keep all of them under the same RegistryBrowser top folder.

Rename your form class as MainForm. From the Toolbox, drag and drop on form's area a mnuMain MenuStrip, tbrMain ToolStrip and sbrMain StatusStrip. Create a mnuFile "&File" menu ToolStripMenuItem, with a "E&xit" subitem which, on Click, will simply Close the form and exit the application.

Drag and drop a splMain SplitContainer, a tvwMain TreeView into the left panel and a lvwMain ListView into the right panel. Set Dock property value to Fill for both the tree and list view controls. Set list view's View property value to Details and add three columns: Name, Type and Data.

Drag and drop a imgMain ImageList and assign it as ImageList to the tree view and SmallImageList to the list view. Populate the image list with the five .ico files from our project. These are 16x16 256 colors icons with following file and default key names: computer.ico, folder.ico, folder_close.ico, value.ico, value-bytes.ico.

We'll populate the child nodes dynamically, on expand, and delete them on collapse. This allows us to refresh data for a node with current registry values on each Expand-Collapse events. When collapsing a node, do not simply delete its child nodes, but also dispose all RegKey instances linked through their Tag property. We'll do this with a ClearNode method, called recursively. We'll also make sure, before we leave the application, that the top node is collapsed, to call ClearNode and dispose all objects.

To determine a node has to be populated with child nodes, we add a dummy invisible node "." under each node that has not been expanded yet. With these rules, our BeforeExpand and AfterCollapse event handler methods become:

private void tvwMain_BeforeExpand(
    object sender, TreeViewCancelEventArgs e)
{
    e.Node.Nodes.Clear();
    
    // populate child nodes with all subkeys of current registry key
    Cursor.Current = Cursors.WaitCursor;
    tvwMain.BeginUpdate();
    try
    {
        RegKey key = e.Node.Tag as RegKey;
        foreach (RegKey subkey in key.Keys)
        {
            // create new tree node for this registry subkey
            TreeNode node = e.Node.Nodes.Add(subkey.Name);
            node.Tag = subkey;
            node.ImageKey = "folder.ico";
            node.SelectedImageKey = "folder_open.ico";
            if (subkey.RegistryKey!=null
                && subkey.RegistryKey.SubKeyCount > 0)
                node.Nodes.Add(".");
        }
    }
    finally
    {
        tvwMain.EndUpdate();
        Cursor.Current = Cursors.Default;
    }
}

private void tvwMain_AfterCollapse(
    object sender, TreeViewEventArgs e)
{
    // remove all child nodes and close associated registry keys
    ClearNode(e.Node);
    e.Node.Nodes.Add(".");
}

// Recursively remove all child nodes and dispose
// all objects associated to node tags
private void ClearNode(TreeNode parent)
{
    foreach (TreeNode node in parent.Nodes)
    {
        ClearNode(node);
        if (node.Tag is RegKey)
            (node.Tag as RegKey).Dispose();
    }
    parent.Nodes.Clear();
}

private void MainForm_FormClosing(
    object sender, FormClosingEventArgs e)
{
    // make sure before leaving that ClearNode
    // is called for the top node
    // and all associated node objects are disposed
    tvwMain.Nodes[0].Collapse();
}

When a tree node is selected, we need to populate the list view with all registry values of the RegKey object associated with the node. The AfterSelect event handler method of the tree control is:

private void tvwMain_AfterSelect(object sender, TreeViewEventArgs e)
{
    lblStatus.Text = "";
    lvwMain.Items.Clear();
    
    if (e.Node != null)
    {
        // Show the key path in status bar
        RegKey key = e.Node.Tag as RegKey;
        lblStatus.Text = key.FullName;

        // populate list view with all registry key values
        Cursor.Current = Cursors.WaitCursor;
        lvwMain.BeginUpdate();
        try
        {
            RegValue[] values = key.Values;
            if (values!=null)
                foreach (RegValue value in values)
                {
                    // create a list item for this registry value
                    ListViewItem item
                        = lvwMain.Items.Add(value.Name);
                    item.ImageKey
                        = (value.Kind == RegistryValueKind.DWord
                        || value.Kind == RegistryValueKind.Binary
                        ? "value_bytes.ico" : "value.ico");
                    item.SubItems.Add(Enum.GetName(
                    typeof(RegistryValueKind), value.Kind));
                    item.SubItems.Add(value.ToString());
                }
        }
        finally
        {
            lvwMain.EndUpdate();
            Cursor.Current = Cursors.Default;
        }
    }
}

The only thing left to do is to create a top node and associate it with a registry RegKey instance, when the form is loaded:

private void MainForm_Load(object sender, EventArgs e)
{
    // create a top entry node to local registry
    RegKey key = new RegKey();
    TreeNode node = tvwMain.Nodes.Add(key.Name);
    node.Tag = key;
    node.ImageKey = node.SelectedImageKey = "computer.ico";
    node.Nodes.Add(".");
    node.Expand();
}

Subscribe and Share: Subscribe using any feed reader Bookmark and Share

Leave a Reply