Tips And Tricks:
Visually Designing a Toolbar
by Robert Bravery


The new Toolbar class in Visual dBASE is a great addition to the arsenal of tools and classes available to the dBASE programmer who is about to make war with the application programming world. The addition of toolbars enhances the visual aspect of one's application, as well as adding to ease of use and user friendliness. This also brings it into line with the way many of today's applications operate, that is, having a floating and dockable toolbar available for your apps.

One problem is that the Toolbar class has a non GUI design interface. In other words, it does not have a graphical IDE with which to design a well planned and well thought out toolbar. This might be seen as a shortfall with the designers of dBASE, but if you see what has gone into Visual dBASE, the added features, the fixed bugs, then this is a small — perhaps we could use the term:—  “irritation” to deal with.

While studying the Toolbar class I came to realize that the way it is defined, the Toolbar class is very similar to the way the other classes in the form are defined. Because I am a lazy person,  I always try to look for an easier way to do something. So my thought was “Why can't we use the form as a part of the GUI design tool for the toolbar?”

Note: Before you carry on reading, be sure to read the HOWTO on toolbars by Ken Mayer, Senior SQA Engineer at dBASE Inc. This is a good tutorial on the Toolbar class, and since the emphasis in this article is not to explain the Toolbar class nor to teach you how to use it, I would suggest that you seriously consider reading Ken's article.

Designing the Toolbar

First thing is to open / create a new form using the Form designer. To get a feel for what the toolbar might look like, I would suggest that the form size should be short and wide, so as to simulate the look of a toolbar. Next place pushbuttons on the form and arrange them so that they are in line. Place as many buttons as one needs. Resize the pushbuttons so that they form a small square roughly about 30 x 30 pixels. What I do is place a single pushbutton onto the form size it correctly then copy and paste the rest. That way all buttons are the same size. Now we can change the various properties to the pushbuttons, like bitmaps and speedtips. Keep in mind that the toolbar has only one bitmap, so using all available bitmap properties of the pushbutton will not work. Use only one bitmap property. I use the upbitmap. The size of the bitmap is very important. The toolbar will automatically size to the largest toolbutton, and the toolbutton will automatically size to the size of the bitmap. Width is not of concern right now but the height is. Try keeping all bitmaps the same size. You are not limited to the size though. If you desire a large toolbar, as in IE5, that's your choice.

If you have read the HOWTO on the toolbar, you will have remembered that in the recource.dll file are some bitmaps especially created for toolbars; use these if you need to as you start out.

From the toolbar HOWTO:
bitmaps: The bitmaps being used in these examples have a resource name of “TS_xxxx” -- the first two letters stand for “Toolbar Small”, the underscore is a separator, and the “xxxx” part is some descriptive name for the actual image. These were created by the Samples and Art groups at Inprise specifically for toolbars. There are also “TL_xxxx” which are the exact same images, but they are a touch larger, hence the “L” instead of “S” in the resource name.

As you add bitmaps to your toolbuttons keep in mind that if you need a separator, then just leave that particular button blank, i.e. no bitmap. Also we need to remove all text from the pushbutton. Next we could draw some similarities between some of the properties of the toolbutton and the pushbutton. We need to do this is order to assign properties to the button which would work when the design of the toolbutton and toolbar is finally completed.

The bitmap property is how you define the image that appears on the toolbutton. This is either a resource or a file.

  • The bitmapOffset property is how you define the offset in pixels from the left of the given bitmap for where you want the image to begin. This is really only useful for those bitmaps that have a series of images for buttons.
  • The bitmapWidth property is similar to above, but used for how wide the image is in the bitmap being used.
  • The checked property returns a logical value if the button has the twoState property set to true — down is true and up is false.
  • The enabled property is what it sounds like — you can enable or disable individual toolbuttons. 
  • The parent property refers to the toolbar that the toolbutton is contained in.
  • The separator property turns the button into a vertical separator (useful for separating sections of a toolbar). Note that if you set this property to true, the only other property that will do anything is the visible property.
  • The speedTip property works like it does for any other visual control in dBASE — displays a bit of text when the mouse is left over the button.
  • The twoState property allows you to define a toolbutton as having two states — useful if you need to turn something on or off.
  • The visible property is what it sounds like — the toolbutton will only be visible if this property is true.
The onClick event is how you determine what to do when the user clicks on the button.

