<% '------------------------------------------------------------------------------- 'File : dBase_Knowledge.asp 'Author : Surya Kumar 'Task : Knowledge Page for dBASE 'Version : 1.0.0.pk 10.08.2004 Base version 'Copyright : Ebase Interactive Inc., NY, USA '------------------------------------------------------------------------------- %> Welcome to dBASE


Overriding Events and Methods in dBL

by Ken Mayer
January 8, 2002
Printer Friendly Version

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

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:

  1. Click on the form surface (to make sure it has focus)
  2. Go to the inspector -- if it's not up, press the F11 key, etc.
  3. Click on the "Methods" tab of the Inspector
  4. Click on the "Open" method
  5. Click on the "Wrench" (tool) button

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:

function form_open
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.

Custom Classes

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:

  1. In the Command Window, type set procedure to MyCust.cc additive and press Enter.
  2. Create a new form. Double-click on "New" in the Navigator under "Forms", or type in the Command Window create form and press Enter.
  3. Drag a table to the form surface from the Navigator (such as the the fish table in the samples)
  4. Drag some fields from the field palette to the surface of the form
  5. Go to the component palette. On the "Custom" tab you should see the pushbutton. Drag it over to the new form.
  6. Make sure the pushbutton has focus and go to the inspector. Click on the "Events" tab. Click on the "onClick" event, and then the tool button.

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:

   MySaveButton::onClick()

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!