Logo

Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.

AutoYield, DoEvents

This property and its related command control the interaction between VFP and ActiveX controls.

Usage

appApplication.AutoYield = lYield
lYield = appApplication.AutoYield
DoEvents

Parameter

Value

Meaning

lYield

.T.

This is the default setting, and the mode of Visual FoxPro 3. Windows events are processed as they are received, meaning the operator can interrupt your code.

.F.

Use this setting if ActiveX controls on your forms need to run your custom code.

The challenge of working with ActiveX controls is that, at times, they seem to have a mind of their own. When AutoYield is left at the default setting, clicking on an ActiveX control sends that click directly to the control and it responds with its native behavior. If your code happens to be in the middle of doing something else, well, too bad.

In Visual FoxPro 5.0, Microsoft introduced the AutoYield property and corresponding DoEvents command to solve this problem. When you have a form with an ActiveX control, set the application’s AutoYield property to .F. and process the messages received by the control by issuing DoEvents when you’re ready to handle them.

DoEvents is also handy when you’re executing processes that are normally not interruptible. For example, if a long loop is running, normally a button-click isn’t processed until the loop is completed. Putting DoEvents in the loop tells FoxPro to go check for interface events, so that if the user is desperately clicking the Cancel button, you can find out.

In versions prior to VFP 7, issuing DoEvents frequently is hazardous to your application’s performance, by an order of magnitude in some cases. Since even a single DoEvents is pretty time-consuming, we recommend setting up a Cancel button, using your loop to test for MDOWN() over your button (detected with SYS(1270)), and only then invoking DoEvents. MDOWN() is efficient enough that you can check it every time through the loop and be more responsive to the user’s click, while not bogging down the processing too badly.

VFP 7 significantly improves the behavior of DoEvents, so you can call it as often as you wish without the performance problems seen in earlier versions.

Example

_VFP.AutoYield = .F.

FOR nCount = 1 TO nSomeInsanelyLargeNumber
   * Do the normal processing for this loop.
   * Now check for user events.
   IF MOD(nCount,100) = 0
      DoEvents
      * If user canceled, get out.
      IF LASTKEY()=27
         EXIT
      ENDIF
   ENDIF
ENDFOR
* Check to see if the Cancel button was pressed while
* processing in a loop. First, check to see if the mouse button
* was pressed. If so, see if the control the mouse is currently
* over is the button named cmdCancel. If so, use DOEVENTS to
* handle the click of the button.

IF MDOWN()
   loControl = SYS(1270)
   IF TYPE('loControl.Name') = 'C' AND ;
      UPPER(loControl.Name) = 'CMDCANCEL'
      DoEvents
   ENDIF
ENDIF

See Also

MDown(), SYS(1270), SYS(2333)