Calling a GX from a GX

Occasionally it is necessary to call one GX from another, using the iRunGX_SYS function. This can eliminate the need to write additional code, and promotes standardization of methods.

For example, many processes, such as those that import data, may require a new database or ask the user whether or not to overwrite the current database. The following code fragment (from the IMPASC GX) performs this function:

// --- Get OASIS Database ---
 
if (iHaveCurrent_EDB() && iInteractive_SYS()) {
 
if (DisplayQuestion_SYS("Import ASCII","Import data into the current database ?")==0)
   {
      if (iRunGX_SYS("create.gx"))  Cancel_SYS();
   } 
 
} else {
   if (iRunGX_SYS("create.gx")) Cancel_SYS();
}
  
// --- get database ---
  
EData = Current_EDB();
Data = Lock_EDB(EData);

Several important points should be noted:

Databases cannot be doubly locked. If the called GX uses Current_EDB and Lock_EDB to obtain the DB database handle, be sure that the calling GX has freed its own DB handle with a call to Unlock_EDB. For the same reason, it is important that databases always be released after having been locked.

// --- Get database ---
  
Edata = Current_EDB();
Data = Lock_EDB(Edata);
 
// --- Access data using the DB handle "œData" ....
.
.
.
 
// --- Release the database ---
 
UnLock_EDB(Edata);
 
// --- Call the GX ---
 
iRunGX_SYS("œAnotherGX");
 
// --- Lock the database again, and continue ---
 
Data = Lock_EDB(Edata);

The iRunGX_SYS function returns 0 if it completes without an error. If an error occurs, or if the user has “cancelled” out, a value of 1 is returned, and it may be necessary to handle this. The following code queries the database to get the current range of X and Y values, then creates a new map based on the range. If any error occurs, the Cancel_SYS function is called to terminate execution of the GX.

if (iRunGX_SYS("xyrange.gx")) Cancel_SYS();
if (iRunGX_SYS("newmap.gx"))  Cancel_SYS();

Sometimes it is necessary to call a GX non-interactively. In this case it is important that the called GXs parameters have been correctly set before it is called. To call a GX non-interactively, turn off the interactive mode as in the following example:

// --- turn off interactive mode ---
 
SetInteractive_SYS(0);   // 0 - interactive off
 
// --- call a GX non-interactively ---
 
if (iRunGX_SYS("mygx1.gx")) Cancel_SYS();
 
// --- restore interactive mode ---
 
SetInteractive_SYS(1);   // 1 - interactive on
 
// --- call a GX interactively ---
 
if (iRunGX_SYS("mygx2.gx")) Cancel_SYS();

Of course, if this GX were run in batch mode, the SetInteractive_SYS command would have no effect, and both called GXs would be run non-interactively, as would the calling GX.

The following is a brief list of commonly called GXs, the GXs that call them, and a brief explanation of the purpose of the call.

 

Called GX

Example Calling GX

Purpose

CREATE

IMPASC

Create a new database.

RANGEDB

NEWMAP

Determine X, Y range of a database

IMGRANGE

NEWMAP

Determine X, Y range of a grid

DEFMAP

GRIDIMG1

Create a new map with no scale

SCLMAP

POST

Define a scale for a map with no scale

IPJSET

NEWMAP

Set up a map projection