Print Page | Close Window

Checking for changes when closing a form

Printed From: Rocket Software
Category: AccuTerm Knowledge Base (read only)
Forum Name: Code Samples
Forum Description: Share your code samples and discuss the bundled sample programs
URL: https://forum.asent.com/forum_posts.asp?TID=2494
Printed Date: March 26 2026 at 8:51pm
Software Version: Web Wiz Forums 12.03 - http://www.webwizforums.com


Topic: Checking for changes when closing a form
Posted By: Shrek59
Subject: Checking for changes when closing a form
Date 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



Print Page | Close Window

Forum Software by Web Wiz Forums® version 12.03 - http://www.webwizforums.com
Copyright ©2001-2019 Web Wiz Ltd. - https://www.webwiz.net