The AccuTerm forum has moved. Go to community.rocketsoftware.com to register for the new Rocket forum. |
Checking for changes when closing a form |
Post Reply |
Author | |
Shrek59
Senior Member Joined: December 04 2006 Location: New Zealand Status: Offline Points: 208 |
Post Options
Thanks(0)
Posted: April 12 2015 at 5:35pm |
Hi,
At various times, there have been issues raised about the GECLOSE event not triggering validations on forms. What happens then is that the validation runs after the form is closed, and if it fails it crashes the GUI environment by trying to activate a control on the closed form. See for example: http://forum.asent.com/topic2466.html http://forum.asent.com/topic872.html http://forum.asent.com/topic993.html I have now written a subroutine to handle this situation, based on the code in posts 872 and 993. This is shown below (see the notes following the subroutine): SUBROUTINE Q.ATGUI.CHECKCHANGED(ischanged, guierrors, guistate) ***************************************************************************** * Bp.Q Q.Atgui.CheckChanged - Check whether a control has changed data when * leaving a form, and post the validation if required. * * Author : BSS * Created: 13 Apr 2015 * Updated: 13 Apr 2015 * Version: 1.0.0 * * Based on code in the AccuTerm forum: * http://forum.asent.com/topic993.html * http://forum.asent.com/topic872.html * * Use this subroutine in the form close event handler as follows: * * CALL Q.ATGUI.CHECKCHANGED(ischanged, guierrors, guistate) * IF (guierrors<1> GE ERR.FAIL) THEN RETURN TO progexit (or gui error handler) * IF (ischanged) THEN RETURN * * Close the form * * ------------------------------------------------------------------------- * * $INCLUDE GUIBP ATGUIEQUATES EQUATE ERR.FAIL TO 2 ischanged = @FALSE * * Get active control * CALL ATGUIGETPROP(GXROOT, '', '', GPSTATUS, 1, 0, actid, guierrors, guistate) IF (guierrors<1> GE ERR.FAIL) THEN RETURN actapp = OCONV(FIELD(actid, '*', 1), 'MCU') actfrm = OCONV(FIELD(actid, '*', 2), 'MCU') actctl = OCONV(FIELD(actid, '*', 3), 'MCU') * * Has it changed? * CALL ATGUIGETPROP(actapp, actfrm, actctl, GPCHANGED, 0, 0, ischanged, guierrors, guistate) IF (guierrors<1> GE ERR.FAIL) THEN RETURN IF (ischanged) THEN * * Get the event mask and changed value of control * CALL ATGUIGETPROP(actapp, actfrm, actctl, GPEVENTMASK, 0, 0, eventmask, guierrors, guistate) IF (guierrors<1> GE ERR.FAIL) THEN RETURN CALL ATGUIGETPROP(actapp, actfrm, actctl, GPVALUE, 0, 0, avalue, guierrors, guistate) IF (guierrors<1> GE ERR.FAIL) THEN RETURN * * Check event mask for events that we should respond to * eventlist = '' argslist = '' ;* Note: args are LOWER'ed in this list gridrow = '' gridcol = '' CALL Q.GUI.EVENTS.CONVERT('OS', events, eventmask) ;* Convert mask to event names; Sort names. LOCATE 'CHANGE' IN events<1> SETTING epos THEN eventlist<-1> = GECHANGE argslist<-1> = avalue END LOCATE 'VALIDATECELL' IN events<1> SETTING epos THEN CALL ATGUIGETPROP(actapp, actfrm, actctl, GPROW, 0, 0, gridrow, guierrors, guistate) IF (guierrors<1> GE ERR.FAIL) THEN RETURN CALL ATGUIGETPROP(actapp, actfrm, actctl, GPCOLUMN, 0, 0, gridcol, guierrors, guistate) IF (guierrors<1> GE ERR.FAIL) THEN RETURN eventlist<-1> = GEVALIDATECELL argslist<-1> = gridcol:@SM:gridrow:@VM:avalue END LOCATE 'VALIDATEROW' IN events<1> SETTING epos THEN IF (gridrow EQ '') THEN CALL ATGUIGETPROP(actapp, actfrm, actctl, GPROW, 0, 0, gridrow, guierrors, guistate) IF (guierrors<1> GE ERR.FAIL) THEN RETURN END eventlist<-1> = GEVALIDATEROW argslist<-1> = gridrow:@VM:LOWER(avalue) END LOCATE 'DEACTIVATEROW' IN events<1> SETTING epos THEN IF (gridrow EQ '') THEN CALL ATGUIGETPROP(actapp, actfrm, actctl, GPROW, 0, 0, gridrow, guierrors, guistate) IF (guierrors<1> GE ERR.FAIL) THEN RETURN END eventlist<-1> = GEDEACTIVATEROW argslist<-1> = gridrow END LOCATE 'VALIDATE' IN events<1> SETTING epos THEN eventlist<-1> = GEVALIDATE argslist<-1> = @VM:LOWER(avalue) END LOCATE 'DEACTIVATE' IN events<1> SETTING epos THEN eventlist<-1> = GEDEACTIVATE argslist<-1> = '' END * * If we don't need to respond to the event, then set the changed flag to false * IF (eventlist EQ '') THEN ischanged = @FALSE END ELSE * * Otherwise, clear any existing events, and post the new events to the queue * Note: We can't repost the GECLOSE here in case the validation fails and we set up a loop! * CALL ATGUICLEAREVENTS(actapp, '', '', 0, 1, guierrors, guistate) IF (guierrors<1> GE ERR.FAIL) THEN RETURN dce = DCOUNT(eventlist, @AM) FOR eventno = 1 TO dce event = eventlist<eventno> args = RAISE(argslist<eventno>) CALL ATGUIPOSTEVENT(actapp, actfrm, actctl, event, args, -1, guierrors, guistate) IF (guierrors<1> GE ERR.FAIL) THEN RETURN NEXT eventno END END RETURN * * ------------------------------------------------------------------------- * * END Notes: You will need to write your own subroutine to convert the eventmask to a list of events. In this subroutine, this is the call to: Q.GUI.EVENTS.CONVERT This subroutine will need testing in your own situation to make sure it picks up all relevant events - AND TO MAKE SURE THAT THE EVENTS ARE HANDLED IN THE CORRECT ORDER. I hope this helps a few people. Cheers, Brian |
|
Post Reply | |
Tweet
|
Forum Jump | Forum Permissions You cannot post new topics in this forum You cannot reply to topics in this forum You cannot delete your posts in this forum You cannot edit your posts in this forum You cannot create polls in this forum You cannot vote in polls in this forum |