home *** CD-ROM | disk | FTP | other *** search
/ DOS Wares / doswares.zip / doswares / DATABASE / DBASE5 / TEMPLATE.ZIP / FORM.COD < prev    next >
Encoding:
Text File  |  1994-06-24  |  54.4 KB  |  1,796 lines

  1. // Module Name: FORM.COD FOR 5.0
  2. // Description: This module produces dBASE 5.0 .FMT files
  3. //              with popups for VALID clause field validation and
  4. //              Context Sensitive Help for each field
  5. //
  6.  
  7. Format (.fmt) File Template with POPUP field validation
  8. -------------------------------------------------------
  9. Copyright (c) 1987, 1990, 1991, 1992, 1994 Borland International, Inc.
  10.  
  11.  
  12. This template will support POPUPs for VALID clause field validations and
  13. context sensitive help for each field.
  14.  
  15. Example: In "ACCEPT value when" under "Edit options" enter,
  16.         "POPUP" = "vendor->vendor_id ORDER vendor_id REQ SHADOW"
  17.         --------------------------------------------------------
  18.         this will activate a popup if the data entered is invalid for
  19.         that field and will also make the field REQUIRED.
  20.  
  21. Explanation of the POPUP string follows:
  22.  
  23. POPUP              Indicates that a popup will be used for this field.
  24. vendor->vendor_id  Indicates the .DBF to open and FIELD to use as validation.
  25. ORDER vendor_id    Indicates which INDEX TAG to SEEK in.
  26. REQ                Indicates the FIELD requires data (can't be empty).
  27.                    Leave REQ out if the field is NOT required.      OPTIONAL!
  28. SHADOW             Use shadowing effect on popups                   OPTIONAL!
  29. NOTE: The POPUP string must be entered with the quotes as in the example.
  30.  
  31. --------------------------------------------------------------------------------
  32.  
  33. Explanation of the Context Sensitive Help file follows:
  34.  
  35. If you want to create your own help file, here is the structure that is required.
  36.  
  37. Structure for Help Database (.dbf):
  38. <first 6 chars. of the format file name>_H.dbf
  39.  
  40. Field   Field Name  Type        Width  Dec   Tag
  41. -------------------------------------------------
  42.     1   FLD_NAME    Character     10         Yes  Field name to lookup on F1
  43.     2   FLD_HEADNG  Character     25          No  Heading to show user on window
  44.     3   FLD_HELP    Memo          10          No  Help text to show user
  45. -------------------------------------------------
  46.         Total                     46
  47. {
  48. include "form.def"    // Form selectors
  49. include "builtin.def" // Builtin functions
  50.  
  51.  if getenv("dtl_debug") then
  52.    debug(2)
  53.    breakpoint( pick_debug )
  54.  endif
  55.  
  56. //
  57. // Enum string constants for international translation
  58. //
  59.  // Enum's for ON KEY labels AND error strings in FORM.DEF
  60.  enum  TRUE  = 1,
  61.        FALSE = 0,
  62.        offset = 2,         // Offset for lmarg()
  63.        range_require  = 2, // Bit for range required set
  64.        valid_required = 4, //  "   "  edit     "      "
  65.        screen_width = 80,  // Screen width for now
  66.        err_ext = ".err"
  67.  ;
  68. //
  69.  
  70.  var  bnl_formname,     // Name of BNL file to newframe if argument() has value
  71.       create_error,     // Indicates if there were problems creating programs
  72.       arg_list;
  73.  
  74.  arg_list = argument()
  75.  if arg_list != "" then
  76.    bnl_formname = token( ",", arg_list, 1 )
  77.    if !newframe( bnl_formname ) then
  78.      return -1;
  79.    endif
  80.  endif
  81.  
  82.  if FRAME_CLASS != form then // We are not processing a form object
  83.    pause(wrong_class + any_key)
  84.    goto NoGen;
  85.  endif
  86.  
  87.  
  88. var  fmt_name,     // Format file name
  89.      crlf,         // line feed
  90.      carry_flg,    // Flag to test carry loop
  91.      carry_cnt,    // Count of the number of fields to carry
  92.      carry_len,    // Cumulative length of carry line until 75 characters
  93.      carry_lent,   // Total cumulative length of carry line
  94.      base_name,        // First 6 characters of the NAME selector
  95.      procedure_name,   // First 7 characters of the NAME selector
  96.      udf_filename,     // UDF file name grabbed from .scb file
  97.      lookup_cnt,
  98.      carry_first,  // Flag to test "," output for carry fields
  99.      color_flg,    // Flag to if color should stay on am line
  100.      line_cnt,     // Count for total lines processed (Mulitple page forms)
  101.      page_cnt,     // Count for total pages processed (Mulitple page forms)
  102.      temp,         // tempory work variable
  103.      cnt,          // Foreach loop variable
  104.      wnd_cnt,      // Window counter
  105.      wnd_names,    // Window names so I can clear them at the bottom of the file
  106.      default_drv,  // dBASE default drive
  107.      dB_status,    // dBASE status before entering designer
  108.      scrn_size,    // Screen size when generation starts
  109.      left_delimiter, // Delimiter to put around SAY
  110.      right_delimiter,// Delimiter to put around SAY
  111.      max_pop_row,  // Maximum row that a popup or shadow can start
  112.      display,      // Type of display screen we are on
  113.      is_popup,     // POPUP validation requested
  114.      is_help,      // HELP (context sensitive) requested
  115.      udf_file,     // UDF file has been created
  116.      hlp_name,     // HELP .dbf name
  117.      trow_positn,  // Temporary variable for row_positn
  118.      tcol_positn,  // Temporary variable for col_positn
  119.      at_pop,       // "POPUP" is in FLD_OK_COND
  120.      master_file,  // Name of master alias based on first field on form
  121.      workarea_dbfs,// DBF files opened on the surface , delimited
  122.      color;        // Color returned from getcolor function
  123.  
  124.  //-----------------------------------------------
  125.  // Assign default values to some of the variables
  126.  //-----------------------------------------------
  127.  carry_flg = carry_first = carry_cnt = carry_len = carry_lent =
  128.  wnd_cnt = line_cnt =  color_flg = cnt = 0
  129.  crlf = chr(10)
  130.  master_file = workarea_dbfs = temp = ""
  131.  page_cnt = 1
  132.  is_popup = is_help = udf_file = 0
  133.  left_delimiter = right_delimiter = "\""
  134.  procedure_name = lower( rtrim( substr( NAME, 1, 7 )))
  135.  base_name      = lower( rtrim( substr( NAME, 1, 6 )))
  136.  udf_filename = "U_" + base_name
  137.  
  138.  //--------------------------------------------------------
  139.  // Determine the size of the screen and the max row that a 
  140.  // help and fill popup can extend to.
  141.  //--------------------------------------------------------
  142.  screen_size()
  143.  dB_status = numset(_flgstatus)
  144.  scrn_size = (!db_status ? scrn_size + 3 : scrn_size)
  145.  max_pop_row = scrn_size - 3;
  146.  
  147.  //-------------------------------
  148.  // Create Format file
  149.  //-------------------------------
  150.  if !make_Fmt() then goto nogen
  151.  
  152.  header()                   // Print Header in the Format file
  153.  fmt_file_initialization()  // Format file initializtion code
  154.  fmt_file_body()            // @ SAY GET Processing
  155.  fmt_file_exit()            // Format file exit code
  156.  make_pop_code()            // Create the Procedure File for POPUP's if required
  157.  make_help_code()           // Make procedures for the help system
  158.  if is_popup || is_help then
  159.    make_general_procs();
  160.  endif
  161.  fileerase(fmt_name+".fmo")
  162.  nogen:
  163. return 0;
  164.  
  165.  
  166. //---------------------------------------
  167. // Template user defined functions follow
  168. //---------------------------------------
  169.  
  170. define fmt_file_initialization()
  171. //
  172. // Format file initialization code
  173. //
  174. }
  175.  
  176. *-- Format file initialization code --------------------------------------------
  177.  
  178. *-- Some of these PRIVATE variables are created based on CodeGen and may not 
  179. *-- be used by your particular .fmt file
  180. PRIVATE ll_talk, ll_cursor, lc_display, lc_status, ll_carry, lc_proc
  181.  
  182. IF SET("TALK") = "ON"
  183.   SET TALK OFF
  184.   ll_talk = .T.
  185. ELSE
  186.   ll_talk = .F.
  187. ENDIF
  188. ll_cursor = SET("CURSOR") = "ON"
  189. SET CURSOR ON
  190. lc_display = SET("DISPLAY")
  191. {
  192.   set_screen_mode();
  193. }
  194. lc_status = SET("STATUS")
  195. *-- SET STATUS was \
  196. {if dB_status then}
  197. ON when you went into the Forms Designer.
  198. IF lc_status = "OFF"
  199.    SET STATUS ON
  200. {else}
  201. OFF when you went into the Forms Designer.
  202. IF lc_status = "ON"
  203.    SET STATUS OFF
  204. {endif}
  205. ENDIF
  206. //-----------------------------------------------------------------------
  207. // Process fields to build "SET CARRY" and WINDOW commands.
  208. //-----------------------------------------------------------------------
  209. {
  210.   foreach FLD_ELEMENT flds
  211.     if FLD_CARRY then 
  212.       carry_flg = 1; 
  213.       ++carry_cnt ;
  214.     endif
  215.     if chr(FLD_VALUE_TYPE) == "M" and FLD_MEM_TYP and wnd_cnt < 20 then
  216.       ++wnd_cnt;
  217.       wnd_names = wnd_names + "wndow" + wnd_cnt + ",";
  218.       new_page(flds);
  219. }
  220.  
  221. *-- Window for memo field {cap_first(FLD_FIELDNAME)}.
  222. DEFINE WINDOW { Window_Def(flds)}\
  223. {   endif
  224.   next flds
  225.   print(crlf);
  226.   if carry_flg then
  227. }
  228.  
  229. ll_carry = SET("CARRY") = "ON"
  230. SET CARRY ON
  231. *-- Fields to carry forward during APPEND.
  232. SET CARRY TO{tabto(41)}&& Clear previous SET CARRY TO list
  233. SET CARRY TO { Carry_Flds()}
  234.  
  235. {endif}
  236. {
  237.   if check_for_popups() then
  238. }
  239.  
  240. ON KEY LABEL F2 ?? chr(7)
  241.  
  242. {   output_set_proc_code();}
  243. DO S_{procedure_name}{tabto(41)}&& Open up Lookup Files
  244.  
  245. {   endif
  246.     if check_for_help() then
  247.       if !is_popup then}
  248. {         output_set_proc_code();}
  249. {       endif}
  250. ON KEY LABEL F1 DO Help WITH VARREAD()
  251. { endif
  252. return;
  253. // eof - fmt_file_init()
  254. enddef
  255.  
  256. //--------------------------------------------------------------
  257. define fmt_file_body()
  258.   var and_loc,
  259.       or_loc;
  260. }
  261.  
  262. *-- @ SAY GETS Processing. -----------------------------------------------------
  263.  
  264. *--  Format Page: {page_cnt = 1
  265.                    page_cnt}
  266.  
  267. {line_cnt = wnd_cnt = 0
  268.  foreach ELEMENT k
  269.    color = getcolor(FLD_DISPLAY, FLD_EDITABLE) // get color of element
  270.    if new_page(k) then
  271. }
  272. READ
  273.  
  274. *-- Format Page: {page_cnt}
  275.  
  276. {  endif
  277. //
  278.  
  279.    if ELEMENT_TYPE == @TEXT_ELEMENT or ELEMENT_TYPE == @FLD_ELEMENT then
  280.      if FLD_FIELDTYPE == calc then
  281. }
  282. *-- Calculated field: {cap_first(FLD_FIELDNAME)} - {FLD_DESCRIPT}
  283. {    endif
  284.      if FLD_FIELDTYPE == memvar then
  285. }
  286. *-- Memory variable: {cap_first(FLD_FIELDNAME)}
  287. {    endif}
  288. @ {nul2zero(ROW_POSITN) - line_cnt},{nul2zero(COL_POSITN)} \
  289. {  endif
  290.    if ELEMENT_TYPE == @BOX_ELEMENT then
  291. }
  292. @ {box_coordinates(k)}\
  293. {  endif}
  294. //
  295. {  case ELEMENT_TYPE of
  296.    @TEXT_ELEMENT:
  297.    // Certain control characters can cause dBASE problems ie, ASCII(13,26,0)
  298.    // so the form designer will either send them to us as a string if they are
  299.    // all the same character or as individual characters if they differ. We
  300.    // handle this by using the chr() function to "SAY" them in dBASE.
  301. }
  302. SAY \
  303. {     if asc(TEXT_ITEM) < 32 then
  304.         if len(TEXT_ITEM) == 1 then}
  305. CHR({asc(TEXT_ITEM)}) \
  306. {       else}
  307. REPLICATE(CHR({asc(TEXT_ITEM)}), {len(TEXT_ITEM)}) \
  308. {       endif
  309.       else
  310.          if substr(TEXT_ITEM,1,1) == "\"" then
  311.             // Double quote is being used on the design surface need to use
  312.             // brackets "[]" as delimiters
  313.             left_delimiter = "["
  314.             right_delimiter = "]"
  315.          endif
  316.          left_delimiter + TEXT_ITEM + right_delimiter} \
  317. {        left_delimiter = right_delimiter = "\""
  318.       endif
  319.       outcolor()}
  320. {  @Box_element:
  321.        outbox(BOX_TYPE, BOX_SPECIAL_CHAR)}
  322. {      outcolor()}
  323. {  @FLD_ELEMENT:
  324.       if !FLD_EDITABLE then; // its a SAY}
  325. SAY \
  326. {        if FLD_FIELDTYPE == calc then
  327.            // Loop thru expression in case it is longer than 237
  328.             foreach FLD_EXPRESSION fcursor in k
  329.                FLD_EXPRESSION}
  330. {           next}
  331. // Output a space after the Fld_expression and get ready for picture clause
  332.  \
  333. {        else // not a editable field
  334.             if FLD_FIELDTYPE == dbf then temp = "" else temp = "m->" endif
  335.                temp + cap_first(FLD_FIELDNAME)} \
  336. {        endif
  337.          if Ok_Template(k) then}
  338. PICTURE "{picture_for_say(k);}" \
  339. {        endif
  340.       else // it's a get}
  341. GET \
  342. {        if FLD_FIELDTYPE == dbf then 
  343.            temp = "" 
  344.            if !master_file then
  345.              master_file = FLD_FILENAME
  346.            endif
  347.          else 
  348.            temp = "m->" 
  349.          endif
  350.          temp + cap_first(FLD_FIELDNAME)} \
  351. {        if chr(FLD_VALUE_TYPE) == "M" && FLD_MEM_TYP then
  352.             if wnd_cnt < 20  then ++wnd_cnt endif
  353.             if Fld_mem_typ == 1}OPEN {endif}WINDOW wndow{wnd_cnt} \
  354. {        endif
  355.          if Ok_Template(k) then}
  356. PICTURE {picture_for_get(k);} \
  357. {        endif
  358.          if FLD_L_BOUND or FLD_U_BOUND then color_flg = 1;}
  359. ;
  360.    RANGE {if range_require & FLD_EDITABLE then}REQUIRED {endif}\
  361. {  FLD_L_BOUND}{if FLD_U_BOUND then},{FLD_U_BOUND}{endif} \
  362. {        endif
  363.          if FLD_OK_COND then color_flg = 1;}
  364. ;
  365. {           if at("POPUP", upper(ltrim(FLD_OK_COND))) == "2" and
  366.                ok_coordinates( k, 2, 1, bad_pick ) then
  367.                // A POPUP is desired for showing coded values, redo the
  368.                // VALID clause to call a UDF based on "U_" + FLD_FIELDNAME
  369. }
  370.    VALID {    if valid_required & FLD_EDITABLE ||
  371.                  is_required( FLD_OK_COND )       then}REQUIRED {endif}\
  372. {  get_udfname(FLD_FIELDNAME)}( {cap_first(FLD_FIELDNAME)} ) \
  373. {             and_loc = at( ".AND.", upper(FLD_OK_COND) );
  374.               if and_loc > 0 then
  375.                 substr( FLD_OK_COND, and_loc )} \
  376. {             endif
  377.             else
  378.                 if !(at("POPUP", upper(ltrim(FLD_OK_COND))) == "2") then
  379. }
  380.    VALID {if valid_required & FLD_EDITABLE then}REQUIRED {endif}{FLD_OK_COND} \
  381. {
  382.                 endif
  383.             endif
  384.  
  385.             if FLD_REJ_MSG then}
  386. ;
  387.    ERROR \
  388. {              if !at("IIF", upper(FLD_REJ_MSG))}"{endif}{FLD_REJ_MSG}\
  389. {              if !at("IIF", upper(FLD_REJ_MSG))}"{endif} \
  390. {           endif
  391.          endif // FLD_OK_COND
  392.          if FLD_ED_COND then color_flg = 1;}
  393. ;
  394.    WHEN {FLD_ED_COND} \
  395. {
  396.          endif
  397.          if FLD_DEF_VAL then color_flg = 1;}
  398. ;
  399.    DEFAULT {FLD_DEF_VAL} \
  400. {        endif
  401.          if FLD_HLP_MSG then color_flg = 1;}
  402. ;
  403.    MESSAGE \
  404. {           if !at("IIF", upper(FLD_HLP_MSG))}"{endif}{FLD_HLP_MSG}\
  405. {           if !at("IIF", upper(FLD_HLP_MSG))}"{endif} \
  406. {        endif
  407.       endif // FLD_EDITABLE
  408. }
  409. {     outcolor()}
  410. {     color_flg = 0;
  411.    otherwise: goto getnext;
  412.    endcase
  413. }
  414.  
  415. //Leave the above blank line, it forces a line feed!
  416. //-----------------
  417. // End of @ SAY GET
  418. //-----------------
  419. {  ++cnt;
  420.    getnext:
  421.  next k
  422. return;
  423. // eof - fmt_file_body()
  424. enddef
  425.  
  426. //--------------------------------------------------------------
  427. define fmt_file_exit()
  428. }
  429. *-- Format file exit code -----------------------------------------------------
  430.  
  431. *-- SET STATUS was \
  432. {if dB_status then}
  433. ON when you went into the Forms Designer.
  434. IF lc_status = "OFF"  && Entered form with status off
  435.    SET STATUS OFF     && Turn STATUS "OFF" on the way out
  436. {else}
  437. OFF when you went into the Forms Designer.
  438. IF lc_status = "ON"  && Entered form with status on
  439.    SET STATUS ON     && Turn STATUS "ON" on the way out
  440. {endif}
  441. ENDIF
  442. {if carry_flg then}
  443. IF .NOT. ll_carry
  444.   SET CARRY OFF
  445. ENDIF
  446. {endif}
  447. IF .NOT. ll_cursor
  448.   SET CURSOR OFF
  449. ENDIF
  450.  
  451. IF SET( "DISPLAY" ) <> lc_display
  452.   SET DISPLAY TO &lc_display.      && Reset Screen size if changed
  453. ENDIF
  454.  
  455. {if wnd_names then}
  456. RELEASE WINDOWS {substr(wnd_names, 1, (len(wnd_names) - 1))}
  457. {endif}
  458.  
  459. RELEASE {if carry_flg then}ll_carry,{endif}lc_fields,lc_status
  460. {    if is_help then}
  461.  
  462. ON KEY LABEL F1
  463. {    endif
  464.      if is_popup or is_help then}
  465. ON KEY LABEL F2
  466. {      if is_popup then}
  467. DO C_{procedure_name}{tabto(41)}&& Close up Lookup Files
  468. {      endif}
  469. SET PROCEDURE TO (lc_proc){tabto(41)}&& Re-Establish any open procedure file
  470. RELEASE lc_proc
  471. {    endif}
  472. IF TYPE( "ll_echo" ) = "L"
  473.   IF ll_echo
  474.     SET ECHO ON
  475.   ENDIF
  476. ENDIF
  477. IF ll_talk
  478.   SET TALK ON
  479. ENDIF
  480. *-- EOP: {filename(fmt_name)}FMT
  481. {return;
  482. // eof - fmt_file_exit()
  483. enddef
  484.  
  485. define picture_for_get(c)
  486. //--------------------------------------------------------------
  487. // DESCRIPTION
  488. //   Build a dBASE Picture template for a @ GET command
  489. //
  490. //--------------------------------------------------------------
  491.   if at("\"", c.FLD_TEMPLATE) or at("'", c.FLD_TEMPLATE)then
  492.     left_delimiter = "["
  493.     right_delimiter = "]";
  494.   endif
  495.   left_delimiter}
  496. { if c.FLD_PICFUN then}@{c.FLD_PICFUN}\
  497. {   if at("S", c.FLD_PICFUN) then}{c.FLD_PIC_SCROLL}{endif}\
  498.  {//leave this space}\
  499. { endif
  500.   if at("M", c.FLD_PICFUN) then
  501.     c.FLD_PIC_CHOICE}\
  502. { else
  503.     c.FLD_TEMPLATE}\
  504. { endif
  505.   right_delimiter}
  506. { left_delimiter = right_delimiter = "\""
  507.  return;
  508. enddef
  509.  
  510. //--------------------------------------------------------------
  511. define picture_for_say(c)
  512.      if c.FLD_PICFUN then}@{c.FLD_PICFUN}\
  513. {       if at("S", c.FLD_PICFUN) then}{c.FLD_PIC_SCROLL}{endif}\
  514.  {//leave this space}\
  515. {       endif
  516.      if !at("M", c.FLD_PICFUN) then
  517.         c.FLD_TEMPLATE}\
  518. {    endif
  519.  return;
  520. enddef
  521.  
  522. define make_pop_code()
  523. //--------------------------------------------------------------
  524. // Create the Procedure File for POPUP's if required
  525. //--------------------------------------------------------------
  526.   var lookup_dbf,   // store get_file(text_line1) for faster processing
  527.       look_alias,   // Lookup alias, diff from DBF if DBF starts with number
  528.       look_1st,     // 1st char of lookup DBF file
  529.       is_format,    // is there a format file
  530.       fmt_name,     // Name of the format file to use with browse
  531.       temp_name,    // store get_popname(text_line1)
  532.       prompt_field, // Name of field to build popup with
  533.       temp_key,
  534.       tag_name,     // tag name for the order
  535.       temp_org_file,// store get_org_file( text_line1 )
  536.       lookup_alias_on_form,
  537.       lookup_dbf_matches,
  538.       is_in_detail  // Flag for in a detail region
  539.       ;
  540.   if is_popup then
  541.     if !make_udf() then 
  542.       return 0;
  543.     endif
  544.     udf_header()
  545.  
  546. }
  547. PROCEDURE S_{procedure_name}
  548. *--------------------------------------------------------------------------------
  549. * DESCRIPTION
  550. *   Open data (.dbf) files for Lookup operations & faster processing
  551. *--------------------------------------------------------------------------------
  552.   PRIVATE lc_alias, ll_esc
  553.   ll_esc = SET( "ESCAPE" ) = "ON"
  554.   SET ESCAPE OFF
  555.   lc_alias = ALIAS(){tabto(41)}&& Capture current alias
  556.  
  557. {   foreach FLD_ELEMENT flds
  558.       at_pop = at("POPUP", upper(ltrim(FLD_OK_COND))) == "2" ? 1 : 0;
  559.       if at_pop then
  560.         lookup_dbf = Cap_first( get_file(FLD_OK_COND) );
  561.         look_1st = ASC( substr( lookup_dbf, 1, 1 ) );
  562.         look_alias = ( look_1st > 47 && look_1st < 58 ) ? 
  563.                         "A" + lookup_dbf : lookup_dbf;
  564.         tag_name = get_key(FLD_OK_COND);
  565.         prompt_field = get_field(FLD_OK_COND);
  566.         lookup_dbf_matches = (upper(lookup_dbf) == FLD_FILENAME) ?
  567.                                     TRUE : FALSE;
  568.         if not at("," + lookup_dbf, workarea_dbfs) then
  569.           workarea_dbfs = workarea_dbfs + "," + lookup_dbf;
  570. }
  571.   IF TYPE("g_{lower(lookup_dbf)}") = "U"
  572.     PUBLIC g_{lower(lookup_dbf)}
  573.  
  574.     IF SELECT("{lookup_dbf}") = 0
  575.       IF FILE( "{lookup_dbf}.DBF" )
  576.         SELECT SELECT()
  577.         USE {lookup_dbf} NOLOG ALIAS {look_alias}
  578.         g_{lower(lookup_dbf)} = 1{tabto(41)}&& File was opened for the first time
  579.         IF TAGNO( "{tag_name}" ) = 0
  580.           DO _Err_Box WITH [{tag_err} ] + [{tag_name}]
  581.           USE
  582.           RELEASE g_{lower(lookup_dbf)}
  583.           RELEASE gl_{lookup_dbf}
  584.           PUBLIC gl_{lookup_dbf}
  585.         ENDIF
  586.         IF TYPE( "{look_alias}->{prompt_field}" ) = "U"
  587.           DO _Err_Box WITH [{var_err} ] + [{look_alias}->{prompt_field}]
  588.           USE
  589.           RELEASE g_{lower(lookup_dbf)}
  590.           RELEASE gl_{lookup_dbf}
  591.           PUBLIC gl_{lookup_dbf}
  592.         ENDIF  
  593.       ELSE
  594.         DO _Err_Box WITH "{lookup_dbf}.DBF " + [{file_err}]
  595.         RELEASE g_{lower(lookup_dbf)}
  596.         RELEASE gl_{lookup_dbf}
  597.         PUBLIC gl_{lookup_dbf}
  598.       ENDIF
  599.     ELSE
  600.       g_{lower(lookup_dbf)} = 2{tabto(41)}&& File was opened outside of this program
  601.     ENDIF
  602.  
  603.   ELSE
  604.     *-- File was already opened by a program generated from Form.gen
  605.     g_{lower(lookup_dbf)} = g_{lower(lookup_dbf)} + 1
  606.   ENDIF
  607.  
  608. {       endif
  609.       endif
  610.     next;
  611. }
  612.   SELECT ( lc_alias )
  613.   IF ll_esc
  614.     SET ESCAPE ON
  615.   ENDIF
  616. RETURN
  617. *-- EOP: S_{procedure_name}
  618.  
  619.  
  620. PROCEDURE C_{procedure_name}
  621. *--------------------------------------------------------------------------------
  622. * DESCRIPTION
  623. *   Close Lookup files on exit of the .fmt, if they are not used
  624. *   by other calling .fmt files
  625. *--------------------------------------------------------------------------------
  626.   PRIVATE ll_esc
  627.   ll_esc = SET( "ESCAPE" ) = "ON"
  628.   SET ESCAPE OFF
  629. {   workarea_dbfs = ""
  630.     foreach FLD_ELEMENT flds
  631.       at_pop = at("POPUP", upper(ltrim(FLD_OK_COND))) == "2" ? 1 : 0;
  632.       if at_pop then
  633.         lookup_dbf = get_file(FLD_OK_COND)
  634.         look_1st = ASC( substr( lookup_dbf, 1, 1 ) );
  635.         look_alias = ( look_1st > 47 && look_1st < 58 ) ? 
  636.                         "A" + lookup_dbf : lookup_dbf;
  637.         if not at("," + lookup_dbf, workarea_dbfs) then
  638.           workarea_dbfs = workarea_dbfs + "," + lookup_dbf;
  639. }
  640.   DO CASE
  641.     CASE TYPE("g_{lower(lookup_dbf)}") = "U"
  642.       *-- Exiting out of the form!  Lookup file was not opened up properly
  643.       RELEASE gl_{lookup_dbf}
  644.     CASE g_{lower(lookup_dbf)} = 1
  645.       USE IN {look_alias}
  646.       RELEASE g_{lower(lookup_dbf)}
  647.     OTHERWISE
  648.       g_{lower(lookup_dbf)} = g_{lower(lookup_dbf)} - 1
  649.   ENDCASE
  650. {       endif
  651.       endif
  652.     next;
  653. }
  654.  
  655.   IF ll_esc
  656.     SET ESCAPE ON
  657.   ENDIF
  658. RETURN
  659. *-- EOP: C_{procedure_name}
  660.  
  661. {         line_cnt = lookup_cnt = 0
  662.           page_cnt = 1
  663.  
  664.           foreach FLD_ELEMENT flds
  665.  
  666.                at_pop = at("POPUP", upper(ltrim(FLD_OK_COND))) == "2" ? 1 : 0;
  667.  
  668.                new_page(flds)
  669.                if at_pop then
  670.                     trow_positn = nul2zero(ROW_POSITN) - line_cnt
  671.                     tcol_positn = nul2zero(COL_POSITN)
  672.                     lookup_dbf = get_file(FLD_OK_COND);
  673.                     look_1st = ASC( substr( lookup_dbf, 1, 1 ) );
  674.                     look_alias = ( look_1st > 47 && look_1st < 58 ) ? 
  675.                                  "A" + lookup_dbf : lookup_dbf;
  676.                     tag_name = get_key(FLD_OK_COND);
  677.                     prompt_field = get_field(FLD_OK_COND);
  678.                     color = getcolor(FLD_DISPLAY, FLD_EDITABLE) // get color of element
  679.  
  680.                     if !ok_coordinates(flds, 2, 0, "") then 
  681.                       loop 
  682.                     endif
  683. }
  684. FUNCTION {get_udfname(FLD_FIELDNAME)}
  685. PARAMETER fld_name
  686. *{replicate("-",69)}
  687.   PRIVATE ALL LIKE l?_*
  688.   PRIVATE esckey, fld_name, rtn_fld
  689.   ll_esc = SET( "ESCAPE" ) = "ON"
  690.   SET ESCAPE OFF
  691.   ll_return = .F.
  692.   IF TYPE( "gl_{lookup_dbf}" ) = "L"{tabto(41)}&& Was lookup file opened?
  693.     IF ll_esc{tabto(41)}&& It wasn't, so return back to the form
  694.       SET ESCAPE ON
  695.     ENDIF
  696.     RETURN(.T.){tabto(41)}&& With no data validation
  697.   ENDIF
  698. {                   if !is_required(FLD_OK_COND) then}
  699.   IF ISBLANK(fld_name){tabto(41)}&& Not a required field
  700.     IF ll_esc
  701.       SET ESCAPE ON
  702.     ENDIF
  703.     RETURN (.T.){tabto(41)}&& Return since it's a blank field
  704.   ENDIF
  705.  
  706. {                    endif}
  707.   EscKey = 27{tabto(41)}&& 27 represents the ESC key
  708.  
  709.   lc_alias = ALIAS(){tabto(41)}&& Grab current workarea
  710.   SELECT {look_alias}{tabto(41)}&& Select the lookup file
  711.   lc_order = ORDER(){tabto(41)}&& Save any existing order
  712.   SET ORDER TO {tag_name}{tabto(41)}&& Set the order to the lookup key
  713.  
  714.   ll_exact = SET("EXACT") = "ON"{tabto(41)}&& Store value of EXACT
  715.   SET EXACT ON
  716.  
  717. {                   if chr(FLD_VALUE_TYPE) == "C" then}
  718.   fld_name = IIF( ISBLANK( TRIM( fld_name)), fld_name, TRIM( fld_name))
  719. {                   endif}
  720.   SEEK fld_name
  721.  
  722.   IF .NOT. ll_exact{tabto(41)}&& Restore SET EXACT to org. value
  723.     SET EXACT OFF
  724.   ENDIF
  725.  
  726.   IF .NOT. FOUND()
  727.  
  728.     DEFINE POPUP {get_popname(FLD_OK_COND)} FROM \
  729. {         if trow_positn < max_pop_row then
  730.              trow_positn + 1},{tcol_positn} ;
  731.         TO {scrn_size-1},{tcol_positn + len(FLD_TEMPLATE) + 1} ;
  732. {         else
  733.              trow_positn - 11},{tcol_positn} ;
  734.         TO {trow_positn - 1},{tcol_positn + len(FLD_TEMPLATE) + 1} ;
  735. {         endif}
  736.         PROMPT FIELD {prompt_field} ;
  737.         MESSAGE {select_msg1}
  738.  
  739.     ON SELECTION POPUP {get_popname(FLD_OK_COND)} DEACTIVATE POPUP
  740.  
  741. {                        if chr(FLD_VALUE_TYPE) == "C" then}
  742.     KEYBOARD TRIM(fld_name)
  743. {                   endif}
  744.     SAVE SCREEN TO temp
  745. {                   if is_shadow(FLD_OK_COND) and
  746.                        ok_coordinates( flds, 4, 1, bad_shadow ) then
  747. }
  748.     DO shadowg WITH {get_pop_shadow(FLD_TEMPLATE);}
  749.  
  750. {                   endif
  751. }
  752.     ACTIVATE POPUP {get_popname(FLD_OK_COND)}
  753.  
  754.     rtn_fld = PROMPT(){tabto(41)}&& Get user choice from pick list
  755.     ln_bar = BAR(){tabto(41)}&& Capture bar number to check for esc
  756.  
  757.     RELEASE POPUP {get_popname(FLD_OK_COND)}
  758.  
  759.     RESTORE SCREEN FROM temp
  760.  
  761.     IF ln_bar <> 0
  762.       @ {trow_positn},{tcol_positn} GET rtn_fld \
  763. {        if Ok_Template(flds) then}
  764. PICTURE {picture_for_get(flds);} \
  765. {           outcolor()}
  766. {        endif}
  767.  
  768.       CLEAR GETS
  769.  
  770.       REPLACE {cap_first(FLD_FILENAME)}->{cap_first(FLD_FIELDNAME)} WITH \
  771. {        if chr(FLD_VALUE_TYPE) == "C" then}
  772. rtn_fld
  773. {        else}
  774. VAL(rtn_fld)
  775. {        endif}
  776.  
  777.       ll_return = .T.
  778.     ELSE
  779.       ll_return = .F.
  780. {
  781.                     if !is_required(FLD_OK_COND) then
  782. }
  783.       IF ISBLANK(fld_name){tabto(41)}&& Not a required field, so return
  784.         ll_return = .T.
  785.       ENDIF
  786.  
  787. {
  788.                     endif
  789. }
  790.     ENDIF
  791.  
  792.   ELSE
  793.     ll_return = .T.
  794.   ENDIF
  795.  
  796.   IF .NOT. ISBLANK( lc_order ){tabto(41)}&& If there was a order on lookup file
  797.     SET ORDER TO ( lc_order ){tabto(41)}&& Set it back to its original setting
  798.   ENDIF
  799.  
  800.   SELECT (lc_alias){tabto(41)}&& Go back to the edit file
  801.  
  802.   IF ll_esc
  803.     SET ESCAPE ON
  804.   ENDIF
  805. RETURN (ll_return)
  806. *-- EOP: {get_udfname(FLD_FIELDNAME)}
  807.  
  808. {
  809.                endif
  810.           next flds
  811.           print("*"+replicate("-",78)+crlf);}
  812.  
  813. {    endif
  814.      return;
  815. // eof - make_pop_code()
  816. enddef
  817.  
  818. //--------------------------------------------------------------
  819. define make_help_code()
  820. //------------------------------------
  821. // Make procedures for the help system
  822. //------------------------------------
  823. if is_help then
  824.      // If the udf file has not already been created, make it.
  825.     if not udf_file then
  826.        if !make_udf() then 
  827.            return 0;
  828.        endif
  829.        // Put up the UDF header
  830.        udf_header()
  831.     endif
  832.     // Make procedures for the help system
  833.     make_help()
  834. endif
  835. if is_help or is_popup then
  836.    // Make shadow procedures
  837.    make_shadow_procs()
  838. endif
  839. return;
  840. enddef
  841.  
  842. //--------------------------------------------------------------
  843. define header()
  844. // Print Header in program
  845.   var len_filename,
  846.       file_name;
  847.  
  848.   file_name = filename(fmt_name);
  849.   len_filename = len( file_name );
  850.   if substr( file_name, len_filename, 1 ) == "." then
  851.     file_name = substr( file_name, 1, len_filename - 1 ) + ".FMT";
  852.   else
  853.     file_name = file_name + ".FMT";
  854.   endif
  855. }
  856. *{replicate( "-", 69)}
  857. * Name.......: {file_name}
  858. * Date.......: {ltrim( substr( date(),1,8))}
  859. * Version....: dBASE {db_version_no}, Format
  860. * Notes......: Format files use "" as delimiters!
  861. *{replicate( "-", 69)}
  862. {
  863. enddef
  864.  
  865. //--------------------------------------------------------------
  866. define udf_header()
  867. // Print Header in UDF program
  868.   var len_filename,
  869.       file_name;
  870.  
  871.   file_name = filename(fmt_name);
  872.   len_filename = len( file_name );
  873.   if substr( file_name, len_filename, 1 ) == "." then
  874.     file_name = substr( file_name, 1, len_filename - 1 ) + ".FMT";
  875.   else
  876.     file_name = file_name + ".FMT";
  877.   endif
  878. }
  879. *{replicate( "-", 69)}
  880. * Name....: U_{rtrim(substr(name,1,6))}.PRG
  881. * Date....: {ltrim(SUBSTR(date(),1,8))}
  882. * Version.: dBASE {db_version_no}, Procedure for Format 
  883. * Notes...: Procedure file for VALID POPUPs and/or Context Sensitive Help
  884. *           for {file_name}
  885. { if master_file then}
  886. *           The Master file for the form is assumed to be {master_file}.
  887. { endif}
  888. *{replicate( "-", 69)}
  889. { lmarg(offset)}
  890. PRIVATE ll_oldtalk
  891. IF SET( "TALK" ) = "ON"
  892.   SET TALK OFF
  893.   ll_oldtalk = .T.
  894. ELSE
  895.   ll_oldtalk = .F.
  896. ENDIF
  897.  
  898. *-- {can_not_run}
  899. DO _Err_Box WITH "{can_not_run}"
  900.  
  901. IF ll_oldtalk
  902.   SET TALK ON
  903. ENDIF
  904. {   lmarg(0)}
  905. RETURN
  906.  
  907.  
  908. {
  909. enddef
  910.  
  911. //--------------------------------------------------------------
  912. define ok_template(cur)
  913.      if cur.FLD_TEMPLATE && !(chr(cur.FLD_VALUE_TYPE) == "D" ||
  914.                               chr(cur.FLD_VALUE_TYPE) == "M" ||
  915.                               chr(cur.FLD_VALUE_TYPE) == "G" ||
  916.                               chr(cur.FLD_VALUE_TYPE) == "B" 
  917.                   ) then
  918.         return 1;
  919.      else
  920.         return 0;
  921.      endif
  922. enddef
  923.  
  924. //--------------------------------------------------------------
  925. define ok_coordinates(cur,              // Current cursor
  926.                       xtra_width,       // Additional width to check ie, shadow
  927.                       want_message,     // Display message flag 0:No 1:Yes
  928.                       message)          // Message to display to user
  929.      // Check to see if coordinates of popup or shadow will fit on screen
  930.      // based on the dimensions of the current field
  931.      if nul2zero(cur.COL_POSITN) + len(cur.FLD_TEMPLATE) + xtra_width > 80 then
  932.         if want_message then
  933.            beep(2)                      // UDF in builtin.def
  934.            cls()
  935.            say_center(10,"Error on Field: " + cur.FLD_FIELDNAME)
  936.            say_center(12, message)
  937.            pause(any_key)
  938.         endif
  939.         return 0;
  940.      else
  941.         return 1;
  942.      endif
  943. enddef
  944.  
  945. //--------------------------------------------------------------
  946. define getcolor(f_display,         // Color of the current field
  947.                 f_editable         // Field is SAY or GET
  948.                )
  949.  // Determines the color from f_display and f_editable (GET or SAY)
  950.  enum  Foreground  =   7,
  951.        Intensity   =   8,  // Color
  952.        Background  = 112,
  953.        MIntensity  = 256,
  954.        Reverse     = 512,  // Mono
  955.        Underline   =1024,
  956.        Blink       =2048,
  957.        default     =32768; // Screen set to default
  958.  
  959.  var forgrnd, enhanced, backgrnd, blnk, underln, revrse, use_colors, incolor;
  960.  incolor=""
  961.  
  962.  use_colors  = default & f_display
  963.  forgrnd  = Foreground & f_display
  964.  enhanced = (Intensity & f_display) || (MIntensity & f_display)
  965.  backgrnd = Background & f_display
  966.  blnk     = Blink  & f_display
  967.  underln  = Underline & f_display
  968.  revrse   = Reverse & f_display
  969.  
  970.  if not use_colors then // Use system colors, no colors set in designer
  971.  
  972.     if backgrnd then backgrnd = backgrnd/16 endif
  973.  
  974.     if (display != mono and display != mono43) then
  975.        case forgrnd of
  976.         0: incolor = "n"
  977.         1: incolor = "b"
  978.         2: incolor = "g"
  979.         3: incolor = "bg"
  980.         4: incolor = "r"
  981.         5: incolor = "rb"
  982.         6: incolor = "gr"
  983.         7: incolor = "w"
  984.        endcase
  985.     else
  986.        incolor = "w"
  987.     endif
  988.  
  989.     if revrse then
  990.        incolor = incolor + "i"
  991.     endif
  992.     if underln then
  993.        incolor = incolor + "u"
  994.     endif
  995.     if enhanced then
  996.        incolor = incolor + "+"
  997.     endif
  998.     if blnk then
  999.        incolor = incolor + "*"
  1000.     endif
  1001.  
  1002.     incolor = incolor + "/"
  1003.  
  1004.     if (display != mono and display != mono43) then
  1005.        case backgrnd of
  1006.         0: incolor = incolor + "n"
  1007.         1: incolor = incolor + "b"
  1008.         2: incolor = incolor + "g"
  1009.         3: incolor = incolor + "bg"
  1010.         4: incolor = incolor + "r"
  1011.         5: incolor = incolor + "rb"
  1012.         6: incolor = incolor + "gr"
  1013.         7: incolor = incolor + "w"
  1014.        endcase
  1015.     else
  1016.        incolor = incolor + "n"
  1017.     endif
  1018.  
  1019.     if f_editable and incolor then
  1020.        incolor = incolor + "," + incolor
  1021.     endif
  1022.  
  1023.  endif // use no colors
  1024.  return alltrim(incolor);
  1025. enddef
  1026.  
  1027. //--------------------------------------------------------------
  1028. define outbox(mbox,            // Border type
  1029.               mchar            // Special character of border
  1030.              )
  1031.    // Output the of Box border and character if any
  1032.    var result;
  1033.    case mbox of
  1034.       0: result = " " // single
  1035.       1: result = " DOUBLE "
  1036.       2: result = " CHR("+mchar+") "
  1037.    endcase
  1038.    return result;
  1039. enddef
  1040.  
  1041. //--------------------------------------------------------------
  1042. define outcolor()
  1043.   // Output the of color of the @ SAY GET or Box
  1044.   var result;
  1045.   result = "";
  1046.   if len(color) > 0 then
  1047.      if color_flg then
  1048.         // If flag is set output a dBASE continuation ";"
  1049.         result = ";" + crlf + space(3)
  1050.      endif
  1051.      result = result + "COLOR " + color + " "
  1052.   endif
  1053.   return result;
  1054. enddef
  1055.  
  1056. //--------------------------------------------------------------
  1057. define window_def(cur)
  1058.    // Build dBASE window command
  1059.    var result;
  1060.    result = "wndow" + wnd_cnt + " FROM " + Box_Coordinates(cur);
  1061.    result = result + outbox(cur.BOX_TYPE, cur.BOX_SPECIAL_CHAR);
  1062.    color = getcolor(cur.FLD_DISPLAY, cur.FLD_EDITABLE);
  1063.    result = result + outcolor();
  1064.    return result;
  1065. enddef
  1066.  
  1067. //--------------------------------------------------------------
  1068. define box_coordinates(cur)             // Pass in foreach cursor
  1069. //
  1070. // Build box coordinates for a dBASE window command
  1071. //
  1072.   var result, temp_page, line_cnt, cur_box_top, cur_row_positn,
  1073.       scrn_num4_win, scrn_num4_fld, cur_box_left;
  1074.  
  1075.   cur_box_top    = nul2zero(cur.BOX_TOP);
  1076.   cur_row_positn = nul2zero(cur.ROW_POSITN);
  1077.   cur_box_left   = nul2zero(cur.BOX_LEFT);
  1078.   
  1079.   if cur.FLD_MEM_TYP then                   // If MEMO window
  1080.     scrn_num4_win = cur_box_top / scrn_size;
  1081.     scrn_num4_fld = cur_row_positn / scrn_size;
  1082.     if scrn_num4_win != scrn_num4_fld then  // If window not on same screen
  1083.       cur_box_top = ( cur_box_top % scrn_size ) + scrn_size + 1;
  1084.     endif
  1085.   endif
  1086.  
  1087.   temp_page = cur_box_top / scrn_size;
  1088.   line_cnt = (scrn_size * temp_page) + (1 * temp_page);
  1089.  
  1090.   result = cur_box_top - line_cnt +",";
  1091.   result = result + cur_box_left + " TO ";
  1092.   temp = cur_box_top + cur.BOX_HEIGHT - line_cnt - 1;
  1093.   if temp > scrn_size then
  1094.     temp = scrn_size;
  1095.   endif
  1096.   result = result + temp + "," + ( cur_box_left + cur.BOX_WIDTH - 1 );
  1097.   return result;
  1098. enddef
  1099.  
  1100.  
  1101. //--------------------------------------------------------------
  1102. define carry_flds()
  1103.    // Build dBASE SET CARRY command
  1104.    carry_len = carry_lent = 13
  1105.    carry_first = 0
  1106.    foreach FLD_ELEMENT flds
  1107.       if FLD_CARRY then
  1108.          carry_len = carry_len + len(FLD_FIELDNAME + ",")
  1109.          carry_lent = carry_lent + len(FLD_FIELDNAME + ",")
  1110.          if carry_lent > 1000 then
  1111.             print(crlf + "SET CARRY TO ")
  1112.             carry_len = carry_lent = 13
  1113.          endif
  1114.          if carry_len > 75 then print(";" + crlf + "  ")  carry_len = 2 endif
  1115.          temp = cap_first(FLD_FIELDNAME)
  1116.          if !carry_first then
  1117.             print(temp)
  1118.             carry_first = 1
  1119.          else
  1120.             print("," + temp)
  1121.          endif
  1122.       endif
  1123.     next flds
  1124.     print(" ADDITIVE");
  1125.  return;
  1126. enddef
  1127.  
  1128. //--------------------------------------------------------------
  1129.  
  1130. define make_fmt()
  1131.    // Attempt to create program (fmt) file.
  1132.    default_drv = strset(_defdrive)  // grab default drive from dBASE
  1133.    fmt_name = FRAME_PATH + NAME     // Put path on to object name
  1134.    if not fileok(fmt_name) then
  1135.       if !default_drv then
  1136.          fmt_name = NAME
  1137.       else
  1138.          fmt_name = default_drv + ":" + NAME
  1139.       endif
  1140.    endif
  1141. //   fmt_name = upper(fmt_name)
  1142.    if not create(fmt_name+".fmt") then
  1143.         pause(fileroot(fmt_name) +".fmt" + read_only + any_key)
  1144.         return 0;
  1145.      endif
  1146.    return 1;
  1147. enddef
  1148. //--------------------------------------------------------------
  1149.  
  1150. define make_udf()
  1151.    // Attempt to create dBASE procedure (prg) file.
  1152.    var udf_root_file_name;
  1153.    udf_root_file_name =  frame_path + "u_" + rtrim(substr(name,1,6))
  1154.    if not create( udf_root_file_name + ".prg") then
  1155.       pause(udf_root_file_name + ".prg" + read_only + any_key)
  1156.       return 0;
  1157.    endif
  1158.    // Force dBASE to recompile the .prg
  1159.    fileerase(udf_root_file_name + ".DBO")
  1160.    udf_file = 1 // Global flag to determine if UDF file was created
  1161.    return 1;
  1162. enddef
  1163.  
  1164. //--------------------------------------------------------------
  1165. define check_for_popups()
  1166. // Check for "popup" string for this fmt file
  1167. foreach FLD_ELEMENT flds
  1168.     if at("POPUP", upper(ltrim(FLD_OK_COND))) == "2" then
  1169.        is_popup = 1
  1170.        exit
  1171.     endif
  1172. next flds
  1173. return is_popup;
  1174. enddef
  1175.  
  1176. //--------------------------------------------------------------
  1177. define check_for_help()
  1178.    // Check for help support for this fmt file
  1179.    // Looking for a .dBF with the same name as the .fmt file
  1180.    hlp_name = frame_path + substr(fileroot(fmt_name), 1, 6) + "_H"
  1181.  
  1182.    if fileexist(hlp_name + ".dbf") and fileexist(hlp_name + ".dbt") then
  1183.       is_help = 1      // Global flag for help support
  1184.    endif
  1185. return is_help;
  1186. enddef
  1187.  
  1188. define new_page(cur)               // Pass in foreach cursor
  1189. //----------------------------------------------------------------------
  1190. // NAME
  1191. //   New_Page - Check for a page break and adjusts line_cnt and page_cnt
  1192. //
  1193. // DESCRIPTION
  1194. //   New_Page() will determine the top line on the screen for the
  1195. //   object specified by the cursor <cur> and is assigned to the
  1196. //   global variable, <line_cnt>.  If the object is on a new page, 
  1197. //   the global variable, <page_cnt>, is adjusted to the new page.
  1198. //   
  1199. //   New_Page() will return a TRUE value if a page break occured, 
  1200. //   otherwise it will return a FALSE value.
  1201. //   
  1202. // EXAMPLE
  1203. //     foreach ELEMENT k
  1204. //       if new_page( k )
  1205. //         ... page break occured
  1206. //       endif
  1207. //     next k;
  1208. //
  1209. // GLOBAL VARIABLES
  1210. //   line_cnt = line number for the top line on the given page
  1211. //   page_cnt = page number for the object, starting at 1
  1212. //
  1213. //----------------------------------------------------------------------
  1214.   var cur_row_positn, 
  1215.       temp_page;
  1216.  
  1217.   cur_row_positn = nul2zero( cur.ROW_POSITN )
  1218.  
  1219.   if cur_row_positn - line_cnt > scrn_size then
  1220.     temp_page = cur_row_positn / scrn_size
  1221.     line_cnt = (scrn_size * temp_page) + (1 * temp_page)
  1222.     page_cnt = temp_page + 1
  1223.     return TRUE;
  1224.   endif
  1225. return FALSE;
  1226. enddef
  1227.  
  1228. //--------------------------------------------------------------
  1229. define parse_line( before,         // Out: chars before the look_for string
  1230.                    input,          // In:  line being parsed
  1231.                    look_for        // In:  string searched for
  1232.                  )                 // Rtn: chars after the look_for string
  1233. // If the look_for sting is not found, the before sting will equal the
  1234. // input string, and the returned value will be NUL
  1235.      var location;
  1236.  
  1237.      location = at(look_for, UPPER(input))
  1238.      if location == 0 then
  1239.           before = input
  1240.           return ( "" );
  1241.      endif
  1242.  
  1243.      before = substr( input, 1, location-1)
  1244.      return ( substr( input,
  1245.                       location+len(look_for),
  1246.                       len(input)
  1247.                     )
  1248.             );
  1249.  
  1250. // end: parse_line()
  1251. enddef
  1252.  
  1253. //--------------------------------------------------------------
  1254. // Parsing routines for pulling objects out of the VALID string
  1255. // "POPUP" = "file->fld_name ORDER key_fld REQ"
  1256. // 1234567890123456789012345678901234567890123
  1257. //            1         2         3         4
  1258. define get_file(valid_str)
  1259.      var  s_arrow,            // String "->"
  1260.           test,
  1261.           s_equal,            // String "="
  1262.           next_alpha,
  1263.           at_alias,
  1264.           s_before,           // String before the searched for item
  1265.           r_target,           // Remainder of the target string after item
  1266.           use_name;           // Return for file
  1267.  
  1268.      s_arrow = "->"
  1269.      s_equal = "="
  1270.      r_target = parse_line( s_before, valid_str, s_equal )      // ' "file->...'
  1271.      next_alpha = atalpha(r_target)                             // 3
  1272.      at_alias = at(s_arrow, r_target)                           // 7
  1273.      use_name = substr(r_target,next_alpha,at_alias-next_alpha) // 'file'
  1274.  
  1275.      return cap_first(use_name);
  1276. enddef
  1277.  
  1278. //--------------------------------------------------------------
  1279. define get_key(valid_str)
  1280.      var  s_order,            // String "ORDER "
  1281.           at_space,
  1282.           q_space,
  1283.           s_before,           // String before the searched for item
  1284.           r_target,           // Remainder of the target string after item
  1285.           order_tag;          // Search TAG to ORDER BY
  1286.  
  1287.      s_order = "ORDER "
  1288.      r_target = parse_line( s_before, valid_str, s_order ) // 'key_fld REQ'
  1289.      at_space = at(" ",r_target)
  1290.      if at_space == 0 then
  1291.           order_tag = substr(r_target, 1, len(r_target)-1) // 'key_fld"'
  1292.      else
  1293.           q_space = at('"',r_target)
  1294.           if q_space != 0 && q_space < at_space then
  1295.                order_tag = substr(r_target, 1, q_space-1)
  1296.           else
  1297.                order_tag = substr(r_target, 1, at_space-1)
  1298.           endif
  1299.      endif
  1300.      return cap_first(order_tag);
  1301. enddef
  1302.  
  1303. //--------------------------------------------------------------
  1304. define get_field(valid_str)
  1305.      var  s_arrow,            // String "->"
  1306.           at_space,
  1307.           s_before,           // String before the searched for item
  1308.           r_target,           // Remainder of the target string after item
  1309.           fld_name;           // Field name to lookup in target file
  1310.  
  1311.      s_arrow = "->"
  1312.      r_target = parse_line( s_before,
  1313.                             valid_str, s_arrow ) // 'fld_name ORDER...'
  1314.      at_space = at(" ",r_target)
  1315.  
  1316.      fld_name = ( at_space == 0 ? r_target : substr(r_target, 1, at_space-1) );
  1317.  
  1318.      return cap_first(fld_name);
  1319. enddef
  1320.  
  1321. //--------------------------------------------------------------
  1322. define get_popname(valid_str)
  1323.      // Create popup name
  1324.      return ( lower( "u_" + substr( get_field( valid_str),1,6) ) );
  1325. enddef
  1326.  
  1327. //--------------------------------------------------------------
  1328. define get_pop_shadow(field_template)   // Pass in FLD_TEMPLATE to deter. shadow
  1329.      if trow_positn < max_pop_row then
  1330.         trow_positn + 1},{tcol_positn},{scrn_size-1},{tcol_positn+len(Field_template)+1}
  1331. {    else
  1332.         trow_positn - 11},{tcol_positn},{trow_positn - 1},{tcol_positn+len(Field_template)+1}
  1333. {    endif
  1334.      return;
  1335. enddef
  1336.  
  1337. //---------------------------------------------------------------
  1338. define get_udfname(fld_str)
  1339.      // Create UDF name
  1340.      return cap_first( "u_" + substr( fld_str,1,6) );
  1341. enddef
  1342.  
  1343. //--------------------------------------------------------------
  1344. define is_required(valid_str)
  1345.      // Determines if the field is required before moving to the next field
  1346.      return ( ( at(" REQ ",  upper(valid_str)) ? 1 : 0 ) or 
  1347.               ( at(" REQ\"", upper(valid_str)) ? 1 : 0 )
  1348.             );
  1349. enddef
  1350.  
  1351. //--------------------------------------------------------------
  1352. define is_shadow(valid_str)
  1353.      // Determines if the user wants shadowing for popup
  1354.      return ( ( at(" SHADOW ",  upper(valid_str)) ? 1 : 0 ) or 
  1355.               ( at(" SHADOW\"", upper(valid_str)) ? 1 : 0 )
  1356.             );
  1357. enddef
  1358.  
  1359. //--------------------------------------------------------------
  1360. define make_shadow_procs()
  1361.      // Make the dBASE code for shadowing
  1362. }
  1363. PROCEDURE Shadowg
  1364. *{replicate("-",69)}
  1365. * DESCRIPTION
  1366. *   Displays shadow that grows.  Specify the same coord and the
  1367. *   window or popup to shadow.
  1368. *{replicate("-",69)}
  1369.   PARAMETER x1,y1,x2,y2
  1370.   PRIVATE   x1,y1,x2,y2
  1371.  
  1372.   x0 = x2+1
  1373.   y0 = y2+2
  1374.   dx = 1
  1375.   dy = (y2-y1) / (x2-x1)
  1376.   DO WHILE x0 <> x1 .OR. y0 <> y1+2
  1377.     @ x0,y0 FILL TO x2+1,y2+2 COLOR n+/n
  1378.     x0 = IIF(x0<>x1,x0 - dx,x0)
  1379.     y0 = IIF(y0<>y1+2,y0 - dy,y0)
  1380.     y0 = IIF(y0<y1+2,y1+2,y0)
  1381.   ENDDO
  1382.  
  1383. RETURN
  1384. *-- EOP: shadowg
  1385.  
  1386. {    return;
  1387. enddef
  1388.  
  1389.  
  1390. define make_general_procs()
  1391. //--------------------------------------------------------------
  1392. // Make the dBASE core routines
  1393. //--------------------------------------------------------------
  1394. }
  1395. PROCEDURE _Err_Box
  1396. PARAMETERS pc_msg
  1397. *----------------------------------------------------------------------------
  1398. * NAME
  1399. *   _Err_Box - Display an error box
  1400. *
  1401. * SYNOPSIS
  1402. *   DO _Err_Box WITH <pc_msg>
  1403. *
  1404. * DESCRIPTION
  1405. *   _Err_Box will display the <pc_msg> string in a box and prompt the
  1406. *   user to press any key to continue processing.  _Err_Box will display
  1407. *   the message based on the length of <pc_msg>.
  1408. *
  1409. * PARAMETERS
  1410. *   pc_msg - the error message to display in the box.  If the length is
  1411. *            greater than 76, the trailing part is chopped off.
  1412. *
  1413. * EXAMPLE
  1414. *   DO _Err_Box WITH "Incorrect window size"
  1415. *   Displays the message in a window as follows at row 9 on the screen:
  1416. *                      +------------------------------+
  1417. *                      |                              |
  1418. *                      |    Incorrect window size     |
  1419. *                      |                              |
  1420. *                      | Press any key to continue... |
  1421. *                      |                              |
  1422. *                      +------------------------------+
  1423. *   Note that the width of the window will increase to accommodate a longer
  1424. *   message string.
  1425. *
  1426. * LIMITATIONS
  1427. *   Truncates the message after 76 characters.  Assumes an 80 character
  1428. *   wide screen.  Looks best with SET CURSOR OFF.
  1429. *
  1430. *----------------------------------------------------------------------------
  1431.  
  1432.   PRIVATE lc_anykey, lc_msg, lc_msglen, lc_win, ln_press, ln_width, ll_trap,;
  1433.           ll_escape
  1434.  
  1435.   lc_anykey = [Press any key to continue...]
  1436.   ln_press  = LEN( lc_anykey )
  1437.   lc_win = WINDOW()                     && Currently activated window if any
  1438.   lc_msg = LTRIM( RTRIM( pc_msg ) )     && Trimmed message
  1439.   ln_msglen = LEN( lc_msg )             && Trimmed length of message
  1440.   ln_width = 0                          && Width of display area in window.
  1441.   ll_escape = SET("ESCAPE") = "ON"
  1442.   IF TYPE( "FXL_DEV" ) = "L" .AND. FXL_DEV
  1443.     SET ESCAPE ON
  1444.   ELSE
  1445.     SET ESCAPE OFF
  1446.   ENDIF
  1447.  
  1448.   *-- Determine the width needed for the window:
  1449.   IF ln_msglen <= ln_press
  1450.     ln_width = ln_press
  1451.   ELSE
  1452.     *-- Make sure the message fits in the window:
  1453.     IF ln_msglen > 76
  1454.       lc_msg = LEFT( lc_msg, 76 )
  1455.       ln_msglen = 76
  1456.     ENDIF
  1457.     ln_width = ln_msglen
  1458.   ENDIF
  1459.   DEFINE WINDOW _err_box FROM 9, ((76 - ln_width) + .5) / 2 ;
  1460.                 TO 15, (ln_width + 83) / 2 DOUBLE
  1461.   ln_width = ( ln_width + 2 )
  1462.  
  1463.   *-- Display the message and prompt to the window and wait for a key press
  1464.   ACTIVATE WINDOW _err_box
  1465.   @ 1, ( ln_width - ln_msglen ) / 2 SAY lc_msg
  1466.   @ 3, ( ln_width - ln_press ) / 2 SAY lc_anykey
  1467.   SET CONSOLE OFF                       && For mouse click recognition
  1468.   WAIT
  1469.   SET CONSOLE ON
  1470.  
  1471.   *-- Clean up the window display and reactivate the previous window
  1472.   RELEASE WINDOW _err_box
  1473.   IF ISBLANK( lc_win )
  1474.     ACTIVATE SCREEN
  1475.   ENDIF
  1476.  
  1477.   IF ll_escape
  1478.     SET ESCAPE ON
  1479.   ELSE
  1480.     SET ESCAPE OFF
  1481.   ENDIF
  1482.  
  1483. RETURN
  1484. *-- EOP: _Err_Box WITH pc_msg
  1485.  
  1486.  
  1487. FUNCTION _Rat
  1488. PARAMETERS pc_source, pc_target
  1489. *--------------------------------------------------------------------
  1490. * NAME
  1491. *   _RAT - Version of AT() that starts from right.
  1492. *
  1493. * SYNOPSIS
  1494. *   _RAT( <expC>, <expC> )
  1495. *
  1496. * DESCRIPTION
  1497. *   _RAT() takes two arguments, a source string and a target
  1498. *   string.  It searches for the first occurrence of the source
  1499. *   within the target beginning on the right end of the string,
  1500. *   and returns an integer representing the first character
  1501. *   position of the matching occurrence.
  1502. *
  1503. *   If the source string is not contained within the target
  1504. *   string, if the source string is longer than the target
  1505. *   string, or if the source string is null, 0 is returned.
  1506. *
  1507. * PARAMETER(S)
  1508. *   The first parameter is the string to find.  The second
  1509. *   parameter is the string to search in.  In theory, any
  1510. *   character expression should be legal.
  1511. *
  1512. * EXAMPLE(S)
  1513. *
  1514. *   ? _RAT("A","ABABA")                      && Returns 5
  1515. *   lc_var = _RAT("A test","A test A test")  && Returns 8
  1516. *   ? _RAT("Long string","short")            && Returns 0
  1517. *
  1518. *--------------------------------------------------------------------
  1519.  
  1520.    PRIVATE lc_len
  1521.  
  1522.    m->lc_len = LEN( m->pc_target )
  1523.  
  1524.    DO WHILE m->lc_len > 0
  1525.      IF m->pc_source $ SUBSTR(m->pc_target, m->lc_len)
  1526.        EXIT
  1527.      ELSE
  1528.        m->lc_len = (m->lc_len - 1)
  1529.      ENDIF
  1530.    ENDDO
  1531.  
  1532.    RETURN m->lc_len
  1533.  
  1534. *-- EOF: _Rat( pc_source, pc_target )
  1535.  
  1536. {    return;
  1537. enddef
  1538.  
  1539. //--------------------------------------------------------------
  1540. define make_help()
  1541. // Make the dBASE code for help
  1542. }
  1543. PROCEDURE Help
  1544. PARAMETER lc_var
  1545. *{replicate("-",69)}
  1546. * DESCRIPTION
  1547. *   Activates the HELP window
  1548. *{replicate("-",69)}
  1549. { lmarg(offset)}
  1550. PRIVATE ALL LIKE ??_*
  1551. ON KEY LABEL F1{tabto(41)}&& Dsiable the F1 key during help
  1552. IF .NOT. FILE("{fileroot(hlp_name)}.dbf")
  1553.   *-- Help file has been deleted or can't be found
  1554.   DO _Err_Box WITH "{help_err1}" + "{fileroot(hlp_name)}.dbf"
  1555.   RETURN
  1556. ENDIF
  1557. ll_cat = SET( "CATALOG" ) = "ON"
  1558. SET CATALOG OFF
  1559.  
  1560. SET CURSOR OFF
  1561.  
  1562. *-- Select workarea and open Help dbf
  1563. lc_area = ALIAS()
  1564.  
  1565. *-- Open the HELP dbf file for the form
  1566. SELECT SELECT()
  1567. USE {fileroot(hlp_name)} ORDER fld_name NOUPDATE NOLOG
  1568.  
  1569. ll_exact = SET("EXACT") = "ON"
  1570. SET EXACT ON
  1571. SEEK lc_var{tabto(41)}&& Search for the field name in help
  1572. IF .NOT. ll_exact
  1573.   SET EXACT OFF
  1574. ENDIF
  1575. IF FOUND()
  1576.   *-- Define the coord for the help window
  1577.   ln_t = 5
  1578.   ln_l = 6
  1579.   ln_b = 15
  1580.   ln_r = 74
  1581.   ON KEY LABEL F3 DO Toggle
  1582.   DEFINE WINDOW z_help FROM ln_t+1, ln_l+2 TO ln_b-1, ln_r-2 NONE
  1583.   ON ERROR lc_error=error()
  1584.   SAVE SCREEN TO zz_help
  1585.  
  1586.   *-- Make Help Box
  1587.   DO shadowg WITH ln_t, ln_l, ln_b, ln_r
  1588.   @ ln_t+1, ln_l+1 CLEAR TO ln_b-1, ln_r-1
  1589.   @ ln_t, ln_l TO ln_b, ln_r DOUBLE
  1590.  
  1591.   ln_memline = SET("MEMO")
  1592.   SET MEMOWIDTH TO 65
  1593.   IF MEMLINES(fld_help) > 9
  1594.     @ ln_t+1,ln_r SAY CHR(24)
  1595.     @ ln_b-1,ln_r SAY CHR(25)
  1596.   ENDIF
  1597.   lc_string = CHR(185)+ [ Help for ] + TRIM(fld_headng) +[ ] + CHR(204)
  1598.   lc_message = IIF(MEMLINES(fld_help) > 9, ;
  1599.                   "{help_msg1 + help_msg2}", ;
  1600.                   "{help_msg2}" ;
  1601.                   )
  1602.  
  1603.   @ ln_t,CENTER(lc_string,80) SAY lc_string
  1604.   @ 0,0 GET fld_help OPEN WINDOW z_help MESSAGE lc_message
  1605.   READ
  1606.   SET MEMOWIDTH TO ln_memline
  1607.   ON ERROR
  1608.   ON KEY LABEL F3
  1609.   RELEASE WINDOW z_help
  1610.   RESTORE SCREEN FROM zz_help
  1611.   RELEASE SCREEN zz_help
  1612. ELSE
  1613.   DO _Err_Box WITH [{help_err2} ] + lc_var
  1614. ENDIF
  1615. SET MESSAGE TO
  1616. IF ll_cat
  1617.   SET CATALOG ON
  1618. ENDIF
  1619. SET CURSOR ON
  1620. USE{tabto(41)}&& Close help file
  1621. SELECT (lc_area){tabto(41)}&& Back to edit work area
  1622. ON KEY LABEL F1 DO Help WITH VARREAD()
  1623. {    lmarg(0)}
  1624. RETURN
  1625. *-- EOP: HELP
  1626.  
  1627.  
  1628. PROCEDURE Toggle
  1629. *{replicate("-",69)}
  1630. * DESCRIPTION
  1631. *   Toggles the Help message back to the original screen
  1632. *{replicate("-",69)}
  1633. {    lmarg(offset)}
  1634. PRIVATE ll_cons
  1635. SAVE SCREEN to Toggle
  1636. RESTORE SCREEN FROM zz_help
  1637. SET MESSAGE TO "Press any key..."
  1638. ll_cons = SET( "CONSOLE" ) = "ON"
  1639. SET CONSOLE OFF
  1640. WAIT
  1641. IF ll_cons
  1642.   SET CONSOLE ON
  1643. ENDIF
  1644. RESTORE SCREEN FROM Toggle
  1645. RELEASE SCREEN Toggle
  1646. SET MESSAGE TO "Scroll thru Help: Ctrl-Home   Exit Viewing Help: Ctrl-End   See Org. Screen: F3"
  1647. {    lmarg(0)}
  1648. RETURN
  1649. *-- EOP: Toggle
  1650.  
  1651.  
  1652. FUNCTION Center
  1653. PARAMETER lc_string, ln_width
  1654. *{replicate("-",69)}
  1655. * NAME
  1656. *   Center() - Provide column needed to center a string in a width
  1657. *
  1658. * DESCRIPTION 
  1659. *   The CENTER() function will return the starting column 
  1660. *   coordinate to center the <lc_string> string within a width of 
  1661. *   screen <ln_width>.  The width of the screen would normally be 
  1662. *   80 colunms, but could just as well be the width of a window.  
  1663. *   If there is an error condition, the returned result will equal 0.
  1664. *   If a numeric value is passed for the <expC> value, it will be 
  1665. *   converted to a string.
  1666. * EXAMPLES
  1667. *   @ 15,center(string,80) say string    
  1668. *   Will center the <string> withing 80 columns
  1669. *-----------------------------------------------------------------------------
  1670.   PRIVATE lc_result, lc_type
  1671.  
  1672.   IF .NOT. TYPE("ln_width") $ "FN"{tabto(41)}&& Force value to 0 for bad type
  1673.     lc_result = 0
  1674.   ELSE
  1675.  
  1676.     lc_type = TYPE("lc_string")
  1677.     DO CASE
  1678.       CASE lc_type = "C"
  1679.         lc_width = (ln_width/2)-(LEN(lc_string)/2)
  1680.       CASE lc_type $ "NF"
  1681.         lc_width = (ln_width/2)-(LEN(ALLTRIM(STR(lc_string)))/2)
  1682.       CASE lc_type = "L"
  1683.         lc_width = (ln_width/2)-(1.5){tabto(41)}&& .T. or .F. have fixed len of 3
  1684.       OTHERWISE                          
  1685.         lc_width = 0
  1686.     ENDCASE
  1687.   ENDIF
  1688.   
  1689.   IF lc_width < 0{tabto(41)}&& Force negative values to 0
  1690.     lc_width = 0
  1691.   ENDIF
  1692.  
  1693. RETURN ( lc_width )
  1694. *-- EOF: Center( lc_string, ln_width )
  1695.  
  1696. {return;
  1697. enddef
  1698.  
  1699. define output_set_proc_code()
  1700. }
  1701. *-- Set procedure to the lookup programs
  1702. ll_echo = SET( "ECHO" ) = "ON"
  1703. SET ECHO OFF
  1704.  
  1705. lc_proc = SET("procedure"){tabto(41)}&& Store procedure file name
  1706. IF FILE("{cap_first(udf_filename)}.prg") .OR. FILE("{cap_first(udf_filename)}.dbo")
  1707.   SET PROCEDURE TO {cap_first(udf_filename)}
  1708. ELSE
  1709.   lc_fullpath = SET("FULLPATH")
  1710.   SET FULLPATH ON
  1711.   lc_setfmt = SET("FORMAT")
  1712.  
  1713.   *-- Pull out the file path from the format file for a prefix
  1714.     lc_slash = IIF( LEFT( OS(), 3 ) = "DOS", "\", "/" )
  1715.  
  1716.     *-- Look for last slash in the string
  1717.     m->lc_len = LEN( lc_setfmt )
  1718.     DO WHILE m->lc_len > 0
  1719.       IF m->lc_slash $ SUBSTR(m->lc_setfmt, m->lc_len)
  1720.         EXIT
  1721.       ELSE
  1722.         m->lc_len = m->lc_len - 1
  1723.       ENDIF
  1724.     ENDDO
  1725.  
  1726.   lc_fullnam = LEFT( lc_setfmt, m->lc_len ) + "{cap_first(udf_filename)}"
  1727.   IF FILE( lc_fullnam + ".prg" ) .OR. FILE( lc_fullnam + ".dbo" )
  1728.     SET PROCEDURE TO ( lc_fullnam )
  1729.   ELSE
  1730.  
  1731.     *-- Display the error message in a windowed box
  1732.     PRIVATE lc_anykey, lc_msg, lc_msglen, lc_win, ln_press, ln_width, ll_trap,;
  1733.             ll_escape
  1734.  
  1735.     lc_anykey = [Press any key to continue...]
  1736.     ln_press  = LEN( lc_anykey )
  1737.     lc_msg = "{proc_err} {cap_first(udf_filename)} {file_err}"
  1738.     ln_msglen = LEN( lc_msg )
  1739.     ln_width = 0
  1740.     ll_escape = SET("ESCAPE") = "ON"
  1741.     SET ESCAPE OFF
  1742.  
  1743.     *-- Determine the width needed for the window:
  1744.     IF ln_msglen <= ln_press
  1745.       ln_width = ln_press
  1746.     ELSE
  1747.       *-- Make sure the message fits in the window:
  1748.       IF ln_msglen > 76
  1749.         lc_msg = LEFT( lc_msg, 76 )
  1750.         ln_msglen = 76
  1751.       ENDIF
  1752.       ln_width = ln_msglen
  1753.     ENDIF
  1754.     DEFINE WINDOW _err_box FROM 9, ((76 - ln_width) + .5) / 2 ;
  1755.                   TO 15, (ln_width + 83) / 2 DOUBLE
  1756.     ln_width = ( ln_width + 2 )
  1757.  
  1758.     *-- Display the message and prompt to the window and wait for a key press
  1759.     ACTIVATE WINDOW _err_box
  1760.     ? lc_msg AT ( ln_width - ln_msglen ) / 2 
  1761.     ?
  1762.     ? lc_anykey AT ( ln_width - ln_press ) / 2 
  1763.     SET CONSOLE OFF
  1764.     WAIT
  1765.     SET CONSOLE ON
  1766.  
  1767.     *-- Clean up the window display and reactivate the previous window
  1768.     RELEASE WINDOW _err_box
  1769.  
  1770.     IF ll_escape
  1771.       SET ESCAPE ON
  1772.     ELSE
  1773.       SET ESCAPE OFF
  1774.     ENDIF
  1775.  
  1776.   ENDIF
  1777.  
  1778.   IF lc_fullpath = "OFF"
  1779.     SET FULLPATH OFF
  1780.   ENDIF
  1781.  
  1782. ENDIF{tabto(41)}&&   UDF's won't run
  1783.  
  1784. {
  1785. return;
  1786. enddef
  1787.  
  1788. include "cm_udf.cod"  // Template language UDFs
  1789. // EOP FORM.COD
  1790. }
  1791.  
  1792.