Developer's Notes [14 May 98]

These notes were written for developers creating applications with the TRIMtools GUI. They focus on the features used in the Chemical Information System and include descriptions of each feature with implementation TRIMpl code.


Features List:

Analytical Balance: Linking to the CIS
Action Buttons: Turning On and Off
Action Buttons: Bitmap labels
Bar Codes
Color: Changing Field Background
Daylight Chemical Systems Interface
Date/Time Manipulations
Debugging Applications
Files: Getting files from Remote and Local Computers
Fonts
Help Windows
Images: Displaying in Browser Windows
Images: Displaying in TRIM windows
Example of a CIS 'ini' file
Installing the CIS
LOV Windows
Popup Menus: Creating & Controlling
Printing Reports: Dynamic HTML
Query from Child Window
Sibling Window: Focus & Control
Stand Alone Trim.pl: trimgen -a / trimrunc

Analytical Balance: Linking to the CIS

Installation of Mettler/Toledo Balance (www.mt.com)

  1. Hardware: Mettler/Toledo College B Balance equipped with LC-B Interface card and LC cable.
  2. Software: TRIMtool driver c:\trifox\bin\scale.exe; TRIMtool application: C:\trifox\cis\balance.gap
  3. Procedure:
    • Assure that path in autoexec.bat includes ' set path=c:\trifox\bin'.
    • Connect LC cable to an available RS232 serial port.
    • Run balance application {Start CIS, Repository Menu, Ship Sample, Action, Balance). Enter port (i.e. COM2), Command (i.e. I4) and Outfile (i.e. c:\trifox\cache\balance.txt) fields and then push the 'Send' button to send your command to the balance. The response from the balance will be displayed in the Results field (i.e. balance serial number). See the Mettler/Toledo Reference Manual Standard Interface Command Set for a list of balance commands and their responses.

Controlling the balance from a GUI application

  1. Weighing Procedure: The weighing process is controlled from the Ship Sample application by selecting the Bottle Number to be weighed and pressing the [Balance] button to run the following script. User control then moves from the computer to the balance. The balance displays 'bottle' on its LCD and the user places an empty bottle on the balance. The balance then displays the quantity of chemical to weigh. After adding this amount to the bottle, the user presses the Tare key again and the weight is automatically sent to the Ship Field of the Ship Sample application.
  2. Command Script: The trigger for the Balance Action Button controls the weighing procedure. This trigger is sends a series of commands to the balance and validates the responses from the balance. After sending each command the trigger validates the corresponding response. If the response is expected, the next command is sent to the balance. If the balance response was not expected, trigger aborts and returns control to the window trigger. The Action Trigger calls balance() and this code is described in item 3.
    {
    char ret[42];
    /* The BALANCE ACTION was designed after the example given on page 70 of
       the "Mettler/Toledo Reference Manual Standard Interface Command Set" */
    
    if (list_curr(p.wl,@p.unit) != "M")    /* Unit must be mg to weigh on balance */
      error("Unit must be 'M' to fetch a balance weight");
    active_field(4);                               /* put cursor on balance field */
    if (balance("@")!="I4 A ")                                 /* reset balance   */
      break;
    if (balance("""K 3""")!="K A") /* disable key function on bal & return key id */
      break;
    if (balance("""D 'BOTTLE'""")!="D A")       /* display 'BOTTLE' on balance LCD*/
      break;
    if (balance("""""") != "K C 3")  /*send balance a NULL & wait for user to tare*/
      break;
    if (balance("T")!="T S  ")                       /* send tare cmnd to balance */
      break;
    if (balance("""D '"                         /* display mg to weigh on bal LCD */
                ^^list_curr(p.wl,@p.QTY)/1000^^"'""")!= "D A")
      break;
    if (balance("""""") != "K C 3")  /*send balance a NULL & wait for user to tare*/
      break;
    if (balance("S")!="S S  ")                  /* get compound weight fm balance */
      break;
    }
  3. BALANCE() is called from the 'Balance' Action Button in Ship.gap It accepts one parameter, the command for the balance, and returns 'FALSE' if the balance executed the command successfully and 'TURE' if the balance failed. BALANCE() displays both error and success messages returned from the balance. A description of the script follows:

    BALANCE() writes a list with three fields:

    • serial port connected to the balance,
    • command for the balance,
    • name of the outfile that will store 'returns' from the balance.

    The balance list is written to TRIMHome\cache\infile.ini. This file is used by the balance driver, TRIMHome\bin\scale.exe, to send data to and from the balance. When the driver receives data from the balance it is it is filed in TRIMHome\cache\outfile.ini. BALANCE() reads outfile.ini to get the data returned from the balance and report it to the user.

    Data returned from the balance is displayed on the status line. It is also checked for its validity using a list containing error codes and error descriptions. If the balance returns an error the current weighing script is aborted. If the balance returns a valid weight it is stored in the window list.

    {
    char response[5];
    list response_list;
    list return_list;
    
    list_mod(g.balance_list,1,"port",g.port);       /* port defined in wrcis.ini  */
    list_mod(g.balance_list,1,"outfile",g.outfile); /*outfile defined in wrcis.ini*/
    list_mod(g.balance_list,1,"command",parm.0);     /* command from weigh action */
    list_file(g.balance_list,"gui!"^^g.cache_dir^^"infile.ini","a");
    
    winexec("scale "^^g.cache_dir^^"infile.ini",1);
    
    return_list= list_open("gui!"^^g.outfile,10);
    response = substr(list_curr(return_list,0),1,5);
    
    if (!response_list){
      response_list= list_open("5 80",6,"Balance Responses: Code & Description");
      list_mod(response_list,1,"D A","Response to the prompted text");
      list_mod(response_list,1,"ES", "Syntax error");
      list_mod(response_list,1,"ET", "Transmission error. The balance has "
                                     "received a 'faulty' command, e.g. "
                                     "a parity error or interface break.");
      list_mod(response_list,1,"EL", "Logical error. Balance "
                                     "can not execute the received command.");
      list_mod(response_list,1,"I4 A ","Balance is reset and ready for operation.");
      list_mod(response_list,1,"K A","Key control command understood and "
                                     "successfully executed.");
      list_mod(response_list,1,"K I","Key control command understood, but "
                                     "not executable at present. Balance may "
                                     "be in menu or input mode.");
      list_mod(response_list,1,"K L","Key control command understood, but "
                                     "command parameter wrong.");
      list_mod(response_list,1,"K C 3","Tare key was pressed briefly, or tare key "
                                     "was released after more than 2 seconds.");
      list_mod(response_list,1,"K R","Tare key was held about 2 seconds. "
                                     "This response repeats every 2 seconds "
                                     "as long as the tare remains pressed.");
      list_mod(response_list,1,"S I","Command not executable. "
                                     "Balance is executing another command "
                                     "(e.g. taring) or stability not reached.");
      list_mod(response_list,1,"S +","Balance in overload range.");
      list_mod(response_list,1,"S -","Balance in underload range.");
      list_mod(response_list,1,"T I","Taring not performed. Balance is currently "
                                     "executing another command (e.g. zero "
                                     "setting) or unable to stabilize.");
      list_mod(response_list,1,"T +","Upper limit of taring range exceeded.");
      list_mod(response_list,1,"T -","Lower limit of taring range exceeded.");
    }
    if(response == "S S  "){
      bell();
      status("Balance returned a stable weight of "
             ^^translate(substr(list_curr(return_list,0),5)," ","")^^".");
      field= 1000*(to_number(substr(list_curr(return_list,0),5,10)));
      g.modified=true;
      }
    else if(response == "T S  "){
      bell();
      status("Balance is tared and has a value of "
             ^^translate(substr(list_curr(return_list,0),5)," ","")^^
             " in tare memory.");
      }
    else if (list_find(response_list,0,response)){
        bell(); bell();
        status("Balance returned '"^^list_curr(response_list,0)^^"': "
               ^^list_curr(response_list,1) );
        field= NULL;
        g.modified=true;
      }
    else{
      bell(); bell();
      status("Balance returned "^^list_curr(return_list,0));
      field      = NULL;
      g.modified = true;
      }
    return_list    = NULL;
    g.balance_list = NULL;
    delete("gui!"^^g.outfile);
    return(response);
    }
    

