by Ken Mayer
January 8, 2002
What exactly is Overriding, anyway? Well, to get started, overriding is simply changing the behavior of an event, or method, of an existing object.
You can override code for stock classes in dB2K (form, entryfield, etc.); and you can override code for custom classes. This document will briefly show examples of each ...
Stock classes, such as forms, have events and methods which fire when specific "things" occur. These are events that are executed by Windows when, for example, a mouse button is clicked, or by dBL navigating through methods such as first(), last(), next(), etc.
If your work included scrolling through a table to perform calculations that are subsequently displayed on the form, any datalinked controls would flash while the code executes and could be distracting to the user. Eliminating this problem provides a simple example of overwriting a stock class's events (or methods).
Assuming you are using the form designer, and you have your controls and such laid out, you might do something like the following:
Note that the form designer has placed the following code in the source editor:
function form_open return FORM::open()
Most importantly, also note that a call to "FORM::open()" was added at the very end. Because we just told the software that we are overriding this method, the form would never open without this code. Now you can insert whatever code you need into the new function. The following is a very simple example:
form.rowset.first() nTotal = 0 do while not form.rowset.endOfSet // add to it nTotal += form.rowset.fields["ANumericField"].value form.rowset.next() // move to next row enddo form.rowset.first() // back to the top form.TotalText.text := nTotal // display value return FORM::open()
When you run the form, the above code will be processed before anything actually displays and before any subsequent code is run.
Pretty powerful stuff, eh?
The above example was for a method of the form class. Methods generally have code already attached which is why the designer will stream out a call to the original code. Events, however, often do not have any event already attached and require you to hook on your own code. If you are using a stock class, the chances are there is no code attached to an event.
This question really comes up a lot, particularly with code contained in the dBASE Users' Function Library (dUFLP) -- for more on this library, see the dBASE KnowledgeBase.
While this particular example does not require the use of the dUFLP code, the same techniques apply. – for more details on custom controls, see the Knowledgebase, the tutorial, and online help.
Even though the following example demonstrates how to override an event, the same basic concepts could be used to override a method.
To see this, create a file called MyCust.cc in the source editor (from the Command Window: modify command MyCust.cc ).
Enter the following:
class MySaveButton( oParent ) of Pushbutton( oParent ) custom this.text = "Save" function onClick form.rowset.save() endclass
This is a rather simple control - a pushbutton with the text "Save" and code that saves changes to the form's rowset. To use it:
Note that you now get a dialog box stating:
form.mysavebutton1.onClick is linked to a method outside of the form; do you want to overwrite it?
Click the 'Yes' button. Notice what happens -- the designer places the following into the source code editor:
function MYSAVEBUTTON1_onClick return
At this point you’ll need to provide the code to make the onClick event actually do something. There remains one problem however -- the original custom control's onClick event will never fire unless told to do so. Unlike our previous example for the stock form class’s OPEN method, note the absence of a call to the original onClick event. This was done because you may not want to call the code in the original control. If you want the control’s onClick event to fire, you’ll need to decide “when” – before, during, or after your own code. (If you're doing validation, you’ll probably want it to fire AFTER your validation code ...)
Once you’ve decided where to insert your code, all that’s left is to add a reference to the class name and the event:
For example, you might want to validate the data and then save the rowset if the validation passes:
function MYSAVEBUTTON1_onClick // test for valid data // Make sure the name field is not empty, for example: if empty( form.rowset.fields["Name"]Value ) msgbox( "The Name field cannot be empty!" ) form.entryfield1.setFocus() // Set focus back there return endif // You could add other code here // Call original onClick event: MySaveButton::onClick() return
You have just successfully overridden the code and called the original code to save the data.
Note: The example shown above demonstrates how to override an event, but you could just as easily override a method. In the case of a method, however, it's really a good idea to make a call to the original class's code as shown in the form’s Open method example. Without it, the original code will not fire and you could be in trouble.
Hopefully this will give you some ideas on how to more effectively use the power of dBL in dB2K!