-
-
Save mikepotjer/43a1f244cc90531095d93cb2367cf4c8 to your computer and use it in GitHub Desktop.
Visual FoxPro ESCAPE handler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
LPARAMETERS tcOnEscapeCommand AS String | |
#IF .F. | |
*------------------------------------------------------- | |
*---------------- FILE CREATION INFO ------------------- | |
Program....: OXESCAPEHANDLER | |
Author.....: Michael J. Potjer | |
Based on ideas in Calvin Hsia's May 15, 2008 blog article | |
"How to interrupt your code": | |
http://blogs.msdn.com/calvin_hsia/archive/2008/05/15/8510677.aspx | |
Date.......: May 21, 2008 | |
*------------------------------------------------------- | |
*------------------ USAGE SECTION ---------------------- | |
DESCRIPTION: | |
A function, procedure, and class to encapsulate the process of setting up an | |
ESCAPE handler, and create an object to restore the relevant settings when | |
you no longer need the handler. | |
PARAMETERS: | |
tcOnEscapeCommand (O) - The command to use as the handler for ON ESCAPE, such as | |
"DO MyEscapeHandler" or "_SCREEN.oEscapeHandler.OnEscape()". | |
If omitted or empty, the escape handler procedure | |
OSI_OnEscapeHandler, defined in this PRG, will be used. | |
EXAMPLE: | |
TRY | |
*-- Load the ESCAPE handler. | |
loOnEscape = OXEscapeHandler() | |
*-- Run some process (such as a bunch of queries) which the | |
*-- user is allowed to abort. | |
CATCH TO loException WHEN loException.ErrorNo = 2071 ; | |
AND loException.UserValue == "ESCAPE" | |
*-- The user aborted the process by pressing ESCAPE. Make | |
*-- sure you cleanup and abort this process. | |
CATCH TO loException | |
*-- Some other error occurred which needs to be handled. | |
FINALLY | |
*-- Restore the ESCAPE settings. | |
loOnEscape = .NULL. | |
ENDTRY | |
RETURNS: Object | |
Returns a push/pop object which stores the original settings related to an | |
ESCAPE handler, and which will restore those settings when released. | |
*--------------- MAINTENANCE SECTION ------------------- | |
INPUTS (extracted from environment): | |
_VFP.AutoYield | |
SET("Escape") | |
ON("Escape") | |
OUTPUTS (changes to environment): | |
_VFP.AutoYield = .T. | |
SET ESCAPE ON | |
ON ESCAPE <Some Procedure> | |
However, these settings are all returned to their original values when the | |
object returned from this function is released. | |
PRE-CONDITION INVARIANTS: None | |
POST-CONDITION INVARIANTS: | |
The object returned from this function must be released to restore the ESCAPE settings. | |
COLLABORATING METHODS: | |
None, apart from what's contained in this PRG. | |
#ENDIF | |
LOCAL loOnEscape, ; | |
lcOnEscapeCommand | |
*-- Check if an ON ESCAPE command was specified. If not, we'll use | |
*-- the procedure included in this program file. | |
lcOnEscapeCommand = IIF( VARTYPE( m.tcOnEscapeCommand ) = "C" ; | |
AND NOT EMPTY( m.tcOnEscapeCommand ), ; | |
ALLTRIM( m.tcOnEscapeCommand ), "DO OSI_OnEscapeHandler" ) | |
*-- Create the push/pop object which will save the current ESCAPE | |
*-- settings, and turn on the specified ON ESCAPE handler. | |
loOnEscape = CREATEOBJECT( "cusPushPopOnEscape", m.lcOnEscapeCommand ) | |
RETURN m.loOnEscape | |
********************************************************************* | |
*-- The default ON ESCAPE procedure which will be used if you don't | |
*-- specify a custom procedure. | |
********************************************************************* | |
PROCEDURE OSI_OnEscapeHandler | |
*-- Within a TRY..CATCH, this will generate error 2071 - "User Thrown | |
*-- Error". If you don't have a TRY..CATCH structure setup to catch | |
*-- this error, you will get error 2059 - "Unhandled Structured | |
*-- Exception", and your app will probably shut down. | |
THROW "ESCAPE" | |
RETURN | |
********************************************************************* | |
*-- An object used to save and restore the settings needed to enable | |
*-- ESCAPE handling. | |
********************************************************************* | |
DEFINE CLASS cusPushPopOnEscape AS Custom | |
*-- These properties store the settings of SET ESCAPE and ON ESCAPE | |
*-- at the time this object is instantiated. | |
icSetEscape = SPACE(0) | |
icOnEscape = SPACE(0) | |
*-- This property stores the setting of _VFP.AutoYield at the time | |
*-- this object is instantiated. | |
ilAutoYield = .NULL. | |
********************************************************************* | |
PROCEDURE Init | |
LPARAMETERS tcOnEscapeCommand AS String | |
*-- It's up to the developer to make sure a command expression is | |
*-- passed to this method. | |
ASSERT VARTYPE( m.tcOnEscapeCommand ) = "C" ; | |
AND NOT EMPTY( m.tcOnEscapeCommand ) ; | |
MESSAGE ALLTRIM( PROGRAM() ) + " failed!" + CHR(13) ; | |
+ "Invalid ON ESCAPE command specified" + CHR(13) ; | |
+ "Select <Debug> to check out the problem." | |
*-- Save the current settings of _VFP.AutoYield, SET ESCAPE, and | |
*-- ON ESCAPE, so that they can be restored after this object is | |
*-- released. | |
This.ilAutoYield = _VFP.AutoYield | |
This.icSetEscape = SET("Escape") | |
This.icOnEscape = ON("Escape") | |
*-- Make sure the AutoYield setting is true, otherwise the setting of | |
*-- SET ESCAPE is ignored, and treated as SET ESCAPE OFF. | |
_VFP.AutoYield = .T. | |
*-- Make sure SET ESCAPE is ON, and set the ON ESCAPE handler to the | |
*-- specified expression. | |
SET ESCAPE ON | |
ON ESCAPE &tcOnEscapeCommand. | |
ENDPROC | |
********************************************************************* | |
********************************************************************* | |
PROCEDURE Destroy | |
LOCAL lcSetting | |
*-- Restore the original ON ESCAPE handler. | |
lcSetting = This.icOnEscape | |
ON ESCAPE &lcSetting. | |
*-- Restore the original SET ESCAPE setting. | |
lcSetting = This.icSetEscape | |
SET ESCAPE &lcSetting. | |
*-- Restore the original AutoYield setting. | |
_VFP.AutoYield = This.ilAutoYield | |
ENDPROC | |
********************************************************************* | |
ENDDEFINE |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment