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 |