Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Adding code to every form/WriteMethod
Message
From
27/03/1998 12:43:50
 
General information
Forum:
Visual FoxPro
Category:
Forms & Form designer
Miscellaneous
Thread ID:
00087353
Message ID:
00087732
Views:
33
Yes, David, I too have some conceptual problems with a few of the things of VFP. And like you, I try to adapt to what's actually there rather than what *I* think should be there.

That bug of VFP 5.x (DODEFAULT executing twice) sure is enough to put anybody off using it!

That aside, It still appears more likely to me that DODEFAULT would operate similarly to NODEFAULT - that is, *after* supplied code is executed.
And therein lies one MAJOR advantage of the :: way of doing it, in that it makes sense that that would execute IN-LINE exactly where specified.

I may be barking up the wrong tree here, but details like this seem relevant to me, and I would like the docs to tell me rather than have to guess.

In any case, I guess enough has been said. It was interesting.

Cheers,
Jim N

>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?
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform