7

The LA Fox Developer Newsletter
July 1997
FoxTalk Tips (Con’t from page 6)

illustrating the differences in accessing and updating data via
ODBC vs. the methods employed in traditional FoxPro/Xbase
syntax.

Pop-ups with a Temporary Error Handler
By Andy Neil

FOXPRO’S ON ERROR command lets you replace the default
error handler (‘cancel, suspend, ignore’) with your own. This
feature can be a ‘hook’ for fancy error reporting programs. But an
error handler doesn’t need to be a huge user-defined function
(UDF) with a full user interface to be handy. In some cases, you
just want to detect that an error occurred.

For example, let’s say you want to write a procedure that adds
a “Suspend” bar to one of your application’s menu pop-ups. You
also want to run this procedure from a hot key at any time. You
can’t define a bar for a non-existent pop-up, so you’ll need to
check for it first. There’s a problem, though-FoxPro doesn’t
have a function to do that! Without an ISPOPUPO, how do you
confirm that it’s out there? You do it with a temporary error
handler, as illustrated in TMPONERR.PRG:
Listing 1
*
TMPONERR.PRG - uses temporary
error handler
PRIVATE IcWasOnErr, IlPopupOK, InNewBar
*
Save the old error handler name
lcWasOnErr = ON(ERROR’)
*
Initialize a flag
IlPopupOK = .T.
*
Temporary error handler
ON ERROR IlPopupOK = .F.
*
Where to put new bar?
InNewBar = cNrBAR(’MYPoPUP’) + I
*
Restore old error handler
ON ERROR &IcWasOnErr
*
Missing popup?
IF !m.llPopupOK
DEFINE POPUP MYPOPUP FROM 5,5
InNewBar I
ENDIF
*
MYPOPUP exists, guaranteed!
DEFINE BAR InNewBar OF MYPOPUP;
PROMPT ‘Suspend’
ON SELECTION BAR InNewBar OF MYPOPUP SUSPEND
ACTIVATE POPUP MYPOPUP
REWRN
**EOFTMPONERR.PRG**

At first glance, it looks like the code inside the IF statement
would never be reached since m.llPopupOK has to be true. The
trick here is in the line with CNTBARO. If ‘MYPOPUP’ hasn’t
been defined, the CNTBARO function will yield an error. If you
were using the default FoxPro error handler, this would put up
the usual dialog box. Instead, when CNTBARO hits the error,
your temporary handler is called.

In this example, the entire “handler” is one statement, which
sets a logical flag to indicate that an error occurred, then returns
control to the executing procedure. The IF statement traps this
and issues the DEFINE POPUP, lethng the rest of the code run
successfully. You could wait for the DEFINE BAR statement
itself to trigger the error, but then you’d have to write loops to
make it execute again after a failure. Using a separate state-
ment like CNTBARO is easier to follow.

Notice that I placed the code restoring the old error handler
immediately after the line that might generate the expected
error. This reduces the risk of encountering some other error
while the temporary handler is in place. For instance, if the error
handler hadn’t been restored when the DEFINE BAR statement
was executed, and the DEFINE BAR statement had a typo in it,
the error handler would just set IlPopupOk to .f. and go on
without alerting the user.

This technique is useful in a variety of contexts other than
looking for pop-ups. For cases where it’s impossible (or just a
lot of work!) to check whether a statement will produce an error,
it’s often easier to set up a temporary error handler and give it a
try. Just be sure to leave a comment in your code so you can
remember why it works!

[Ed. Note: Fox Talk is published monthly by Pinnacle Publish-
ing, Inc., 18000 72nd Avenue South - Suite 217, Kent, WA
98032. Cost of domestic subscriptions, which include monthly
disks, is $179112 issues, $259124 issues. To order, call
Pinnacle at 8001188-1900, or visit their website at http://
www.pinpub.com. It’s a very worthwhile subscription and you
can learn some neat “stuff”]


Hot Tip.....
Add a Field InputMask Property to your Data Dict.

VFP doesn’t use the Comment property for fields (in the Table
Designer). The Comment property is for any
character string (up to 254 characters) you want to associate
with the field. You can use the field Comment
property to store the most significant thing that seems to have
been left out of the data dictionary.. .the
InputMask string. In the Form/Class Designers’ Properties
Sheet, enter this code in the InputMask property:

=DBGETPROP(’Customer.CustNo”,”FIELD”,”cOMMENT”)


Have You Heard...
“Did you hear that Microsoft Interactive is coming out with
a new version of the TV show ‘Hawaii Five-Oh’? It will be
called ‘Hawaii 5.Oa’”
<rim shot>
Tom Rombouts

7