The TreeDropper Control
A custom class written for Visual dBASE 7.01
by Dan Howard - Date: March, 1999
  • What is the TreeDropper control?
  • Features
  • What's included in the package
  • Installation
  • How to use the TreeDropper on your forms
  • Some ideas for it's use
  • Nuts & Bolts
  • Limitations
  • Conclusion
  • Known issues

  • What is the TreeDropper control?

    The TreeDropper is a new control that is similar in functionality to the stock combobox found in dBASE. This one though will drop down a treeview instead of the simple list. This takes advantage of two of the most powerful classes in dBASE: the container class and the treeview class.

    Features

    What's included in the package

    Installation

    Simply extract all of the files from bu01tree.exe into a directory, open up dBASE, locate the directory you unzipped the files to and double-click on TreeDrop.wfm in the navigator to see the sample form.

    How to use the TreeDropper on your own forms

    The first thing you should do is open up Dform.cfm in the source editor and review the added methods in it. This base form class handles an important feature of the TreeDropper and any other control you may ever use. DForm uses iteration to look for a special method called “INIT” in either the form or any control on the form. If it finds one, it runs it before the form opens. This gives you the advantage that all initialization of the form itself or any control on the form can be done while the form is off screen. This prevents a lot of flickering when you open the form. The DForm class can be implemented as a base class for your own forms or you can simply cut the code out and paste it in you own base form class. DForm has a few other goodies as well!

    To ensure that the TreeDropper is always loaded when dBASE starts up, open up a form in the form designer,  right-click on the component pallet and choose "Setup Custom Components" from the menu. You'll see a dialog box which lists all of the custom class files which you currently use.  Click the "Add" button and locate the TreeDrop.cc file then click “OK”. Now this class will be added to your vdb.ini file and will be automatically loaded next time you fire up dBASE.

    Now go to the “Custom” tab on the component pallet, find the TreeDropper object and drag in onto the form's surface. What you'll see is something similar to what is shown in the image below. Notice that the  button is missing? This is  because I create this button dynamically before the form opens and position it at the right edge of the entryfield. This saves you the trouble of having to reposition it yourself in the designer.  You also don't have to worry about the widths of the entryfield or the treeview itself. They will resize themselves to the width of the container.

    Notice also the thin line under the entryfield. This is the treeview itself. I make it small so as not to take up too much space on your form. This treeview will be resized and repositioned at run-time depending on the width of the TreeDropper control itself. It's available in the designer so you can customize the treeview any way you want.

    If you want to add treeitems to the TreeDropper in the form designer, use your mouse to expand the container downward and then expand the treeview. You can use this treeview the same as any standard one in the designer.

    You can add, edit and delete items all you want and the information will be saved in your form. There are other ways of filling the treeview with items but I'll get to that later.

    The TreeDropper has a few custom properties which you can use as well. Since dBASE does not yet support custom property streaming they have to be defined in either the Init or onOpen methods of your form.

    They are: See the TreeDropForm (TreeDrop.WFM) to see how these are implemented.

    Some ideas for its use

    Nuts & Bolts

    This class implements some interesting techniques. One of the challenges posed by this control is it's z-order. If it is dropped below pushbutton for instance, the treeview will show up below it. Not exactly what we want. My solution is to use the Win API SetParent function. This function will attach an object to another object. It takes two hWND properties as parameters. See the TreeDropper code to see how it works.  There is a limitation to this:  a combobox's list will drop outside the form if necessary - the TreeDropper's list won't. I haven't quite figured out how to do this yet so if you come up with a way, let me know.

    I like the ability to create and move objects before the form opens.  This allows you to define two types of functionality: design-time and run-time. It also simplifies the use of containers in the form designer as you don't have to deal with repositioning all of the container's components. You can define your own rules on how the container's components will look at run-time.

    I create a form property called ActiveTreeDropper in this class. It is a pointer to the currently active TreeDropper control. I use it to ensure that only one TreeDropper is open at a time.

    I also added several new methods to the treeview which you could move into your own base treeview class.

    Limitations

    Since the lists are objects and not simple strings you should probably not use this control for very large lists.  A few hundred will be ok but more than that and you could run out of memory.

    I didn't spend much time testing the positioning logic with different fonts. I normally use Arial 8 pt for my forms and controls. You might find that the drop button doesn't position itself correctly if you standardize on a different font. Improvements in this area would be greatly appreciated. Also this only works with “char” metrics. It would need more tweaking to handle others.

    The DropDownHeight property doesn't really do what I want. This should specify how many items will appear in the treeview regardless of the font or font sizes used. Currently it simply sets the treeview's height to it's value.

    Finally I would definitely not call this a production control.  It does the basics but there is a lot of extra functionality that could be added to it. Let me know of any ideas you have for this control and I'll implement them for the next version.

    Conclusion

    You can see that the container class gives us a whole new avenue for custom control creation.  With the container we can create composite objects. You can create virtually any type of control that you can dream up. If you're looking for inspiration for your own controls, have a look at the software sitting on your desktop now.  Think about how other  controls in different applications operate. How does the user interact with them? How do they interact with each  other?  When you see something you like, sit down, plan it out and then code away. The possibilities are endless!

    Known Issues:

    Workaround: Simply use the treeview either as a static treeview or a dynamic one. Don't mix them. In other words - if you know that the contents of your treeviews are going to change at some time, don't add items to them in the designer - use the Fill method instead.
    To download the TreeDropper Control code, click here
    (it's a 63Kb zipped executable file)


    Dan Howard has been an independent software developer for almost 10 years using Clipper for DOS and Visual dBASE for Windows.  He can be contacted at: sproket@total.net