902.3.1
Implement new streamlined statements for retrieving and returning parameters within an SBX routine. Previously this was done exclusively with the XCALL MIAMEX,MX'XCBDATA... routine. Now, you may optionally use any of the following:
XGETARGS ARG1{,ARG2,...{ARGN}}
XGETARG ARGNO,ARG
XPUTARG ARGNO,ARG
XGETARGS retrieves the XCALL arguments into the corresponding variables. (The first argument is returned in ARG1, the second in ARG2, etc.) If more args were passed than you specify variables for, the extra arguments are ignored. Conversely, if you specify more ARG variables in the XGETARGS statement then were passed by the caller, the excess ARG variables are ignored. In either case, the operation is non-destructive to the original argument list, so you can later go back and retrieve (or re-retrieve) parameters using XGETARGS, XGETARG, or the original MIAMEX,MX'XCBDATA statements.
XGETARG ARGNO,ARG performs the same function as XGETARGS except that it retrieves only the one argument (whose number is specified in ARGNO).
XPUTARG ARGNO,ARG is the reverse of XGETARG. It returns the value of the argument ARG into the caller's argument number ARGNO.
Note that in the case XPUTARG, ARG can be a variable or an expression, whereas in the case of XGETARGS or XGETARG, they must be variables. (You can't retrieve an argument into an expression, but you can use an expression to return an argument.)
Type conversions will be made as appropriate if the variable types (P1, P2, etc.) do not match the types passed to the xcall (but it behooves you to use "appropriate" data types for the circumstances).
The following examples may clarify the equivalencies between the new statements and the old MIAMEX calls:
XGETARGS P1,P2,P3,P4
is equivalent to:
xcall MIAMEX,MX'XCBDATA,XCBADR,XCBGET,1,P1
xcall MIAMEX,MX'XCBDATA,XCBADR,XCBGET,2,P2
xcall MIAMEX,MX'XCBDATA,XCBADR,XCBGET,3,P3
xcall MIAMEX,MX'XCBDATA,XCBADR,XCBGET,4,P4
and is also equivalent to:
XGETARG 1,P1
XGETARG 2,P2
XGETARG 3,P3
XGETARG 4,P4
For returning arguments,
xcall MIAMEX,MX'XCBDATA,XCBADR,XCBPUT,1,A+B/C
is equivalent to:
XPUTARG 1,A+B/C
The main advantage of the new statements is just efficiency, both for the programmer and for the computer. (This is especially true if you use XGETARGS to retrieve all arguments in one statement.)
Note that these new statements do not require XCBADR or any of the other variables set up by XCALL.BSI. However, you may still want to continue including XCALL.BSI at the start of your SBX modules since it does set the variable XCBCNT to the number of parameters passed, and the XCBSTRUCT() array to the types and sizes, and this information can be useful in determining how to interpret the passed parameters. (XGETARGS and XGETARG do not give you any obvious indication when fewer parameters were passed to the subroutine than the subroutine is expecting, so a well-written subroutine should, at a minimum, check XCBCNT to see how many parameters were passed.)
You do need to compile with the /X:2 (A-Shell extensions) switch (but this is true for all SBX modules anyway).
902.3.2
When an SBX routine is called and the amount of free memory in the calling partition is more than the SBX minimum (as set in the 2nd argument of the MEMORY= statement in miame.ini, or 360K default), it now takes over all of the free memory in the parent job. Previously it used only the minimum amount. The advantage of the new approach is that if the parent partition is large relative to the amount needed for SBX routines, multiple levels of SBX routines can be called without having to do separate memory allocations.
Previously, if PROG.RUN did an XCALL SUB1.SBX, and it in turn called SUB2.SBX, the SUB2.SBX would always allocate a new work area, regardless of how big the partition of the parent was. (This is mainly a performance issue since there is some overhead with allocating memory. An application which does a lot of nested SBX calls might want to make the main partition large enough to accomodate several levels of subroutines.)
Note that when SBX calls are nested, the amount of memory used up in each level is only the amount actually needed, not the full minimum as specified by the MEMORY= statement. So, for example, if your MIAME.INI has MEMORY=1000K,500K and you call a series of small nested subroutines, you may be able to stack them many levels deep (as opposed to just 2 levels as implied by the ratio of 1000K to 500K).
A new sample SBX/XFUNC function is included to demonstrate this. The SBX is called FACT and it returns the factorial of the argument passed. See the test calling program FACTST.BAS. The algorithm is highly recursive [FACTORIAL(N) = N * FACTORIAL(N-1)], and displays the amount of free memory at each level, allowing your to see that only a few K are used up with each successive level of nesting. Note that it is only practical to run it for numbers up to, say, 32 (i.e. 32 levels deep), since not only do you hit the maximum positive F,6 value about then, but will soon thereafter run out of stack memory.
SBX PERFORMANCE NOTES
As a rough comparison of the performance benefits of these two SBX enhancements (XGETARGS and the improved memory allocation), I ran 500 iterations of FACT(30) (i.e, 15000 subroutine calls, nested from 1 to 30 levels deep). On a 1.7MHz laptop, with the previous method, the elapsed time as about 12 seconds vs. about 2 seconds for the new method, i.e. a six-fold improvement, with the new method doing about 2500 SBX calls per second. At 2500/sec, the overhead of SBX calls is negligible enough to not affect many kinds of operations. (But performing the same logic within a single program using global memory variables is still an order of magnitude faster, so you might not want to use nested SBX functions within a CPU-intensive calculation.)
On another test, I wrote a simple SBX which received a channel # and a string and output the string to the specified print file. I then compared the performance of outputting to the sequential file via the XCALL and directly, i.e.:
XCALL XPRNT,CHANNEL,PLINE
versus
PRINT #CHANNEL,PLINE
This ran about 7K lines per second with the XCALL to XPRNT.SBX, and about 140K lines per second directly. Again, the message is that using an external XCALL is an order of magnitude slower than doing the same thing directly, but, depending on the situation, that may not be significant. (In an application that generates a 1-5 page printout based on user input, it won't make any difference; in an application that generates a 10,000 page report, the difference will be measured in seconds.)
Obviously, the effect of the overhead is progressively reduced as the amount of work done in each iteration of the subroutine is increased. For example, if instead of merely outputting a line of text to a file, our above XPRNT.SBX routine created an entire page, then the total overhead of the SBX call for even a 7000 page report would be only 1 second. Or, a more realistic example would be using a subroutine to format and display a field of data. Since you can hardly squeeze more than 100 or so fields of data on a single screen, the total SBX overhead for displaying the 100 fields on the screen would be a few milliseconds, which is not going to matter in that context.
Considering that performance is no longer a consideration in most interactive business applications, the modularization and reusability benefits of external subroutines combined with their reasonably low overhead, argue for their greater use in A-Shell/Basic software development.
902.2.1
(Windows/ATE) Fix a problem with the behavior of date picker controls when not the active field by converting them to combo box style. Now, you can reactivate the field (and turn it back into a date picker) by clicking on it (either on the edit window or the dropdown button.)
902.2.1
(Windows) Implement a new MIAMEX function (135 or MB'BTNIDLE) to simplify waiting for user to select among a group of buttons using keyboard commands, or click on something which generates an exitcode:
xcall MIAMEX,MX'BTNIDLE,PARENTID,CTLID,EXITCODE{,OP}
parentid
should be set to the control ID of the parent (dialog or groupbox) which owns the buttons you want to wait for. Set to zero if the buttons are part of the main window.
ctlid
should be set to the control ID of the button you want to initially receive the focus. If set to 0, the first button within the group identified by the PARENTID will be given the focus.
exitcode (F,6)
will return an INFLD-standard exitcode indicating how the routine was exited. Typically this would be the exitcode resulting from a mouse-click of a clicked object (whether one of the buttons in the group or some other clickable object.) An EXITCODE of 99 indicates an internal error (button not found, etc.)
op
may optionally contain one or more of the following flags:
1 = Set the focus on the button FOLLOWING the specified CTLID
2 = Set the focus and return (don't wait for an exit code event).
This operation can also be invoked via:
PRINT TAB(-10,33);PARENTID;",";CID;",";OP;chr(127);
(xcall MIAMEX will use this method internally if you run it on a UNIX server with an ATE client.)
902.0.1
(Windows/ATE) Increase the maximize number of GUI objects defined at one time from 400 to 600.
902.0.2
(Windows/ATE) Allow symbol fonts to be used in GUI objects. Normally, when requesting a font, A-Shell asks for the ANSI character set. But this interferes with the ability to select a symbol font, such as Wingdings. To overcome this, you can now add the value 131072 (CHARSET'SYMBOL) to the FONTATTR parameter in MIAMEX,119 or TAB(-10,20) to specify that you want a symbol set font. Note that this probably only makes sense with fonts like "Wingdings", or "Symbol". The font mapper may return an unexpected font if you try this with a font that doesn't contain a symbol set character encoding.
Symbol characters can be useful as a simple way of creating a button containing a graphic symbol. For example, the following statement would create a button with a large (120% size) checkmark in it that acts like the Enter key (%VK_ENTER%):
xcall MIAMEX, 119, 1, BID, chr(252), 0, MBF'KBD, "%VK_ENTER%", "", STATUS, SROW, SCOL, SROW, SROW+1, -1, -1, CHARSET'SYMBOL, 120, "Wingdings"
A new sample program, SYMBOL.BP, displays all of the characters for a specified font. To find out what symbol fonts you have, you can look in the control panel Fonts applet for likely looking names. Or, if you have a word processing program like Word, you can look in in "Insert Symbol" dialog, which typically allows you to select among the available symbol fonts and see what characters are available. (To get the numeric byte values, run the SYMBOL program, specifying the symbol font.) Note that for maximum portability, you should probably stick with just the Wingdings and Symbol fonts, which are almost always installed.
902.0.3
(Windows/ATE) INFLD TYPE |E (to use an edit-style control for the display or redisplay of data when not actively being edited) now arranges to have the cursor change to an arrow when mousing over it. (Edit controls, unlike static controls, do not normally ever use an arrow cursor, so this left users uncertain if the field was clickable.)
902.0.4
(Windows/ATE) Various improvements in the handling of TAB controls when XP Themes are active.
902.0.5
(Windows) Remove a dependency on a function that was not present in W95 (and therefore preventing A-Shell from running at all under W95).
902.0.6
(W2003) Fix a problem which was causing A-Shell to hang on startup under W2003.
902.0.7
Add bits to the second set of global options to disable spooling and INFLD screen capture (^P). These are mapped in ashell.bsi [95] as:
map1 GOP2'NOSPOOL,b,2,16384
map1 GOP2'NOCAPTURE,b,2,32786
They can be queried via:
XCALL MIAMEX,59,options,options2
And set via:
XCALL MIAMEX,60,options,options2
These options might be useful in a security context to prevent the operator from using general tools, such as the ability to print from with EZVUE, or to print the screen using ^P.
For example, to set the NOSPOOL flag:
XCALL MIAMEX,59,OPTIONS,OPTIONS2 ! retrieve option flags
OPTIONS2 = OPTIONS2 OR GOP2'NOSPOOL ! set NOSPOOL flag
XCALL MIAMEX,60,OPTIONS,OPTIONS2 ! set new option flags
The sample program MIAMEX.BAS has been updated (edit [33]) to illustrate these flags.
902.0.8
Add message "003,045,Insufficient privileges to print" to ERRMSG.xxx. This message displays if a spool request is made when the NOSPOOL flag is set.
902.0.9
(Windows/ATE) A new opcode (11) for the MIAMEX,119 or TAB(-10,20) functions allows you to activate a specific tab item (or pane) in a TAB control. To use, just specify the control ID of the TAB control in the ID parameter, and put the desired tab # (starting with 1) in the STATE parameter. For example:
TABNO = 2 ! tab or pane # to activate
TABID = <ID of the tab control>
xcall MIAMEX,119,11,TABID,"",TABNO,MBF'TAB,"","",STATUS,0,0,0,0
902.0.10
TAB Controls may now be placed within dialogs. See the new sample program TABDLG.
902.0.11
The compiler now indicates which variable was unmapped when reporting unmapped variable errors; this is often useful when looking at lengthy statements. It also strips off the leading blanks when reporting the source lines, making the error messages slightly easier to read when they are highly indented.
902.0.12
New compiler switch /MX acts like /M (treat unmapped variables as errors) except that it reports every line in which an unmapped variable appears, even if that variable has already been reported. Note that, as with other errors, typically only the first error on a line is reported. (Otherwise you might get dozens of errors on each line due to the cascading effect.)
902.0.13
New compiler switch /B (for background mode) sends all error messages to <sourcefile>.lst instead of the screen. Format of each message:
<filename>,<line#>,<error message>,<source line>
(You'll need the 1.0(114) version of COMPIL.LIT/OCMPIL.LIT/COMPLP.LIT for the new compiler switches.)
902.0.14
(Windows/ATE) It is no longer necessary to pass a minimum of 13 parameters to MIAMEX,119. For example, when deleting a control by its ID number, there is no need for the coordinates, type, state, etc. (This is mainly just a coding convenience when hard-coding arguments, since it led to argument lists like 0,0,"","",0,0,""...
Also, if you omit the STATUS parameter (#9), or pass it as a string, then the routine does not return the status or control ID. This "feature" is only useful for optimizing the telnet traffic between UNIX servers (particularly AIX) and ATE. (If ATE doesn't need to return anything, the sender can send out commands as fast as the wire will allow; otherwise it needs to wait for a response after each command.)