Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Adding code to every form/WriteMethod
Message
 
 
To
26/03/1998 21:19:20
General information
Forum:
Visual FoxPro
Category:
Forms & Form designer
Miscellaneous
Thread ID:
00087353
Message ID:
00087689
Views:
37
Jim,

NODEFAULT and ::/DoDefault() are two different animals.

NODEFAULT is to prevent the automatic execution of the VFP BaseClass method code when all of the overridden code has executed. It's useful for two things 1) to prevent the BaseClass behavior entirely, and 2) to change when the BaseClass behavior occurs. And you are right about it being able to be executed at any time. I think of it as a flag set, that gets tested to conditionally execute the BaseClass behavior.

Thing 1: you want to prevent the A key from being entered in a textbox:
procedure KeyPress
lparameter nKeyCode, nShift
if ( nKeyCode = 65 )
   nodefault && pretend this keypress never even occurred
endif


Thing 2: change the order (this is my cTextBox.GotFocus)
* provide SelectOnEntry even if focus is coming to this control via mouse click

if ( this.SelectOnEntry )
   TextBox::GotFocus()
   nodefault

   this.SelStart = 0
   do case
      case ( this.MaxLength > 0 )
         this.SelLength = this.MaxLength
      case ( len( this.InputMask ) > 0 )
         this.SelLength = len( this.InputMask )
   endcase
)
endif

The explicit call to the BaseClass behavior is made TextBox::GotFocus() because it sets the SelStart and SelLength properties, which I'm about to modify. The nodefault is issued because otherwise we'd get another execution of the BaseClass behavior automatically at the end of my overridden code and it would undo all of the work of my code.

Ok so NODEFAULT only prevents the automatic execution of the VFP BaseClass behavior after the overridden method code It has NOTHING to do with overridden code anywhere up the class tree.

:: and DoDefault() control the execution of our overridden method code in the class tree.

DoDefault() there is a big kettle of worms, and to be honest I rarely use it, I still hardcode :: calls. Most of the time you don't see a problem, because most of the time the VFP BaseClass behaviors to not produce "observeable" effects. But DoDefault() when issued from a subclass to an empty ParentClass method will cause an execution of the VFP BaseClass behavior, and you'll get the automatic execution at the end. Issuing a :: call to the ParentClass does not cause this duplication to happen. So it's only going to happen to class trees two or more levels deep. This is a bug in my opinion, although not everyone in the VFP community agrees. Our subclasses should not have to know whether or not the class they are derived from has any code in the method. I first ran into this last summer while working on a txtDate class derived from my cTextBox class. The cTextBox.KeyPress() method is not overridden. Here's the relevant code from txtDate.KeyPress():
LPARAMETERS nKeyCode, nShiftAltCtrl

* This TextBox subclass provides Quicken date field keys to be used to adjust
* a date field.

* Keystroke           Function
* ---------           --------
* +, =, UpArrow       increment 1 day
* -, DownArrow        decrement 1 day
* M, Shift-UpArrow    First day of month, then back 1 month
* H, Shift-DownArrow  Last day of month, then to end of next month
* Y                   First day of year, then back one year
* R                   Last day of year, then to end of next year
* T                   Today
* E                   Empty (Erase)

* To remember M, H, Y and R think of MontH and YeaR

* 07-Aug-97 added arrow keys, changed to case from if
* 04-Nov-97 fixed problem with arrow keys, added mlUseArrow, added E

local lcKey, lnMonth, lnDay, lnYear

lcKey = upper( chr( nKeyCode ) )

if ( this.mlUseArrow )
   do case
      case nKeyCode = 5  && up arrow
         lcKey = '-'
      case nKeyCode = 24 && down arrow
         lcKey = '+'
      case ( ( nKeyCode = 56 ) and ( nShiftAltCtrl = 1 ) ) && shift up arrow
         lcKey = 'M'
      case ( ( nKeyCode = 50 ) and ( nShiftAltCtrl = 1 ) ) && shift down arrow
         lcKey = 'H'
   endcase
endif

if ! ( lcKey $ "T+-=MHYRE" )
   * 07-Jul-97
   * this appears to be a bug in 5.0a we should pass the other keystrokes on
   * but it causes them to appear twice in the field, so just don't DoDefault()
   *   DoDefault( nKeyCode, nShiftAltCtrl )
   return
endif

nodefault  && prevent dings from keys not normally allowed in date field

* 07-Jul-97
* again the bug would appear to be preventing the use of DoDefault to pass
* the key onto cTextBox, so send it using :: instead
* DoDefault( nKeyCode, nShiftAltCtrl ) causes ding
cTextBox::KeyPress( nKeyCode, nShiftAltCtrl )


The only thime you are going to see this is when the VFP BaseClass really does something you can detect, like KeyPress, GotFocus. Events like MouseDown who can tell that you actually made VFP display the pushed down image of a button once or twice, you can't unless traced the code with something like CodeView.

Now if you go put any code in the cTextBox.KeyPress() method DoDefault() would work just like cTextBox::KeyPress(). And that's where I feel the bug is, it shouldn't behave differently depending on whether or not there is code in the ParentClass method.

I've always thought DoDefault() was a shortcut, a way of coding a subclass without putting a hard-coded reference to the ParentClass::Method() in your overridden code.

Now back to the original question. Sometimes you want your overridden code to execute before the ParentClass, sometimes after, and sometimes in the middle of your overridden code. I'd say 98% of the time my code looks like:

ParentClass::Method()
*augmentation code here

1.99% of the time it's:

*augmentation code here
ParentClass::Method()

and 0.01%

*augmentation code here
ParentClass::Method()
*more augmentation code here

It just really depends on what the overridden code up the class tree is doing to know when it needs to be executed.

>Since NODEFAULT can be placed *anywhere* in its relevant code to perform its work (implying to me that 'default' is always done AFTER supplied stuff), then wouldn't it follow that DODEFAULT would also execute at a specific "spot" REGARDLESS of where it is placed?
>
>If not, then should we not be told, in view of what we are told for NODEFAULT?
df (was a 10 time MVP)

df FoxPro website
FoxPro Wiki site online, editable knowledgebase
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform