Rocket Software Homepage
Forum Home Forum Home > AccuTerm Knowledge Base (read only) > Code Samples
  New Posts New Posts RSS Feed - Checking for changes when closing a form
  FAQ FAQ  Forum Search   Register Register  Login Login

The AccuTerm forum has moved. Go to community.rocketsoftware.com to register for the new Rocket forum.

Forum LockedChecking for changes when closing a form

 Post Reply Post Reply
Author
Message
Shrek59 View Drop Down
Senior Member
Senior Member


Joined: December 04 2006
Location: New Zealand
Status: Offline
Points: 208
Post Options Post Options   Thanks (0) Thanks(0)   Quote Shrek59 Quote  Post ReplyReply Direct Link To This Post Topic: Checking for changes when closing a form
    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
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.03
Copyright ©2001-2019 Web Wiz Ltd.