** Main Program SET PROCEDURE TO StateClass poInitialState = CREATEOBJ('SaveState') poSetupState = Setup() DO OtherStuff **Setup.Prg SET EXCLUSIVE OFF * other stuff RETURN CREATEOBJ('savestate', .t.) && return a state object **Cleanup.Prg poInitialState.Restore() **StateClass.Prg DEFINE CLASS SaveState AS LINE PROTECTED ExclusiveMode, SafetyMode, NearMode, MyAlias, ErrHand && add whatever you want RestoreOnExit = .T. PROCEDURE Init LPARAMETER tuNoAutoRestore && Optional - allows state object which doesn't AutoRestore state on destruction WITH this =.RecordState() * allow object to not restore on destroy if optional .t. parameter given .RestoreOnExit = IIF(TYPE('tuNoAutoRestore') = 'L',! tuNoAutoRestore, .T.) * public property - it can be altered after init by assignment ENDWITH ENDPROC PROCEDURE RecordState WITH this .ExclusiveMode = SET('EXCLUSIVE') && State of EXCLUSIVE .SafetyMode = SET('SAFETY') && State of SAFETY .NearMode = SET('NEAR') && State of NEAR .ErrHand = ON('Error') && error handler in effect .MyAlias = ALIAS() && Alias selected on entry ENDWITH ENDPROC PROCEDURE Restore && reset state when object first inited && if more settings need to reset, define properties for them && save detail LOCAL cErrHand WITH this IF .ExclusiveMode = 'ON' SET EXCLUSIVE ON ELSE SET EXCLUSIVE OFF ENDIF IF .SafetyMode = 'ON' SET SAFETY ON ELSE SET SAFETY OFF ENDIF IF .NearMode = 'ON' SET NEAR ON ELSE SET NEAR OFF ENDIF IF EMPTY(.MyAlias) OR ! USED(.MyAlias) && Empty work area or alias closed SELECT 0 ELSE SELECT (.MyAlias) ENDIF cErrHand = .ErrHand && can't macroexpand a property, so copy to a local ON ERROR &cErrHand && for macroexpansion ENDWITH ENDPROC PROCEDURE DESTROY IF this.RestoreOnExit this.Restore() ENDIF ENDPROC ENDDEFINE ** If you want to experiment with the class, try: SET PROC TO StateClass SET SAFETY OFF ? 'init',set('safety') oState = createobj('savestate') SET SAFETY ON oState = null ? 'after first',set('safety') oState = createobj('savestate',.t.) SET SAFETY ON oState.Restore() ? 'restore explicit 2nd',set('safe') SET SAFETY ON oState=NULL ? 'last noauto',set('safe')Essentially, whenever you have a state you'd like to preserve, you code:
>>local lOldSetExact >>lOldSetExact=set('exact') >>set exact off >>***** Other code ******* >>if lOldSetExact="ON" >> set exact on && Avoid macro, if possible >>endif >>>