INDEX


Recursively scanning a disk and
saving the results on a Delphi Treeview


     The demo code which accompanies this article shows how to add items onto a Delphi TreeView, how to associate nodes on the Treeview with icons (or you could use bitmap images etc), and how to trace a path from a selected node to the root. The icon code adds to the complexity of the unit, and has already been discussed on previous pages on this site (follow the link to the Index below).The recursive disk function was also previously used to insert values onto a binary tree, and is recycled here and this time is being used to insert values onto a visual Treeview structure. If you are simply interested in learning to use a TreeView structure you can ignore the graphics code in which case the important procedures and functions are Button1Click, which initializes the root of the TreeView, and then calls FileLook (which scans the disk and subdirectories for folders and files) and the function TracePath, which iteratively moves backwards down the tree and reconstructs a path to the root, in this case returning a string which is a full path to the selected directory or file.

     The basics of using a TreeView can be briefly described by the following code fragments...

Initialize the RootNode of the TreeView :
TreeView1.Items.Clear; {clear the Treeview if required}
The syntax for creating the root node of the Tree is:
RootNode := TreeView1.Items.Add(nil, TheTextCaption); {top parent of treeview}

      TreeViews get their graphics from an ImageList which is associated with the TreeView using its image property on the VCL property editor. In this example code the program begins by launching the standard Windows Browse for Folder function to find a starting directory for the disk scan so the root is assumed to be a folder. TreeView images can have two views, one when not selected and one when selected. Constants are defined in the code which represent the position of the images within the ImageList. At program start, in the FormCreate event handler the ImageList is loaded with 15 standard icons from Shell32.dll (the code is recycled and only the two folders are actually used in this project.) You will notice a constant string declared with a bunch of numbers encoded. These two digit numbers are extracted from the string and converted to integers and represent the icon position within the Shell32.dll for the icons to be extracted and then added onto the ImageList. To assign a picture from the image list to a TreeView node, you put the integer value of the position of the image on the imagelist into the two image index properties of that node. In this example constant values represented by strings are used.

RootNode.ImageIndex := ISAClosedFolder; {how the image looks to start}
RootNode.SelectedIndex := ISAOpenFolder; {image when item selected}

     Any node can then have a child node added onto it using the code:

TempNode := TreeView1.Items.AddChild(Node, CaptionText);

     In this example 'TempNode' holds the pointer to the newly created child node of 'Node' and it will have the Caption contained in the string 'CaptionText'. One could then assign TempNode a graphic from the ImageList using the syntax above. Basically the syntax for the root node above and the syntax for creating a child node just illustrated is all you need to know to create a TreeView structure.

     Trees are by their nature 'recursive structures'. When a function uses recursion, it means that the function calls itself, rather than calling another function. If you need to read some source code discussing the recursive disk function that loads the Treeview in this example, follow the link to the text file disk_search_recursive.txt. This code, along with the Icon code in this example is simply recycled for this project.

     As an example of a recursive function consider the following simple example.

procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
begin
   i :=1;
   i := AddUpI(i);
   ShowMessage('The end result : ' + IntToStr(i));
end;

function TForm1.AddUpI(i : integer):integer;
begin
   Result := 0;    ShowMessage('Entering function - i = ' + IntToStr(i));
   i := i + 1;
   If i < 6 then
   Result := AddUpI(i);
   ShowMessage('Leaving function - Result = ' + IntToStr(Result));
end;

     If you are going to experiment with recursion in code, you should save all your work before you test the code, as a fail safe against locking up and crashing your computer. With that being said, the recursive function call where AddUpI calls itself is embedded in the second last line of code. I enters the function set to 1 and Result is first initialized to zero (otherwise anything could be in it). I is incremented. The all important stop condition (if i is less than 6) prevents infinite recursion and a system lock up. As long as i is less than 6 the function calls itself again, passing the value of i. The end result is 15 which is 1 + 2 + 3 + 4 + 5. When i becomes 6 is doesn't get added onto the running total because the recursive function call fails the comparison test in the if statement at this point. When i reaches six rather than calling the function recursively one more time, the code drops to the next line, and outputs a message showing the Result, which the first time this code gets reached (when i reaches 6) is Result = 5. If you watch the message boxes you will see that first i climbs up to 6, and then sequentially all the recursive function calls return and the result begins to climb up to 15, the final total.

     Recursion works well for crawling through a disk for all files. What happens is that when a file is encountered the routine continues iterating through a loop, but when a folder is encountered it calls itself recursively passing the folder name. Each instance of a recursive procedural or function call is unique. If i = 5 in one instance of the function, that is the value that it has only for that called instance of the function. Meanwhile the function where i = 4 still exists and is only on hold until the i = 5 function returns. When procedures or functions return they always drop down to the next line of code. So then when a recursive call is made in the Treeview program when a folder is encountered a new instance of the code is created and in this instance the files are scanned that belong in that folder. The files are also attached to the correct parent node on the tree because in that instance of the recursive call, the node is passed as the Parent node (while in the calling instance it was a child). When the code returns from the recursive call, the Node goes back to being a child, and the other recursive call where it was the parent is destroyed and disappears. Furthermore, any other files that still exist in the parent folder are then interatively looped through and inserted as siblings along side the folder which just returned from its recursive call as the parent of its own instance of the code. So the important thing to keep in mind about recursive procedures and functions is that in each instance of the function the values are unique to that instance of the code. This is what makes recursion work. Many programmers are comfortable with iterative code (for loops, while loops, repeat statements) but Trees are naturally recursive, as the disk scanning code demonstrates, and so although it is more difficult to design code using recursion, its worth learning for that very reason.

     A few words about the code. The recursive function that scans the drive is called FileLook and it is called by passing it a starting path and wildcards to indicate any file or folder, as well as the root node of the tree, initilized on the TreeView by the Button1Click event handler. In the first recursion the RootNode will be parent node, as described above, and ultimately it will be the parent of every other node on the Treeview.