Bar Codes

WindowBar V4 software can be called from GUI applications to print bar code labels. The following description should be used with the WindowBar manual to configure the bar code software.

  1. Installation :
    • Install the WindowBar V4 software including the printer driver (WR has a Zebra Printer?) and configure the com port using the WindowBar User's Manual Version 4.1, pp. 5-8/9.
    • Place the WindowBar Security Key between the printer port and the printer cable. WindowBar will only run in Demo mode if the key is not installed. Note that there are two Security Keys, a Print Key and a Standard Key- try both to determine which one is required. See the WindowBar User's Manual Version 4.1, pp. 1-4/5 & 6-3/4, for help on the Security Keys.
    • Set the environmental parameter 'bar_code' in TRIMhome\wrcis.ini to '1'.
  2. Labels are designed in the WindowBar designer program and stored in c:\Winbar4x\Labels\ directory. Walter Reed currently uses two label programs:
    • bn1make.lab: This label is used on bottles containing samples being accessioned into the CIS. Currently this label program prompts the user to enter the BN. It must be modified by removing the prompts and taking the BN variables as a parameters from the batch file that is generated by the [Bar Code] Action Button in the Accession Sample Application. The bn1make.lab file is included at the end of this description on bar codes.
    • wrbship2.lab: This label is used on bottles for shipments to Test Systems. Currently this label program prompts the user to enter the BN, Test System, and Milligrams. This program must also be modified to remove the prompts and to take these variables as parameters from the batch file coded in the trigger associated with the [Bar Code] Action Button in the Ship Sample Application. The wrbship2.lab file is included at the end of this description on bar codes.
  3. Batch files are used to select the label program and pass it parameters (WindowBar User's Manual Version 4.1, pp. 1-4, 5-11/12). Batch files are created in the GUI application triggers associated with the [Bar Code] Action buttons. Currently the CIS writes two batch files:
    • The [Bar Code] Button in the Accession Sample Application executes the following code to write the following batch file called new_bn.bat. When run this batch file calls the bn1make.lab program and passes it a Bottle Number as a parameter.
      {
      list barcode;
      
      if (!to_int(g.bar_code))        /* g.bar_code is environ var set in wrcis.ini */
        error("Bar Code program is not installed on this computer.");
      else if (!p.bn_d)               /* BN must be displayed to print a bar code   */
        error("Enter BN field before printing bar code");
      else{
        barcode= list_open("80",9,"Ship BarCode list");
        list_mod(barcode,1,"[LABEL]");
        list_mod(barcode,1,"Label=C:\WINBAR3X\LABELS\BN1MAKE.LAB");
        list_mod(barcode,1,"Port=COM3:");
        list_mod(barcode,1,"Quantity=1");
        list_mod(barcode,1,"P-BN="^^p.bn_d);
        list_mod(barcode,1,"P-NAME=WindowBar AutoPrint");
        list_file(barcode,"gui!c:\winbar4X\batch\new_bn.bat","a");
        status("Created file c:\winbar4X\batch\new_bn.bat");
        }
      }
      
    • The [Bar Code] Button in the Ship Sample Application executes the following code to write a batch file called ship_bn.bat. When run, this batch file calls the wrbship2.lab program and passes it three parameters, Bottle Number, Test System, and Milligrams.
    {
    list barcode;
    
    if (!to_int(g.bar_code))        /* g.bar_code is environ var set in wrcis.ini */
      error("Bar Code program is not installed on this computer.");
    else if (!p.bn_d)               /* BN must be displayed to print a bar code   */
      error("Enter BN field before printing bar code");
    else{
      barcode= list_open("80",9,"Ship BarCode list");
      list_mod(barcode,1,"[LABEL]");
      list_mod(barcode,1,"Label=C:\WINBAR3X\LABELS\WRBSHIP2.LAB");
      list_mod(barcode,1,"Port=COM3:");
      list_mod(barcode,1,"Quantity=1");
      list_mod(barcode,1,"P-BN="^^p.bn_d);
      list_mod(barcode,1,"P-TS="^^p.test_d);
      list_mod(barcode,1,"P-MG="^^p.ship_qty_d^^" M");
      list_mod(barcode,1,"P-NAME=WindowBar AutoPrint");
      list_file(barcode,"c:\winbar4X\batch\ship_bn.bat","a");
      status("Created file c:\winbar4X\batch\new_bn.bat");
      }
    }
    
  4. AutoPrint is a WindowBar utility that runs as a background process and controls label printing (WindowBar User's Manual Version 4.1, Chapter 5). Start Autoprint by pressing the WBatch.exe icon and open Setup from the Menu Bar. Use the manual as a guide to configure Program Setup, Batch Setup and Port Setup. Batch Setup is used to enter the names of the batch files to be read, the interval to look for new batch files, and the path to the log directory.
  5. Running WindowBar V4.1:
    • Turn on the printer.
    • Start AutoPrint by pressing the WBbatch.exe icon.
    • Open the Ship Sample Application, select data, select the appropriate row and press the [Bar Code] button.
  6. How It Works:
    • The action trigger associated with the [Bar Code] button in the GUI Application reads the parameters from the GUI display (i.e. bottle number etc) and writes a batch file called c:\winbar4x\batch\*.bat.
    • AutoPrint looks in C:\Winbar4x\Batch for new batch files at frequent intervals set by the user. If found, the batch file is opened and read.
    • AutoPrint performs four actions:
      • Prints the label.
      • Copies c:\winbar4X\batch\bn.bat to c:\winbar4X\log\bn.bat. Thus a log of the batch files run is maintained.
      • Erases c:\winbar4X\batch\bn.bat from the batch directory so that AutoPrint will not find it and print it again.
      • If an error occurs, a message written to c:\winbar4x\log\sample.err. See WindowBar User's Manual Version 4.1, pp. 5-13/14, for a list of errors.
  7. bn1make.lab: program to print a bar code label for a new sample to be stored in the repository. This program was designed with prompts for the user to enter data. I think that the '[PROMPT]' and 'STATEMENT= ' commands need be removed to run this label program from a batch file.
    [PARAMETER]
    PGM_UNITS=INCHES
    CLASS=ZEBRA
    PRINTER=Zebra 105
    ORG=0,0
    DB_CLASS=Vista
    DB_PATH=
    DENSITY=8 dots/mm
    DOTS_MMX=8.00000
    DOTS_MMY=8.00000
    DOTS_INCHX=203.20000
    DOTS_INCHY=203.20000
    DESC=PRINTS ONE BOTTLE LABEL
    LABELSIZE=305,114
    SIZE=305,114
    EXTENT=305,114
    LABEL_OFFSET=0,6
    CUTTER_ENABLE=N
    CUTTER_QTY=0
    DARKNESS=60
    CUTTER_PAUSE_OVERRIDE=N
    PRINTSPEED= 51 mm/sec
    MODE=Tear Off
    LABEL_ROTATION=0   degrees
    CLEAR_PRINTER=N
    MIRROR=N
    REVERSE=N
    BACKFEED=N
    DIRECT_THERMAL=N
    CONTINUOUS=N
    SEQREPEAT_QTY=2
    SLEW_DOTS=0
    STOCK=C:\WINBAR3X\STOCKS\BTLB2UP.STK
    MAX_BITMAPS=6
    DB_EXT=
    [BARCODE]
    ORG=35,11
    SYMBOLOGY=CODE 39
    RATIO=2:1
    HEIGHT=69
    OBJ_ROTATION=0   degrees
    XDEM=2
    GUIDE=Y
    INTERP_SIZE=12,17
    INTERP_OFFSET=5
    INTERP_STARTSTOP=Y
    BC_X_OFFBEF=0
    BC_X_OFFAFT=0
    INTERPRETATION=BELOW
    PACK=
    CHECKSUM=0
    START_CHAR=
    STOP_CHAR=
    SERIALIZED=N
    LEADING_ZEROS=N
    INC/DEC=INC
    STEP=1
    VARIABLE_NAME=P-BN
    DATA=BN12345
    EXTENT=232,89
    [END_OBJS]
    [PROMPT]
    STATEMENT=Enter Bottle Number to Print
    NAME=P-BN
    MAX_LENGTH=7
    DATA_TYPE=STRING
    [END_VARS]
    
  8. Wrbship2.lab: program to print a bar code label for a sample to be shipped to a test system. This program was designed with prompts for the user to enter data. I think that the three '[PROMPT]' and 'STATEMENT= ' commands need be removed to run this label program from a batch file.
    [PARAMETER]
    PGM_UNITS=INCHES
    CLASS=ZEBRA
    PRINTER=Zebra 105
    ORG=0,0
    DB_CLASS=Vista
    DB_PATH=c:\winbar3x\data
    DENSITY=8 dots/mm
    DOTS_MMX=8.00000
    DOTS_MMY=8.00000
    DOTS_INCHX=203.20000
    DOTS_INCHY=203.20000
    DESC=
    LABELSIZE=256,272
    SIZE=256,272
    EXTENT=256,272
    LABEL_OFFSET=0,16
    CUTTER_ENABLE=N
    CUTTER_QTY=0
    CUTTER_PAUSE_OVERRIDE=N
    PRINTSPEED= 76 mm/sec
    LABEL_ROTATION=0   degrees
    CLEAR_PRINTER=N
    MIRROR=N
    REVERSE=N
    BACKFEED=N
    CONTINUOUS=N
    SEQREPEAT_QTY=0
    SLEW_DOTS=0
    STOCK=
    MAX_BITMAPS=6
    DARKNESS=30
    MODE=Tear Off
    DIRECT_THERMAL=N
    [BARCODE]
    ORG=5,35
    SYMBOLOGY=CODE 39
    RATIO=2:1
    HEIGHT=51
    OBJ_ROTATION=90  degrees
    XDEM=2
    GUIDE=Y
    INTERP_SIZE=12,17
    INTERP_OFFSET=5
    INTERP_STARTSTOP=Y
    BC_X_OFFBEF=0
    BC_X_OFFAFT=0
    INTERPRETATION=ABOVE
    PACK=
    CHECKSUM=0
    START_CHAR=
    STOP_CHAR=
    SERIALIZED=N
    LEADING_ZEROS=N
    INC/DEC=INC
    STEP=1
    VARIABLE_NAME=P-BN
    DATA=BM12345
    EXTENT=232,71
    [BARCODE]
    ORG=181,46
    SYMBOLOGY=CODE 39
    RATIO=2:1
    HEIGHT=51
    OBJ_ROTATION=270 degrees
    XDEM=2
    GUIDE=Y
    INTERP_SIZE=12,17
    INTERP_OFFSET=5
    INTERP_STARTSTOP=Y
    BC_X_OFFBEF=0
    BC_X_OFFAFT=0
    INTERPRETATION=ABOVE
    PACK=
    CHECKSUM=0
    START_CHAR=
    STOP_CHAR=
    SERIALIZED=N
    LEADING_ZEROS=N
    INC/DEC=INC
    STEP=1
    VARIABLE_NAME=P-MG
    DATA=1234M
    EXTENT=180,71
    GROUPED=
    [TEXT]
    ORG=39,4
    FONT=Smooth Font
    FONT_SIZE=21,26
    FONT_MULT=1,1
    OBJ_ROTATION=0   degrees
    OBJ_CHARSET=USA - 1
    REVERSE=N
    SERIALIZED=N
    LEADING_ZEROS=N
    INC/DEC=INC
    STEP=1
    VARIABLE_NAME=CONST Field
    DATA=WRAIR
    EXTENT=57,26
    [TEXT]
    ORG=67,242
    FONT=Smooth Font
    FONT_SIZE=19,26
    FONT_MULT=1,1
    OBJ_ROTATION=0   degrees
    OBJ_CHARSET=USA - 1
    REVERSE=N
    SERIALIZED=N
    LEADING_ZEROS=N
    INC/DEC=INC
    STEP=1
    VARIABLE_NAME=CONST Field
    DATA=Test System:
    EXTENT=95,26
    GROUPED=
    [TEXT]
    ORG=176,243
    FONT=Smooth Font
    FONT_SIZE=19,26
    FONT_MULT=1,1
    OBJ_ROTATION=0   degrees
    OBJ_CHARSET=USA - 1
    REVERSE=N
    SERIALIZED=N
    LEADING_ZEROS=N
    INC/DEC=INC
    STEP=1
    VARIABLE_NAME=P-TS
    DATA=TS
    EXTENT=19,26
    GROUPED=
    [TEXT]
    ORG=158,3
    FONT=Smooth Font
    FONT_SIZE=14,26
    FONT_MULT=1,1
    OBJ_ROTATION=0   degrees
    OBJ_CHARSET=USA - 1
    REVERSE=N
    SERIALIZED=N
    LEADING_ZEROS=N
    INC/DEC=INC
    STEP=1
    VARIABLE_NAME=F-MONTH
    DATA=October 10. 1994
    EXTENT=89,26
    GROUPED=
    [TEXT]
    ORG=100,27
    FONT=Smooth Font
    FONT_SIZE=17,22
    FONT_MULT=1,1
    OBJ_ROTATION=270 degrees
    OBJ_CHARSET=USA - 1
    REVERSE=N
    SERIALIZED=N
    LEADING_ZEROS=N
    INC/DEC=INC
    STEP=1
    VARIABLE_NAME=CONST Field
    DATA=JOHN_NOTSCH@WRSMTP-
    EXTENT=178,22
    GROUPED=
    [TEXT]
    ORG=136,67
    FONT=Smooth Font
    FONT_SIZE=17,22
    FONT_MULT=1,1
    OBJ_ROTATION=270 degrees
    OBJ_CHARSET=USA - 1
    REVERSE=N
    SERIALIZED=N
    LEADING_ZEROS=N
    INC/DEC=INC
    STEP=1
    VARIABLE_NAME=CONST Field
    DATA=CCMAIL.ARMY.MIL
    EXTENT=123,22
    GROUPED=
    [END_OBJS]
    [PROMPT]
    STATEMENT=Enter Bottle Number:
    NAME=P-BN
    MAX_LENGTH=7
    DATA_TYPE=STRING
    [PROMPT]
    STATEMENT=Enter Test System:
    NAME=P-TS
    MAX_LENGTH=2
    DATA_TYPE=STRING
    [PROMPT]
    STATEMENT=Enter Sample Weight
    NAME=P-MG
    MAX_LENGTH=7
    DATA_TYPE=STRING
    [FORMAT]
    STATEMENT=
    MAX_LENGTH=9
    NAME=F-DATE
    DATA_TYPE=STRING
    [FORMAT]
    STATEMENT=" "", "
    MAX_LENGTH=18
    NAME=F-MONTH
    DATA_TYPE=STRING
    [END_VARS]
    

Action Buttons: Turning On and Off


Action Buttons: Bitmap Labels

To display an image on an action button, follow these steps:
  1. Create a bitmap label using drawing software such as paint.exe. First size the image file to the size of the button (i.e. 17 X 17 pels), zoom the image from 400% to 800%, and, perhaps, toggle grid on. Draw the image and outline the edge of the button with a black perimeter. Save the image in bitmap format to TRIMhome\cis (i.e. uparrow.bmp).
  2. Create an action button by right clicking the application canvas to display a drop down menu. Select Create and then 'Action'. In the Define Action dialogue, name the button, define the height and width of the button (i.e. 1 X 2), and check the Bit Map box.
  3. Open the window trigger and place the following code near the top so that the image appears as the window opens:

    file_copy("uparrow.bmp","gui!image:sortup.bmp");

    Note that the name of the source file, 'uparrow.bmp', doesn't matter. However, the name of the target file, 'sortup.bmp', must match the name of the Action Button. In this example, the Action Button must be named 'sortup'. Note that the extension is not kept as part of the name of the Action Button.
  4. Run the application.
  5. To remove an image simply use delete(). For example:

    delete("gui!image:sortup.bmp");

    The extension is optional and if specified it is ignored.

How it works:
A list of all loaded images are kept in GUIslave. This is the dynamic image area. The resources compiled into the .exe file is the static image area. When a bitmap is needed (Buttons or graphic lists) the dynamic area is searched first. This mean that you can override a built in bitmap with a dynamically loaded one.

Color: Changing Field Background


Date/Time Manipulations

TRIMpl stores the date and timestamp by default. However, the prompt and printf commands print date, but not timestamp, by default. Prompt/printf can be forced to display the date and timestamp using the following mask:

prompt("Print timestamp: " ^^to_char(dt,"DD-MON-YY HH:MI:SS") );

Care must be taken to determine if the timestamp is needed or if it should be set to zero. This decision is based on the:
  1. database datatype:
  2. intended use of the select statement:
  3. TRIMpl lock_row() function:
{
/* datetime.pl, an example of date manipulation.*/

datetime dt;

dt= SYSDATE;
prompt("dt with timestamp   : "
       ^^to_char(dt,"DD-MON-YY HH:MI:SS") );
/* Prints: dt with timestamp   : 08-DEC-97 10:26:08 */

dt= to_date(to_char(SYSDATE,"DD-MON-YY") );
prompt("dt without timestamp: "
       ^^to_char(dt,"DD-MON-YY HH:MI:SS"));
/* Prints: dt without timestamp: 08-DEC-97 00:00:00 */

dt= to_date(SYSDATE,"DD-MON-YY");
prompt("dt without timestamp: "
       ^^to_char(dt,"DD-MON-YY HH:MI:SS")^^" ?????");
/* Prints: dt without timestamp: 08-DEC-97 10:27:01 ??????*/

}

Daylight Interface

  1. Displaying Single Images in TRIM windows
  2. Displaying Multiple Images in browser windows [Deleting duplicate SMILES; Managing Dot.Disconnects]
  3. Daylight CGI: Depicting SMILES, GRINS, Similarity Searches
  4. Structure/Activity Analyses (merging biology data in wl with chem data from DAYcgi)

Data Dictionary

  1. Creating and managing data base tables
  2. Storing and retrieving field definitions

Debugging Applications

  1. Gui Debugger
  2. Vortex logging
    • set VORTEX_API_LOGFILE=filename
    • set VORTEX_API_LOGOPTS=FULL

Fonts: Changing Fonts

Winprop() can be used to change fonts in a window.

  1. To give the user the capability of changing fonts, display a window in the developer, and create a child item called 'Font' under File on the menu bar. Make the Fonts trigger a single call: 'winprop(deffile)'.
  2. To modify fonts run the application and click 'File/Fonts' on the menu bar to open the Window Defaults dialog box. Experiment with the several available fonts and change their size. Changes to the fonts and sizes are displayed immediatly in the running application.
  3. Save the new font to file with a '.vgd' suffix.
  4. To apply the new font to all applications run as thin clients, add the following line to the c:\trifox\lib\guicis.ini file:
    default_file             c:\trifox\lib\wrcis.vgd
    
    Finally, call guicis.ini from the command line:
    C:\TRIFOX\bin\gcmnod32.exe -ic:\trifox\lib\guicis.ini
    
  5. To apply the new font to all applications run as fat clients, use the GUI_DEFAULT_FILE environment variable in wrcis.ini and set it to the '.vgd' file ( GUI_DEFAULT_FILE=d:\wrcis\pade.vgd ).
  6. To change the font for each window run either fat or thin, call winprop(deffile) with the vgd filename. The call could be made at the top of the window triger. Put the '.vgd' file on the server in TRIMhome/cis and use the get_file() function to copy it to the client. (i.e. winprop(getfile("etcis",g.cis_dir,"ship.vgd","a",""));

Help on Application Fields

Field help is displayed by creating help keys and popup menu items, calling field triggers, formatting the 'help text' into lists, and displaying the lists. The following example is used to tell the user that there are two methods of shipping a chemical sample.
  1. Creating help keys, menus and popups to set g.keys.....
    • To create a help key the following lines must be added to *.kma ...
    • To create a help item in a popup menu ...
  2. Calling the field trigger:
      else {                                    /* normal mode                    */
        input(G.input_var);
        ...
        if (G.key == key_f1) ...
        else if (G.key == key_f2)...
        else if ...
        else if (G.key in (key_help,key_lov)){
          key_exec(G.key);
          }
        else if ...
          }
        }                                       /* normal mode                    */
    
  3. Formatting 'help text' into lists and displaying a 'help window':
    {
    trigger help= {
      list mail_lst;
      mail_lst= list_open("27",3, "Ship: Shipment Priority");
      list_mod(mail_lst,1,"R: Routine, 1 week delivery");
      list_mod(mail_lst,1,"E: Express, 1 day delivery");
      list_mod(mail_lst,1,"Format: C | LOV: [F11]");
      list_view3(mail_lst,-1,-1,-1,key_f3,opt_highlight,0);
      mail_lst= NULL;
      };
    ;
    }
    

Images: Displaying in TRIM windows


Images: Displaying in TRIM windows

An image canvas can be created in a window with other alphanumeric fields, or in a separate window that displays only the bitmap. The image canvas is actually a Graphics List which can be created by following these steps. This example displays a chemical structure in a separate TRIM window which changes each time the current SMILES in the calling window changes.
  1. Create a sibling window called structure and display it in the GUI developer. Right click the spot for the location of the new image. From the drop down menu, select 'Create' and then 'List' to get the 'Define List' Dialog Box. Complete the Dialog Box by entering the name of the list, setting the size of the image canvas, choosing List Type Graphics and clicking OK.
  2. Assign *.bmp file to the variable 'theimage.bmp' and create a list. This might be done in a user trigger as follows:
    {
    /* STRUCTURE() creates a Graphic List */
    list ll;
    file_copy("c:\trifox\cache\228277b.bmp","gui!image:theimage.bmp");
    ll = list_open("60",1);
    list_mod(ll,1,"0 8   0   0 9999 9999 THEIMAGE");
    return(ll);
    }
    
    The space delimited string "0 8 0 0 9999 9999 THEIMAGE" defines the chracteristics of the image canvas and reading left to right:
    • 0 is the window ID
    • 8 defines the list as Type Graphics
    • 0 is width of image*
    • 0 is height of image*
    • 9999 is the 'x' position of the canvas
    • 9999 is the 'y' position of the canvas
    • 'THEIMAGE' is the filename of the bitmap image
    • *If width & height are 0, the area of the bmp equals that of the bitmap file itself.

  3. Control the structure window from the SMILES field of the calling window using this code.
    ...
    struct.structure = structure();  /* create graphics list;assign it to struct.structure */
    window(struct,open);
    list_view2(struct.structure,-1,-1,-1,0);
    
    Finally, set the user attributes in the SMILES field of the calling window to 'Calculate' (right click SMILES field to get Define Field Dialogue, click Attributes and select Calculate). With 'Calculate' on the field trigger for SMILES will be executed and the structure for the new SMILES will be displayed.

Example of a CIS 'ini' file

# INI files list the environmental variables used by the CIS.
# Note that spaces (not tabs) are used as delimiters between 
# env vars and their values and that comments begin with #.
# You must edit the ip addresses, paths, filenames, usernames
# and passwords to fit the configuration of your client.

#Configuration
server_os   0                       #nt=0, unix=1, vms=2
client_os   0                       #nt/95=0, un=1, s8=3; 3.1=9
trim_config 0                       #fat=0,thin=1,java=2

#Paths to helper applications on client
acrobat    c:\Acrobat3\Reader\AcroRd32.exe
browser    c:\Program Files\NETSCAPE\Communicator\PROGRAM\netscape.exe 
chemdraw   c:\chemoffice\chemdraw\chemdraw.exe   #Delete path if not installed
excel      c:\Program Files\Microsoft Office\Office\EXCEL.EXE
raswin_dir c:\raswin\

#HTML help 
ras_manual http://www.umass.edu/microbio/rasmol/distrib/rasman.htm  #URL to Rasmol manual
trim_help  http://www.trifox.com/trimpl/index.html         # URL to Trim functions
da_help    http://xxx.xxx.xxx.xxx/dapl/index.html          # URL to DataAspects functions
devnotes   http://xxx.xxx.xxx.xxx/devnotes/devnotes.html   # URL to DataAspects functions
chemnet    http://xxx.xxx.xxx.xxx/chemnet.html             # URL to DataAspects functions

# Thin Client configuration with all help & reference files on application server
#widgets_dir  /usr2/trim/widgets/    # path to widget gif files
#cache_dir    gui!c:\daspects\cache\ # save helper files on client: pdf,dynamic html,pdb
#path         c:\daspects\cache\     # same as cache_dir, but w/o 'gui!'
#cis_dir      /usr2/trim/cis/        # path to application run files
#help_dir     /usr2/trim/help/       # path HTML help on applications
#user_dir     /usr2/trim             # user hit lists; username appended in main.trg

# Fat Client configuration with all help & reference files on client.
# Note: Do not preceed the path with gui!
widgets_dir  c:\trifox\widgets\       # path to widget gif files
cache_dir    c:\trifox\cache\         # prepend 'GUI!' in thin client athena.ini
path         c:\trifox\cache\         # path to cache for both thin & fat client
cis_dir      c:\trifox\cis\           # path to CIS run files
help_dir     c:\trifox\help\          # path to help files
user_dir     c:\trifox\cojo           # user hit lists; username appended in main.trg

# CISSERVER:  Connection to biology/inventory database
# Oracle db from outside firewall
cisserver  net:username/password@1958:xxx.xxx.xxx.xxx!/usr2/trim/bin/vtxhost.net,TRIM_HOME=/usr2/trim@@1958:xxx.xxx.xxx.xxx(%AUTH%)!/usr2/trim/bin/vtxhost.ora,ORACLE_HOME=/usr4/oracle,ORACLE_SID=A
# Oracle db from inside firewall
# cisserver  net:username/password@1958:xxx.xxx.xxx.xxx(%AUTH%)!/usr2/trim/bin/vtxhost.ora,ORACLE_HOME=/usr4/oracle,ORACLE_SID=A

# APPSERVER:  Connection to the application server
appserver net:moose@xxx.xxx.xxx.xxx(%AUTH%)!/usr2/trim/bin/vtxhost.fcp

# IMAGESERVER:  Connection to the image server
#imageserver  net:sql$database@1958:xxx.xxx.xxx.xxx(username/password)!d::\trifox\bin\vtxfcp

# CHEMSERVER:  Connection to the Daylight server
chemserver    http://www.daylight.com/   #Daylight
# chemserver  http://xxx.xxx.xxx.xxx/    #My DAYcgi

# Parameters for Daylight databases
day_parms  &datatype=SMI&dbname=cis&dbpw=cheminfo&uname=dayuser&upw=cheminfo

# Parameters for installing Mettler Balance  
balance  1            # Balance: not installed= 0;  installed= 1
port     com2         # Com port (com1, com2, com3, etc)
baud     9600         # Baud rate for com port (2400, 4800, 9600, etc)
parity   2            # Parity (0= no parity; 1= odd; 2= even; 3= mark; 4= space)
bits     8            # bits per byte (4,5,6,7, or 8)
flow     0            # flow control (0= hardware (DTR/CTS); 1= Xon/Xoff)
outfile  c:\daspects\cache\fm_bal.txt         # stores data returned from balance 
}

Installing the CIS

The TRIMtools GUI can be configured as either a thin client or a fat client. Thin client means that the client PC is used simply as a presentation manager. In this mode, only three or four files that consume around 100kb of disk space are stored on the client PC while the remaining TRIMtoos and CIS applications are stored on the server.

In contrast, fat clients have all TRIMtools and/or all CIS applications on the client. Fat clients can be configured in two ways to either create an environment for the software developer or for the end user. For developers, all TRIMtools and CIS applications are installed on the PC making a very fat client. For the end user, the installation of MIR files (Machine Independent Run files) reduces the number of files to the CIS applications to simplify installation and maintenance.

Each configuration has its advantages and disadvantages. Since thin clients get most of their information from the server, display refresh rates are vulnerable to network and modem baud rates. On the other hand, fat clients get most of their data from the local hard drive except when interacting with the database server. From a CIS management point of view, thin clients are preferable because there is only one copy of each application located on the server which simplifies version updates. Conversely, each fat client stores all CIS applications and new version must be copied onto the hard drive of each client. In summary, deploy thin clients when network transmission rates refresh screen displays at an acceptable speed. Deploy fat clients on remote computers operating over slow networks and modems.

These instructions focus on the following installation topics:

Downloading TRIMtools
Helper Programs
TRIMhome Directory
Thin Client for End Users
Java Client for End Users
Fat Client for End Users
Fat Client for Developers
Additional information on the Installation of TRIMtools is presented on the Trifox Home Page.

  • Downloading TRIMtools

    1. cd c:\trifox\bin
    2. ftp ftp.trifox.com
    3. username
    4. password
    5. cd /products/nt
    6. binary
    7. get 'filename'.exe

  • Helper Programs

    These instructions assume that the following software has been already been installed on the server and/or client computers:

    1. VORTEXchannel ???
    2. Netscape Navigator 4.xx to read dynamic HTML and integrate the CIS with the Daylight CGI and the World Wide Web runs on the client..
    3. Adobe Acrobat Reader to read pdf files stored in the CIS database and downloaded from the World Wide Web runs on the client.
    4. Daylight Chemical Information System to manage the chemical database runs on the CIS server.
    5. RasMol to display chemical structues in 3d runs on the client.

  • TRIMhome

  • Thin Client for End Users (=GUIslave)

      Files on CIS Server
      Directory
      Files
      [prod.trifox.prod] accession.gap, balance.gap, merck.gap, track.gap, request.gap, ship.gap, start.gap
      [prod.trifox.cis] accession.run, balance,merck.run, track.run, request.run. ship.run, start.run,
      biotable.txt, merckwr.txt, pdwr.txt, stectwr.txt, trsmalwr.txt, trsradwr.txt
      [prod.trifox.help] aboutcis.htm, chemnet.htm, devnotes.htm, gaphelp.htm, support.htm
      [TRIMhome.lib] gui.fnc, import.h, net.ini
      Note: To compile on the server, execute the following commands from the command line: 'trimgen *.gap -u -s -o'. Then copy the resulting run files to the CIS directory: 'copy [prod.trifox.prod]*.run [prod.trifox.cis]*.run'.

      CIS Files & Directories on Thin Client
      Directory
      Files
      c:\trifox\bin gcmnod32.exe (32 bit client),
      gcmnode.exe (16 bit client),gcvt.exe
      c:\trifox\bmp blank.bmp,dnarrow.bmp,uparrow.bmp
      c:\trifox\cache stores temporary files downloaded from server
      c:\trifox\lib anthena.ini,gui.ini,guicis.ini,wrcis.vgd
      c:\trifox\lists stores lists of structures created by user
      c:\trifox\queries stores extended queries created by user
      c:\trifox\ship stores shipping documents created by user
      c:\trifox\spreadsheets stores delimited files created by user

    1. Configuring c:\trifox\lib\guicis.ini: The variables and values in guicis.ini are read by gcmnode32.exe and used to connect the thin client (=guislave) to the application server. To set the variables in guicis.ini for the local client open it with a text editor (i.e. Notepad).

      Note that the ip addresses used in guicis.ini differ according to the location of the client relative to the WRAIR firewall.

      • If the client is outside the firewall, use the outside address, 141.236.12.10, in gui.ini to penetrate the firewall, connect to etcis, and run the opening CIS application. The first window in the CIS connects the client to the database and since this application is running inside the firewall, it requires an inside address, 141.236.20.10.
      • If the client is located inside the WRAIR firewall then all addresses are inside addresses, 141.236.20.10.

      Also note that port 1958 is used for the DBMS server for fat client and that port 1959 is used for the GUI server for thin client.

      The following guicis.ini is set to run a thin client outside the WRAIR firewall.

      rem ---------- Trifox Virtual GUI Specifics for Thin Client Connection to WRAIR
      env_vars          TRIM_HOME=dka0:[trim],WRCIS.INI=gui!c:\trifox\lib\wrcis.ini
      hostname          141.236.12.10                   --Thin client outside firewall
      !hostname         141.236.20.10                   --Thin client inside firewall
      working_directory dka0:[prod.trifox.cis]          --ETCIS Server
      program           dka0:[prod.trifox.cis]start.run --opening program
      parameters        start                           --start.run opening application
      packetsize        4096                            --network packet (send/recv)
      port              1959                            --THIN CLIENT guiserver daemon port
      default_file      c:\trifox\lib\wrcis.vgd         --font file
      
    2. Configuring c:\trifox\wrcis.ini: The wrcis.ini file is used to assign environmental variables on the thin client. When the CIS is started this file is read by a user function called get_parms() and the variable names with their corresponding values are stored in memory. The environmental variables are used to fit the CIS to the unique configuration of each client. To configure wrcis.ini open it with a text editor (i.e. Notepad) and set the variables. An example of the wrcis.ini file with typical settings follow:

      An example of a WRCIS.INI file follows.

      !WRCIS.INI lists the environmental variables used by the CIS.
      !Note that the following variables and their corresponding values 
      !must be separated with 'spaces' not 'tabs' and that an exclamation 
      !mark is used to 'comment out' a line.
      
      platform    nt     !Client Operating system: nt, 95, 31
      client      thin    !Client =  fat, thin
      location    1      !Inside WR firewall= 0, outside= 1
      bar_code    1      !Bar Code Software not installed= 0, installed= 1
      
      !Parameters for Daylight Chemical Database
      day_parms   &datatype=SMI&dbname=cis&dbpw=cheminfo&uname=dayuser&upw=cheminfo
      
      !Paths to helper applications
      acrobat     c:\Acrobat3\Reader\AcroRd32.exe
      browser     c:\Program Files\NETSCAPE\Navigator\PROGRAM\netscape.exe 
      
      !Parameters for installing Mettler Balance.  
      balance     1     ! Balance: not installed= 0;  installed= 1
      port        com2  ! Com port (com1, com2, com3, etc)
      baud        9600  ! Baud rate for com port (2400, 4800, 9600, etc)
      parity      2     ! Parity (0= no parity; 1= odd; 2= even; 3= mark; 4= space)
      bits        8     ! bits per byte (4,5,6,7, or 8)
      flow        0     ! flow control (0= hardware (DTR/CTS); 1= Xon/Xoff)
      outfile     c:\trifox\cache\fm_bal.txt     ! stores data returned from balance  
      
      !Thin client configuration with all help/reference files on ETCIS server
      cache_dir        c:\trifox\cache\
      raswin_dir       c:\raswin\
      ship_dir         c:\trifox\ship\
      cis_dir          dka0:[prod.trifox.cis]
      help_dir         dka0:[prod.trifox.help]
      mass_dir         dka0:[prod.trifox.massspec]
      run_dir          dka0:[prod.trifox.run]
      sri_dir          dka0:[prod.trifox.sri]
      sweeney_dir      dka0:[prod.trifox.sweeney]
      cisserver        net:sql$database@141.236.20.10(%AUTH%)!ljk
      chemserver       http://141.236.12.11/
      
      !Fat client configuration to WR with all help/reference files on client
      !cache_dir       c:\trifox\cache\
      !raswin_dir      c:\raswin\
      !ship_dir        c:\trifox\ship\
      !cis_dir         c:\trifox\cis\
      !help_dir        c:\trifox\help\
      !mass_dir        c:\trifox\massspec\
      !run_dir         c:\trifox\run\
      !sri_dir         c:\trifox\sri\
      !sweeney_dir     c:\trifox\sweeney\
      !cisserver       net:sql$database@141.236.12.10(%AUTH%)!ljk
      !chemserver      http://141.236.12.11/
      
      !Fat client configuration with all help/reference files on ETCIS Server
      !cache_dir       c:\trifox\cache\
      !cis_dir         c:\trifox\cis\
      !raswin_dir      c:\raswin\
      !ship_dir        c:\trifox\ship\
      !help_dir        dka0:[prod.trifox.help]
      !mass_dir        dka0:[prod.trifox.massspec]
      !run_dir         dka0:[prod.trifox.run]
      !sri_dir         dka0:[prod.trifox.sri]
      !sweeney_dir     da0:[prod.trifox.sweeney]
      !cisserver       net:sql$database@141.236.12.10(%AUTH%)!ljk
      !chemserver      http://141.236.12.11/
      
      !Walter Reed SHIVA connection:
      !cisserver       net:sql$database@141.236.20.10(%AUTH%)!ljk!
      !chemserver      http://141.236.20.11/
      
      !Daylight Server:
      !chemserver      http://207.71.104.130/
      
    3. GUIslave Icon properties
      • Win NT/95
        • Target c:\trifox\gcmnod32.exe -ic:\trifox\lib\guicis.ini
        • Start in c:\trifox\bin
      • Win 3.1
        • Command Line: c:\trifox\bin\gcmnod.exe -ic:\trifox\lib\guicis.ini
        • Working Directory: c:\trifox\bin

    4. Display: Set the resolution of the display to 1024 by 768 pixels.

      • Win NT/95: My Computer/Control Panel/ Display/ Settings/
      • Win 3.1:

  • Fat Client for End Users

    Machine Independent Run (MIR) files run as stand alone applications without the TRIM library (gui.fnc, gui.h, trim.h, etc.). By eliminating the TRIM library, the number of files on the fat client are minimized and installation is simplified. In addition, MIR files exclude unnecessary code such as programmer's comments so they are actually smaller than the original source file. Finally, the use of MIR files guarantees that the end user will not change your code.

    There are two steps to making MIR files. Open a Command Prompt Window, go to the directory containg the ASCII source applications and follow these steps:

    1. Compile the ASCII source applications to MIR files (*.gap or *.app) using the '-i' option:

      trimgen *.gap -u -s -o -i.

      This command will write ASCII files with the '.mir' suffix that contain all of the library functions required to run as stand alone applications. The '.mir' files can be moved to the following target computers and converted into binary run files: WinNT/Win95, VMS, ...PAUL ADD OTHER OSs. Note that 16-bit DOS/Windows machines are not supported.

    2. Convert the ASCII '.mir' applications into run files on the target computer:

      trimmir *.mir

      This command will write binary files with the '.run' suffix. They will only run on the OS under which they were made. For example, '.mir' files converted to run files on a 32 bit WinNT machine can be copied to other WinNT or Win95 machines. Note that the run files can easily be zipped with a few configuration, data, and help files to distribute a runtime version of the Chemical Information System:
      CIS Files Fat Client for End Users [1.25Mb]
      Directory
      Files
      c:\daspects\bin cexuser.dll, gcvt.exe, guirun.exe, msvcrt.dll, scale.exe, vtx3.exe, vtx.dll, WRCIS icon
      c:\daspects\bmp blank.bmp, dnarrow.bmp, uparrow.bmp
      c:\daspects\cache empty
      c:\daspects\cis accession.run, address.run, balance.run, merck.run, request.run, ship.run, start.run, track.run
      biotable.txt, merckwr.txt, pdwr.txt, stectwr.txt, trsmalwr.txt, trsradwr.txt
      c:\daspects\help aboutcis.htm, chemnet.htm, devnotes.htm, gaphelp.htm, support.htm
      c:\daspects\lib gui.ini, gui.msg, wrcis.ini, wrcis.vgd
      c:\daspects\ship empty

    The readme.txt file provides instructions on creating the WRCIS Icon, modifing autoexec.bat and setting environmental variables.

  • Fat Client for Developers

    1. CIS files on Server: There are no CIS files on the server. All CIS files are on the fat client.

    2. CIS Files TRIMtools & Directories on Fat Client

      Files on CIS Fat Client
      Directory
      Files
      c:\trifox\lib CIS: gui.fnc, gui.dft, guicis.ini, import.h, wrcis.ini, wrcis.vgd
      TRIMtools: net.ini, gui.cc, gui.ini, gui.csf, gui.h, gui.key, gui.kma, gui.msg, gui.pev,gui.uat, gui.vis
      c:\trifox\prod CIS: accession.gap, balance.gap, merck.gap, request.gap, ship.gap, start.gap, track.gap
      c:\trifox\cis CIS: accession.run, balance.run, merck.run, request.run, ship.run, start.run, track.run
      CIS: biotable.txt, merckwr.txt, pdwr.txt, stectwr.txt, trsmalwr.txt, trsradwr.txt
      c:\trifox\help CIS: aboutcis.htm, chemnet.htm, devnotes.htm, gaphelp.htm, support.htm
      c:\trifox.bin TRIMtools: scale.exe, gcvt.exe, guiapp.exe, guirun.exe, guimsg32.exe, vtx3.exe, vtx3.dll, vtxping.exe, trimgen.exe
      Note: To compile on the fat client open the Command Prompt Window and execute the following command: 'trimgen c:\trifox\prod\*.gap -u -s -o'. Then copy the run files: 'copy c:\trifox\prod\*.run ..\cis'.

    3. Directories
      • c:\trifox\bin for TRIMtool executables.
      • c:\trifox\lib for CIS and TRIMtool configuration files.
      • c:\trifox\cache to store temporary files downloaded from servers.
      • c:\trifox\ship to store ship lists to be sent to the test systems formatted as tab delimited files for e-mail or dynamic HTML documents for printing hard copies.

    4. The GUIapp Icon properties for Win NT/95/3.1
      • Target c:\trifox\C:\TRIFOX\bin\guirun.exe start
      • Start in c:\trifox\cis

    5. Display: Set the resolution of the display to 1024 by 768 pixels

      • Win NT/95: My Computer/Control Panel/ Display/ Settings/
      • Win 3.1:

  • Java Client


    LOV Windows


    Popup Menus: Creating & Controlling

    Popup Menus are used to display a list from the right mouse button.
    Creating a Popup Menu:
    1. Declare your list as a Global variable.
    2. Create a list in a user trigger using list_open() and list_mod(). Your list should have two fields. Text in the first field will be displayed in the popup menu. The value in the second field will be used to set G.key in the popup event trigger. Example code follows:
      {
      g.bal_pu_list= NULL;
      list_mod(g.bal_pu_list,1,"Send",41);         /* key 41 Create file to_bal.txt */
      list_mod(g.bal_pu_list,1,"Exit    F3",3);    /* key_f3 Exit application       */
      list_mod(g.bal_pu_list,1,"",0);              /* Displays line in popup menu   */
      list_mod(g.bal_pu_list,1,"Copy  Ctrl+C",38); /* key 38 Copy to clipboard      */
      list_mod(g.bal_pu_list,1,"Cut    Ctrl+X",39);/* key_39 Cut fld; copy to clip  */
      list_mod(g.bal_pu_list,1,"Paste Ctrl+V",40); /* key_40 Paste from clip to fld */
      list_mod(g.bal_pu_list,1,"",0);              /* Displays line in popup menu   */
      list_mod(g.bal_pu_list,1,"LOV    F11",key_lov);
      list_mod(g.bal_pu_list,1,"Help    F12",key_help);
      }
      
    3. Associate the actions listed in the popup menu with the value of g.key in the window trigger:
        else {                                    /* normal mode                    */
          input(G.input_var);
          if (G.modified) move_f2l(0);            /* update window list (if needed) */
          if (G.key == key_f3) break;             /* default Quit key               */
          else if (G.key in (key_help,key_lov))
            key_exec(G.key);                      /* execute the key trigger        */
          ...
          else if (G.key == key_41)               /* exchange data with balance     */
            send();                               /* see user triggers              */
          }                                       /* normal mode                    */
        if (G.key in (key_38,key_39,key_40))      /* copy,cut,paste field_d         */
          clip();                                 /* see gui.fnc                    */
        }                                         /* while loop forever             */
      
    4. Load the g.bal_pu_list by calling your user trigger from the beginning of the main window trigger. Then load the popup_menu. For example:
      ...
      if (G.error_code) {                         /* an error occured ?             */
         ...
        }
      else {
         ...
        load_bal_pu_list();                       /* load g.bal_pu_list into popup    */
        popup_menu(popup_load,g.bal_pu_list);     /* load popup menu                */
        }
      while (true) {                              /* loop forever                   */
      ...
      
    5. Modify the 'Event trigger for popup menu' using the dialog box. You can display this box by navigating this path in the GUIdeveloper: Window Name/Triggers.../ Events/popup menu. Your trigger should assign the second column of current row of the popup list to g.key. The current row is selected by the user- the user's choice. Set the 'popup menu trigger' to Prevalidate. Example code follows:
      {
      g.key= list_ixed(g.bal_pu_list,g.aux,1);     /* assign user's choice to g.key */
      escape(input);                               /* exit to the window trigger    */
      }
      
    6. Verify, save and run your application. To display the popup menu, press the right mouse button. To execute a popup action, select with the arrow and press the left button.

    Printing Reports: Dynamic HTML


    Query from Child Window

    {
    /*
      This trigger fires formates a query using child/sibling variables and
      fires this query in the parent/caller window.
    
      Actions:
        1. Determine if query is originating with parent or child.
        2. If it is originating in the child then:
            a. Construct an 'in' predicate using BNs from child window
            b. Save values in query fields of child. (why do this?)
            c. Run filter. (why do this?)
            d. Run query trigger in parent using g.query_buf.
    
      Problems:
        1. What does g.save_val do?  It is a flag for the field triggers:
            {
            char save_val[128];
            if (g.save_val) save_val= field_d;
            else            field_d = save_val;
            }
      Pat McGreevy, 16 Feb 98
    */
    int from_parent;
    from_parent = true;                         /* initialize true                */
    /*  if child in normal mode (p.mode=false) parent is calling so clear child   */
    if (!p.mode) { p.ar = 0; field_set(NULL); } /* clear if parent calling        */
    else {                                      /* parent not calling             */
      query(query_max);                         /* run child query                */
      if (list_rows(p.wl)) {                    /* did child select returned data?*/
        g.query_buf = NULL;
        g.query_buf = "a.an in (";              /* start 'in' predicate           */
        while (list_rows(p.wl)) {               /* append child variables         */
          g.query_buf = g.query_buf ^^ list_curr(p.wl,@p.bn);
          list_mod(p.wl,0);                     /* delete curr row in child wl    */
          if (list_rows(p.wl)) g.query_buf = g.query_buf ^^ ",";
          }
        g.query_buf = g.query_buf ^^ ")";       /* finish 'in predicate'          */
        p.mode = 0;                             /* set child to normal mode       */
        g.save_val = true;                      /* set flag to save child fields  */
        field_exec(uat_noquery,false);          /* save values in child qry flds  */
    /*    window(start,query);                     run parent query/use g.qry_buf */
        if (prompt("Filter results [N]: ") == "Y") {
          g.save_val = false;                   /* reset save_val flag false      */
          field_set(NULL);                      /* clear child fields             */
          field_exec(uat_noquery,false);        /* exe trg in child query fields  */
          from_parent = true;
          g.save_val  = true;
          }
        else from_parent = false;
        }
      refresh(false);                           /* turn off refresh temporarily   */
      }
    if (from_parent) {                          /* run child query again ?        */
      status("Query in progress");
      cursor_wait(true);
      query(query_max,"a.bn = "^^start.bn);
      status(query_count(G.query_buf)^^" rows returned");
      G.query_buf = NULL;                       /* reset query_buf                */
      edit_win(p.wl,edt_refresh,false);         /* refresh the window             */
      if (child) window(child,query);           /* CHANGE TO RUN ONLY RUN IF OPEN */
      else refresh(true);
      }
    }
    

    Sibling Window: Focus & Control

    Code required to change the focus among multiple windows follows.
    1. Window change event (PEV_10).
      • Old default code:
        G.key = decode(focus(true),parent,key_f3,
                             child ,key_nextblock,
                             9999);
                
      • New code:
        {
                     G.tw  = focus(true);
                     G.key = decode(G.tw,parent,key_f3,
                                         child ,key_nextblock,
                                         9999);
                     }
                 
    2. In "driving window" (registration):
      • Old default code:
        }
        while (true) {                              /* loop forever                   */
                
      • New code:
        }
        g.tw = current;
        while (true) {                              /* loop forever                   */
          while (g.tw != current) { i = g.tw; g.tw = current; window(i,run); }
                
        3.  In Structure window trigger:
        {                                           /* User window trigger            */
        list dl;                                    /* delete list                    */
        int  mode; int rows;                        /* window mode, rows per row      */
        int  i;    int   j;                         /* loop variables                 */
        char val_wrno[6];                           /* USED IN WRNOVAL()              */
        char val_bn[7];                             /* USED IN BNVAL()                */
        
        while (true) {
          raw_input();
          if (G.key in (key_quit,9999)) break;
          }
        
        if (G.key != 9999)
          window(current,close);
        
        

        Stand Alone Trim.pl: (trimgen -a / trimrunc