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 |