FileLook(ThePath + '\' + '*.*', RootNode)

      The initial path is obtained using a standard Windows API call for a Folder Browser demonstrated in the function BrowseForFolder. The Form Create method loads 15 icons onto the ImageList that will be connected to the TreeView using its Image property on the Object Inspector. It also calls a Windows function that locates the Windows system directory which is where Shell32.dll is located. There are about 80 icons in Shell32.Dll and if you follow the links on the main index page to one of the Icon browsing examples you can open the Shell, browse the icons, and make a note of the number associated with an icon you might want to call for code of your own. For the purposes of this demo the icon numbers are encoded as two numerals in a string constant and are referenced for adding to the TreeNode by a list of constants you will notice in the variable declaration section of the code. There are two sections of Code that find icons for the TreeView, FindFilesIcon and RegistryIconExtraction. Icons can be located in an exe file, an ico icon file, in which case the icon should be extracted from those files. Certain file extensions are associated with certain icons (for example the extension txt is associated with the icon for a text file, and so on). These associations are stored in the registry. A text file does not contain an icon, but rather the icon associated with a text file is stored in Shell32.dll, and this information is found in the registry key for that file extension. The function TracePath demonstrates how to work back to the root from any given selected TreeNode, and in this code it returns a string which is a fully qualified path, including a filename if it was a file that was selected. The source code is commented and hopefully together with the discussion included on this page, will be easy to understand.

      A final note. Processing graphics is time intensive even on a fast computer, so you should scan just a few directories and sub folders. Normally what you would want to do is to exclude subdirectories in your disk scan and just scan the current folder, thus quickly filling one branch of the tree at a time. However, to demosntrate recursion, this code scans sub folders, and thus it can seem that perhaps the program has crashed and is not responding, but actually it is just chewing up CPU cycles on all those TreeView graphics. Scan just a few folders and sub folders to get a feel for how the code works.

You can download the source as a text file ... treeview_delphi3.txt the Delphi 3 version or ... treeview_delphi5.txt the Delphi 5 version. The code is also downloadable as a ready to run project file for Delphi 3/Delphi 5 in the following zip file ... treeview_disk_scan.zip 20 KB.

Related pages can be found on the Main index page on this site...


Delphi INDEX




A Unified Field Theory

failed_gravity_theory.gif - 10361 Bytes



The Unified Field Theory
is also available as a zip file ->
unified.zip

Introduction :The Pioneer Effect and the New Physics. A brief description of the new physics required to explain the 'Pioneer Effect', which is the constant deceleration of space craft as they fly through space.




Principles of Evolution: A Study in the Evolution of Bedbugs



A couple of years ago my bedroom was invaded by bedbugs. There were two variant genetic lines. One type of bedbug was an enlongated, thin, tubular insect, and the second genetic line was a flat, perfectly circular insect. The result of the cross breeding of these two genetically distinct variants was the production of a bedbug with charcteristics of both, an enlongated, flat bedbug with a central bulge (such that the shape of the bedbug was somewhere between 'long' and 'circular'). The long skinny bedbugs were such strange and unfamiliar looking insects that at first I did not recognize them as being bedbugs, and considered them to be a seperate species of insect. However, as the photographs of bedbugs above indicate, enlongated and skinny bedbugs are not uncommon, and the photographs also show the variants that are produced by genetic combinations that result in an insect somewhere in between 'circular' and 'enlongated'.

Therefore it is my hypothesis that evolution occurs by means of the transfer of dominate genes, with the production of such dominant genes being the product of 'biological algorithms', a genetic software program that brings physical characteristics into harmony with behavior, such that when behavior changes, and a conflict then exists, this acts as a trigger and causes the release of dominant genes. The result is rapid evolution of species. The bedbug is a relatively new insect, not the product of millions of years of evolution but rather an insect that is evolving in real time. The newly emerging dominant form of the insect is the flat, round ciruclar insect, well adapted to living in human bedrooms (it is flat, rather than tubular, thus allowing it to hide in the smallest cracks, living a stealthy lifestyle, and it is round, which gives the insect a maximum storage capacity such that it must endanger itself only a few times a month by emerging to feed.

Other examples of rapid evolution include the development of long legs in an invasive species of toad in Australia. As the toads move into the mountainous regions of Australia, and their behvaior changes, making them 'climbing toads', over the course of just a couple of decades the toads in the highlands have grown long legs specially adapted to climbing. It is worth noting here that the toads are poisonous, and are a successful invasive species because they have no natural predators in Australia, and so it would not be the case that the toads with long legs were 'the fittest survivors', because all the toads are survivors, and therefore predation does not explain the rapid emergence and spread of such well adapted, long legged toads. Once again we see evidence for the existence of biological algorithms and the rapid spread of dominant genes through a population, which once introduced proceed to overwhelm the older genes which are being replaced (making toad long legged and a bed bug round and flat).


A Theological Experiment

My interest in pursuing the Unified Field Theory is spurred on by my need to discover the theoretical explanation of a new form of propulsion (as explained on this page: Why the Unified Field Theory?). The experiment involving the bedbugs came out of nowhere.

I also believe that it is possible to justify theological propositions using experimental methods. If a thing is an objective truth then it can be verified and proven true by means of experimentation. Such a theological proposition is of more value than a ‘divine revelation’, since such revelations depend upon nothing more than establishing authority figures which requires the creation of artificial hierarchies, for the only reason why I might be encouraged to believe an authority figure who orders me to believe unsubstantiated opinions is if I could somehow be convinced that this authority possessed a mind that was somehow superior to mine, and thus was fit to express opinions as though opinions were unquestionable facts and thus worthy of being elevated to the status of absolute dogma.

There is a self evident human inequality which is visibly apparent. Some people are ‘beautiful’ and thus are the true elite on this planet, and some people are not. It is this sexual inequality and the degeneration that follows upon beauty that is the true driving force behind all the evil that happens on earth. The need for ruthless oppression and the pursuit of wealth and the consequent creation of suffering and poverty which must follow upon this practice is for the purpose of creating an artificial alpha elite.

The true elites are the young and the beautiful. The artificial elite are the rich and the wealthy. The elite aging rich artificial alpha male has no good looks, for he is physically degenerate, but he will be found escorting beauty because he has a beautiful wallet. If he loses his wallet he will be found at home with all the other unattractive aged beta males sitting in a rocking chair watching reruns of Bonanza. No money, no sex. It is for this reason that the alpha males are found to be so ruthless and so violent in pursuit of their goal. The alpha male has fallen. The beta male has arisen and now the whole planet is full of ruinous destruction for it.

We see in religion a confused and contradictory reaction to this reality. On the one hand religion preaches a sexless heaven where castration and the clitorectomy create ‘pure spirits’. Muslims throw women under sacks. On the other hand religion supports hierarchy and is the prop of the elite alpha male. It is for this reason that religion is incoherent when it comes to speaking about sex.

Now we see this same principle at work in all of nature. Guppies dance and show off their colorful tails and the guppy who dances with the most colorful tail is the sexually successful guppy. Therefore it is the doctrine of the ruthless oppressor which teaches that the solution to human sexual violence is to be found in castration and the creation of pure ghosts. This would be equivalent to damning an aardvark for having the ‘sinful aardvark nature’ or prosecuting an anteater for the high crime of ‘ant genocide’.

Therefore it was my theological hypothesis that the correct solution to this problem is to give every guppy a beautiful colorful tail. I compare this solution to the classic religious solution which is to cut off every tail since having a tail is ‘sinful’. If having a tail is sinful then God must be sinful for no human being has any choice in deciding whether or not they would be born with a colorful tail, or whether they would not.

When I was young I was a beautiful guppy with a lovely tail. So everyone seemed to think. I am older now. My nose became very badly sunburned and destroyed. It seemed good to me to test my hypothesis by using these ‘biological algorithms’ to correct this problem. I healed half my nose as you can see by the line separating the still very dark patch on the side in the photograph below.





I documented my experiment on these pages. one two t hree four fi ve six


I have confirmed to my own satisfaction that my theological proposition is correct and that religious dogma is erroneous, being based as it was upon nothing more than ‘divine revelation’ which is just a form of opinionated speculation. For the time being I am not continuing this experiment, for I must wait until the weather on this planet improves, and the dark clouds of ruthless oppression break letting a little sun shine come through so that I can show the world the truth about God, by showing people how God goes about giving an old guppy back his beautiful colorful tail.


Until then I will have to sit on the sidelines, while all my scientific breakthroughs are deliberately ignored, while I wonder to myself what ever in the world could be wrong with the human race, because what this all will prove at the end of it all is that there definitely was something wrong with the people on this planet.