Perhaps we could map the properties as follow

 Toolbutton Property   Pushbutton Property 
 Bitmap  Upbitmap
 Bitmap Offset  None
 Bitmap width  None
 Checked   None
 Enabled  Enabled
 Parent  Parent
 Separator  None
 Speedtip  Speedtip
 Twostate  Toggle
 Visible  Visible
 Onclick  Onclick

We can then assign values to our pushbutton properties which would then correspond to the values of properties of our future toolbuttons. Once you have assigned the values to the properties wich are needed, we can then save out form. The form might look like the following:
Comment: The irregular spacing between the toolbuttons at this point is confusing and distracting.

Changing the form to a toolbar

Once the form is saved we need to open it in the editor and change a few things. First we delete or change the header information that is streamed out by the Form designer. Next we need to delete the form initiation method, i.e., delete all the following:
parameter bModal

local f
f = new MYTOOLBARForm()
if (bModal)
f.mdi = false // ensure not MDI

Next we need to replace and change the class from FORM to TOOLBAR. So the following: class MYTOOLBARForm of FORM must be changed to class MYTOOLBARForm of TOOLBAR.

Next we need to do a few search and replace commands. First, we need to search and replace the pushbutton class with the toolbutton class. So in the editor replace the word “pushbutton” with “toolbutton”. You will then notice that all your pushbuttons are now defined as toolbuttons. Example:
with (this.TOOLBUTTON1)
onClick = class::TOOLBUTTON1_ONCLICK
height = 30
left = 10
top = 6
width = 30
text = ""
upBitmap = "RESOURCE #2110"
speedTip = "Enter, Edit or Update Students."

Once this is done, we can then replace all the rest of the properties. Referring to the table above, upbitmap would be replaced with bitmap, and toggle with twostate. What do we do with the properties that are not part of the toolbutton class? Well, simple: delete them. So now we have to scan through our code and delete all lines that do not pertain to the Toolbutton class. We must also be reminded to delete any properties from the Toolbar class that are still a spillover from the form. We can delete all, but I chose to keep the text property, so that when the toolbar is floating it would have a descriptive property. So then all the following would be deleted:
metric = 6 // Pixels
height = 53
left = 163
top = 122
width = 436

Now our instance of the Toolbar class would look something like this:
with (this)
  text = "Standard Mail Box Toolbar"

this.toolbutton1 = new toolbutton(this)
with (this.toolbutton1)
  onClick = class::toolbutton1_ONCLICK

  bitmap = "RESOURCE #2110"
  speedTip = "Enter, Edit or Update Students."

this.toolbutton2 = new toolbutton(this)
with (this.toolbutton2)
  onClick = class::toolbutton2_ONCLICK
  bitmap = "RESOURCE #1060"
  speedTip = "Enter, Edit or Update Correspondence Courses"

Next thing we need to do is locate the code for the only pushbutton (now a toolbutton) which never had a bitmap assigned to it. We are going to use this as a separator toolbutton. Once found we enter the separator property as true. For this toolbutton it would be the only property. Our code might then look like this.
this.toolbutton7 = new toolbutton(this)
with (this.toolbutton7)
  separator = true 

Making the toolbar work with functions.

Adding event capabilities to the pushbutton is easy. If we previously added onclick()events to the pushbutton when we designed our form, then theses would be carried over automatically, and we would need not do anything. The onclick() event is the only one that we need at this moment. Because our original pushbutton had such an event, now our instance of the Toolbutton class will also have an onclick() event.
this.toolbutton6 = new toolbutton(this)
with (this.toolbutton6)
  onClick = class::toolbutton6_ONCLICK
  bitmap = "RESOURCE #1050"
  speedTip = "Edit, Edit or update Postal Codes and Areas"

This onClick() event was created while still in the forms designer, the functions were automatically streamed.
function toolbutton6_onClick
  do postal.wfm 

Finishing up

Once this is all done. All that we need to do is save the toolbar as either a *.cc or a *.prg, and attach the toolbar to a form. Once the toolbar is attached to a form we then have a great working toolbar that was designed, at least in part, visually.


If you are exactly like me, you would always strive to push dBASE to the limits, as well as trying to find shortcuts and better ways of doing things. dBASE is a powerful yet very flexible programming language. The are always many ways to skin a cat. I hope you enjoyed this article. Don't be afraid to share your small gems with the rest of us, no matter how small they might seem to be. If they are of assistance to you, then they might also be of great assistance to others.

The author would like to thank Robert W. Newman (my proof-reader) for his suggestions and the improvements they brought to this text.