home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a108 / 15.ddi / GENSCRN.PR_ / GENSCRN.bin
Encoding:
Text File  |  1994-03-10  |  285.8 KB  |  9,165 lines

  1. *:*****************************************************************************
  2. *:
  3. *: Procedure file: C:\FOXPROW\GENSCRN.PRG
  4. *:         System: GenScrn
  5. *:         Author: Microsoft Corp.
  6. *:      Copyright (c) 1990 - 1993 Microsoft Corp.
  7. *:  Last modified: 1/4/93 at 19:33:06
  8. *:
  9. *:      Documented              FoxDoc version 3.00a
  10. *:*****************************************************************************
  11. *
  12. * GENSCRN - Screen Code Generator.
  13. *
  14. * Copyright (c) 1990 - 1993 Microsoft Corp.
  15. * One Microsoft Way
  16. * Redmond, WA 98502
  17. *
  18. * Description:
  19. * This program generates code for objects designed and built with
  20. * FoxPro screen builder.
  21. *
  22. * Notes:
  23. * In this program, for clarity/readability reasons, we use variable
  24. * names that are longer than 10 characters.  Note, however, that only
  25. * the first 10 characters are significant.
  26. *
  27. PARAMETER m.projdbf, m.recno
  28. PRIVATE ALL
  29.  
  30. IF SET("TALK") = "ON"
  31.    SET TALK OFF
  32.    m.talkset = "ON"
  33. ELSE
  34.    m.talkset = "OFF"
  35. ENDIF
  36.  
  37. m.escape = SET("ESCAPE")
  38. ON ESCAPE
  39. SET ESCAPE OFF
  40. m.trbetween = SET("TRBET")
  41. SET TRBET OFF
  42. m.comp = SET("COMPATIBLE")
  43. SET COMPATIBLE FOXPLUS
  44. mdevice = SET("DEVICE")
  45. SET DEVICE TO SCREEN
  46.  
  47. *
  48. * Declare Global Constants
  49. *
  50. #DEFINE c_otscreen         1
  51. #DEFINE c_otworkarea       2
  52. #DEFINE c_otindex          3
  53. #DEFINE c_otrel               4
  54. #DEFINE c_ottext           5
  55. #DEFINE c_otline           6
  56. #DEFINE c_otbox            7
  57. #DEFINE c_otlist          11
  58. #DEFINE c_ottxtbut        12
  59. #DEFINE c_otradbut        13
  60. #DEFINE c_otchkbox        14
  61. #DEFINE c_otfield         15
  62. #DEFINE c_otpopup         16
  63. #DEFINE c_otpicture       17
  64. #DEFINE c_otinvbut        20
  65. #DEFINE c_otspinner       22
  66.  
  67. #DEFINE c_authorlen       45
  68. #DEFINE c_complen         45
  69. #DEFINE c_addrlen         45
  70. #DEFINE c_citylen         20
  71. #DEFINE c_statlen          5
  72. #DEFINE c_ziplen          10
  73. #DEFINE c_countrylen      40
  74.  
  75. #DEFINE c_sgsay            0
  76. #DEFINE c_sgget            1
  77. #DEFINE c_sgedit           2
  78. #DEFINE c_sgfrom           3
  79. #DEFINE c_sgbox            4
  80. #DEFINE c_sgboxd           5
  81. #DEFINE c_sgboxp           6
  82. #DEFINE c_sgboxc           7
  83.  
  84. #DEFINE c_dos     "DOS"
  85. #DEFINE c_windows "WINDOWS"
  86. #DEFINE c_mac     "MAC"
  87. #DEFINE c_unix    "UNIX"
  88.  
  89. * Determines whether SHOW snippets are checked for suspicious SHOW GETS statements
  90. #DEFINE c_checkshow        1
  91.  
  92. #DEFINE c_maxwinds        25
  93. #DEFINE c_maxpops         25
  94. #DEFINE c_maxscreens       5
  95. #DEFINE c_maxplatforms     4
  96. #DEFINE c_20scxflds          57
  97. #DEFINE c_scxflds         79
  98. #DEFINE c_pjxflds         31
  99. #DEFINE c_pjx20flds       33
  100.  
  101. #DEFINE c_esc            CHR(27)
  102. #DEFINE c_null            CHR(0)
  103. #DEFINE c_cret            CHR(13)
  104. #DEFINE c_lf            CHR(10)
  105. #DEFINE c_under            "_"
  106. #DEFINE c_single        "┌─┐│┘─└│"
  107. #DEFINE c_double        "╔═╗║╝═╚║"
  108. #DEFINE c_panel            "████████"
  109. #DEFINE c_fromone        1
  110. #DEFINE c_untilend        0
  111.  
  112. #DEFINE c_error_1        "Minor"
  113. #DEFINE c_error_2        "Serious"
  114. #DEFINE c_error_3        "Fatal"
  115.  
  116. #DEFINE c_aliaslen   10   && maximum alias length
  117.  
  118. #DEFINE c_premode            0
  119. #DEFINE c_postmode            1
  120.  
  121. #DEFINE c_userprecode        "*# USERPRECOMMAND"
  122. #DEFINE c_userpostcode        "*# USERPOSTCOMMAND"
  123.  
  124. IF _MAC
  125.    m.g_dlgface = "Geneva"
  126.    m.g_dlgsize = 10.000
  127.    m.g_dlgstyle = ""
  128. ELSE
  129.    m.g_dlgface = "MS Sans Serif"
  130.    m.g_dlgsize = 8.000
  131.    m.g_dlgstyle = "B"
  132. ENDIF
  133.  
  134. #DEFINE c_pathsep  "\"
  135.  
  136. #DEFINE c_genexpr    0
  137. #DEFINE c_gencode    1
  138. #DEFINE c_genboth    -1
  139.  
  140. #DEFINE c_therm1      5
  141. #DEFINE c_therm2     15
  142. #DEFINE c_therm3     35
  143. #DEFINE c_therm4     60
  144. #DEFINE c_therm5     65
  145. #DEFINE c_therm6     70
  146. #DEFINE c_therm7     95
  147.  
  148. #DEFINE c_all 1
  149. m.g_picext = "PCT"   && Mac picture
  150. m.g_bmpext = "BMP"   && Windows bitmap
  151. m.g_icnext = "ICN"   && Mac icon
  152. m.g_icoext = "ICO"   && Windows icon
  153.  
  154. m.g_genparams = PARAMETERS()
  155. *
  156. * Declare Variables
  157. *
  158. STORE "" TO m.cursor, m.consol, m.bell, m.exact, ;
  159.    m.safety, m.fixed, m.print, m.delimiters, m.unique, mudfparms, ;
  160.    m.fields, mfieldsto, m.mdecpoint, m.origpretext, m.mcollate, m.mmacdesk
  161. STORE 0 TO m.deci, m.memowidth
  162.  
  163. m.g_closefiles = .F.           && Generate code to close files?
  164. m.g_current    = ""            && current DBF
  165. m.g_defasch1   = 0               && Default color scheme 1
  166. m.g_defasch2   = 0               && Default color scheme 2
  167. m.g_defwin     = .F.           && Generate code to define windows?
  168. m.g_errlog     = ""               && Path + name of .ERR file
  169. m.g_homedir    = ""               && Application Home Directory
  170. m.g_idxfile    = 'idxfile.idx' && Index file
  171. m.g_itse       = c_null           && Designating character from #ITSEXPRESSION
  172. m.g_lastwindow = ""            && Name of last window defined
  173. m.g_keyno      = 0
  174. m.g_havehand = .F.
  175. m.g_redefi     = .F.           && Don't redefine windows
  176. m.g_screen     = 0             && Screen currently being generated.  Also used in error messages.
  177. m.g_nscreens   = 0             && Number of screens
  178. m.g_nwindows   = 0             && Number of unique windows in this platform
  179. m.g_multreads  = .F.           && Multiple reads?
  180. m.g_openfiles  = .F.           && Generate code to open files?
  181. m.g_orghandle  = -1            && File handle for ctrl file
  182. m.g_outfile    = ""            && Output file name
  183. m.g_projalias  = ""            && Project database alias
  184. m.g_projpath   = ""
  185. m.g_rddir      = .F.           && Is there a #READCLAUSES directive?
  186. m.g_windclauses= ""            && #WCLAUSES parameters for DEFINE WINDOW
  187. m.g_rddirno    = 0             && Number of 1st screen with #READ directive
  188. m.g_readcycle  = .F.           && READ CYCLE?
  189. m.g_readlock   = .F.           && READ LOCK/NOLOCK?
  190. m.g_readmodal  = .F.           && READ MODAL?
  191. m.g_readborder = .F.           && READ BORDER?
  192. m.g_relwin     = .F.           && Generate code to release windows?
  193. m.g_moddesktop = .F.
  194. m.g_snippcnt   = 0             && Count of snippets
  195. m.g_somepops   = .F.           && Any Generated popups?
  196. m.g_status     = 0
  197. m.g_thermwidth = 0             && Thermometer width
  198. m.g_tmpfile    = SYS(3)+".tmp" && Temporary file
  199. m.g_tmphandle  = -1            && File handle for tmp file
  200. m.g_windows    = .F.           && Any windows in screen files?
  201. m.g_withlist   = ""
  202. m.g_workarea   = 0
  203. m.g_genvers       = ""            && version we are generating for
  204. m.g_thisvers   = ""            && version we are running under now
  205. m.g_graphic    = .F.
  206. m.g_isfirstproc= .T.           && is this the first procedure emitted?
  207. m.g_procsmatch = .F.           && are cleanup snippets for all platforms identical
  208. m.g_noread     = .F.           && omit the read statement?
  209. m.g_noreadplain= .F.           && omit the read statement and the SET TALK TO.. statements?
  210. m.g_dualoutput = .F.           && generating for Mac on Windows (& etc.) ?
  211.  
  212. m.g_boxstrg = ['─','─','│','│','┌','┐','└','┘','─','─','│','│','┌','┐','└','┘']
  213.  
  214. m.g_validtype  = ""
  215. m.g_validname  = ""
  216. m.g_whentype   = ""
  217. m.g_whenname   = ""
  218. m.g_actitype   = ""
  219. m.g_actiname   = ""
  220. m.g_deattype   = ""
  221. m.g_deatname   = ""
  222. m.g_showtype   = ""
  223. m.g_showname   = ""
  224. m.g_showexpr   = ""
  225.  
  226. m.g_sect1start = 0
  227. m.g_sect2start = 0
  228.  
  229. m.g_devauthor  = PADR("Author's Name",c_authorlen," ")
  230. m.g_devcompany = PADR("Company Name",c_complen, " ")
  231. m.g_devaddress = PADR("Address",c_addrlen," ")
  232. m.g_devcity    = PADR("City",c_citylen," ")
  233. m.g_devstate   = "  "
  234. m.g_devzip     = PADR("Zip",c_ziplen," ")
  235. m.g_devctry    = PADR("Country",c_countrylen, " ")
  236.  
  237. m.g_allplatforms = .T.            && generate for all platforms in the SCX?
  238. m.g_numplatforms = 1              && number of platforms we are generating for
  239. m.g_parameter    = ""             && the parameter statement for this SPR
  240. m.g_areacount    = 1              && index into g_areas to count workareas we use
  241. m.g_dblampersand = CHR(38) + CHR(38)   && used in some tight loops.  Concatenate just once here.
  242.  
  243. DO CASE
  244. CASE AT(c_windows, UPPER(VERSION())) <> 0
  245.    m.g_thisvers = c_windows
  246.    m.g_graphic  = .T.
  247. CASE AT(c_mac, UPPER(VERSION())) <> 0
  248.    m.g_thisvers = c_mac
  249.    m.g_graphic  = .T.
  250. CASE AT(c_unix, UPPER(VERSION())) <> 0
  251.    m.g_thisvers = c_unix
  252.    m.g_graphic  = .F.
  253. CASE AT("FOXPRO", UPPER(VERSION())) <> 0
  254.    m.g_thisvers = c_dos
  255.    m.g_graphic  = .F.
  256. OTHERWISE
  257.    DO errorhandler WITH "Unknown FoxPro platform",LINENO(),c_error_3
  258. ENDCASE
  259.  
  260. STORE "" TO m.g_corn1, m.g_corn2, m.g_corn3, m.g_corn4, m.g_corn5, ;
  261.    m.g_corn6, m.g_verti2
  262. STORE "*" TO  m.g_horiz, m.g_verti1
  263.  
  264. * This array stores the names of the DBFs in the environment for this platform
  265. DIMENSION g_dbfs[1]
  266. g_dbfs = ""
  267.  
  268. * If you add arrays that are based on C_MAXSCREENS, remember to check PrepScreens().
  269. * You'll probably need to add the array name there so that if the number of screens
  270. * exceeds C_MAXSCREENS, your array gets expanded too.
  271.  
  272. *    generated popup names associated with scollable lists.
  273. *
  274. *    g_popups[*,1] - screen basename
  275. *    g_popups[*,2] - record number
  276. *    g_popups[*,3] - generated popup name
  277. *
  278. DIMENSION g_popups[C_MAXPOPS,3]
  279. g_popups = ""
  280.  
  281. *     screen file name array definition
  282. *
  283. *     g_screens[*,1] - screen fully qualified name
  284. *     g_screens[*,2] - window name if any
  285. *     g_screens[*,3] - recno in proj dbf
  286. *    g_screens[*,4] - initially opened?
  287. *    g_screens[*,5] - alias
  288. *    g_screens[*,6] - 2.0 screen file?
  289. *    g_screens[*,7] - Platform to generate from
  290. *
  291. DIMENSION g_screens[C_MAXSCREENS,7]
  292. g_screens = ""
  293.  
  294. * Array to store window stack.
  295. * g_wndows[*,1]  - Window name
  296. * g_wndows[*,2]  - Window sequence
  297. DIMENSION g_wndows[C_MAXWINDS,2]
  298. g_wndows = ""
  299.  
  300. * Store the substitution string for window names
  301. DIMENSION g_wnames[C_MAXSCREENS, C_MAXPLATFORMS]
  302. g_wnames = ""
  303.  
  304. * g_platforms holds a list of platforms in common among all screens
  305. DIMENSION g_platforms[C_MAXSCREENS]
  306. g_platforms = ""
  307.  
  308. * g_platprocs is a parallel array to g_platforms.  It holds the name
  309. * of the procedure to contain the setup snippet and all the @SAYs
  310. * and @GETs for the corresponding platform.
  311. DIMENSION g_platproc[C_MAXSCREENS]
  312. g_platproc = ""
  313.  
  314. * g_areas holds a list of areas we opened files in during this gen and that
  315. * we need to close on exit.
  316. DIMENSION g_areas[256]
  317. g_areas = 0
  318.  
  319. * g_firstproc holds the line number of the first PROCEDURE or FUNCTION in
  320. * the cleanup snippet of each screen.
  321. DIMENSION g_firstproc[C_MAXSCREENS]
  322. g_firstproc = 0
  323.  
  324. DIMENSION g_platlist[C_MAXPLATFORMS]
  325. g_platlist[1] = c_dos
  326. g_platlist[2] = c_windows
  327. g_platlist[3] = c_mac
  328. g_platlist[4] = c_unix
  329.  
  330. DIMENSION g_procs[1,C_MAXPLATFORMS+3]
  331. * First column is a procedure name
  332. * Second through n-th column is the line number in the cleanup snippet where
  333. *    a procedure with this name starts.
  334. * C_MAXPLATFORMS+2 column is a 1 if this procedure has been emitted.
  335. * C_MAXPLATFORMS+3 column holds the parameter statement, if any.
  336. * One row for each unique procedure name found in the cleanup snippet for any platform.
  337. g_procs = -1
  338. g_procs[1,1] = ""
  339. g_procs[1,C_MAXPLATFORMS+3] = ""
  340. g_procnames = 0   && the number we've found so far
  341.  
  342. **
  343. ** Main program
  344. **
  345.  
  346. m.onerror = ON("ERROR")
  347. ON ERROR DO errorhandler WITH MESSAGE(), LINENO(), c_error_3
  348.  
  349. IF m.g_genparams < 2
  350.    DO errorhandler WITH "Invalid number of parameters passed to"+;
  351.       " the generator",LINENO(),c_error_3
  352.    RETURN m.g_status
  353. ENDIF
  354.  
  355. DO setall
  356.  
  357. IF openprojdbf(m.projdbf, m.recno) AND prepscreens(m.g_thisvers) AND prepplatform()
  358.    DO BUILD
  359. ENDIF
  360.  
  361. DO cleanup
  362.  
  363. RETURN m.g_status
  364.  
  365. **
  366. ** Code Responsible for Genscrn's environment setting.
  367. **
  368.  
  369. *!*****************************************************************************
  370. *!
  371. *!      Procedure: SETALL
  372. *!
  373. *!      Called by: GENSCRN.PRG
  374. *!
  375. *!*****************************************************************************
  376. PROCEDURE setall
  377. *)
  378. *) SETALL - Create program's environment.
  379. *)
  380. *) Description:
  381. *) Save the user's environment that is being modified by the GENSCRN,
  382. *) then issue various SET commands.
  383. *)
  384. CLEAR PROGRAM
  385. CLEAR GETS
  386.  
  387. m.g_workarea = SELECT()
  388. m.delimiters = SET('TEXTMERGE',1)
  389. SET TEXTMERGE DELIMITERS TO
  390. SET TEXTMERGE NOSHOW
  391. mudfparms = SET('UDFPARMS')
  392. SET UDFPARMS TO VALUE
  393.  
  394. m.mfieldsto = SET("FIELDS",1)
  395. m.fields = SET("FIELDS")
  396. SET FIELDS TO
  397. SET FIELDS OFF
  398. m.memowidth = SET("MEMOWIDTH")
  399. SET MEMOWIDTH TO 256
  400. m.cursor = SET("CURSOR")
  401. SET CURSOR OFF
  402. m.consol = SET("CONSOLE")
  403. SET CONSOLE OFF
  404. m.bell = SET("BELL")
  405. SET BELL OFF
  406. m.exact = SET("EXACT")
  407. SET EXACT ON
  408. m.safety = SET("SAFETY")
  409. m.deci = SET("DECIMALS")
  410. SET DECIMALS TO 0
  411. m.mdecpoint = SET("POINT")
  412. SET POINT TO "."
  413. m.fixed = SET("FIXED")
  414. SET FIXED ON
  415. m.print = SET("PRINT")
  416. SET PRINT OFF
  417. m.unique = SET("UNIQUE")
  418. SET UNIQUE OFF
  419. m.mcollate = SET("COLLATE")
  420. SET COLLATE TO "machine"
  421. #if "MAC" $ UPPER(VERSION(1))
  422.    IF _MAC
  423.       m.mmacdesk = SET("MACDESKTOP")
  424.       SET MACDESKTOP ON
  425.     ENDIF
  426. #endif
  427. m.origpretext = _PRETEXT
  428. _PRETEXT = ""
  429. RETURN
  430.  
  431. *!*****************************************************************************
  432. *!
  433. *!      Procedure: CLEANUP
  434. *!
  435. *!      Called by: GENSCRN.PRG
  436. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  437. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  438. *!
  439. *!          Calls: CLEANSCRN          (procedure in GENSCRN.PRG)
  440. *!               : CLEARAREAS         (procedure in GENSCRN.PRG)
  441. *!
  442. *!*****************************************************************************
  443. PROCEDURE cleanup
  444. *)
  445. *) CLEANUP - Restore environment to pre-execution state.
  446. *)
  447. *) Description:
  448. *) Put SET command settings back the way we found them.
  449. *)
  450. PRIVATE m.i, m.delilen, m.ldelimi, m.rdelimi
  451. IF EMPTY(m.g_projalias)
  452.    RETURN
  453. ENDIF
  454. SELECT (m.g_projalias)
  455. USE
  456. DO cleanscrn
  457. DO clearareas  && clear the workareas we opened during this run
  458. SELECT (m.g_workarea)
  459.  
  460. DELETE FILE (m.g_tmpfile)
  461. DELETE FILE (m.g_idxfile)
  462.  
  463. m.delilen = LEN(m.delimiters)
  464. m.ldelimi = SUBSTR(m.delimiters,1,;
  465.    IIF(MOD(m.delilen,2)=0,m.delilen/2,CEILING(m.delilen/2)))
  466. m.rdelimi = SUBSTR(m.delimiters,;
  467.    IIF(MOD(m.delilen,2)=0,m.delilen/2+1,CEILING(m.delilen/2)+1))
  468. SET TEXTMERGE DELIMITERS TO m.ldelimi, m.rdelimi
  469.  
  470. SET FIELDS TO &mfieldsto
  471. IF m.fields = "ON"
  472.    SET FIELDS ON
  473. ELSE
  474.    SET FIELDS OFF
  475. ENDIF
  476. IF m.cursor = "ON"
  477.    SET CURSOR ON
  478. ELSE
  479.    SET CURSOR OFF
  480. ENDIF
  481. IF m.consol = "ON"
  482.    SET CONSOLE ON
  483. ELSE
  484.    SET CONSOLE OFF
  485. ENDIF
  486. IF m.escape = "ON"
  487.    SET ESCAPE ON
  488. ELSE
  489.    SET ESCAPE OFF
  490. ENDIF
  491. IF m.bell = "ON"
  492.    SET BELL ON
  493. ELSE
  494.    SET BELL OFF
  495. ENDIF
  496. IF m.exact = "ON"
  497.    SET EXACT ON
  498. ELSE
  499.    SET EXACT OFF
  500. ENDIF
  501. IF m.safety = "ON"
  502.    SET SAFETY ON
  503. ELSE
  504.    SET SAFETY OFF
  505. ENDIF
  506. IF m.comp = "ON"
  507.    SET COMPATIBLE ON
  508. ENDIF
  509. IF m.print = "ON"
  510.    SET PRINT ON
  511. ENDIF
  512. SET DECIMALS TO m.deci
  513. SET MEMOWIDTH TO m.memowidth
  514. SET DEVICE TO &mdevice
  515. SET UDFPARMS TO &mudfparms
  516. SET POINT TO "&mdecpoint"
  517. SET COLLATE TO "&mcollate"
  518. #if "MAC" $ UPPER(VERSION(1))
  519.    IF _MAC
  520.       SET MACDESKTOP &mmacdesk
  521.     ENDIF
  522. #endif
  523. IF m.fixed = "OFF"
  524.    SET FIXED OFF
  525. ENDIF
  526. IF m.trbetween = "ON"
  527.    SET TRBET ON
  528. ENDIF
  529. IF m.talkset = "ON"
  530.    SET TALK ON
  531. ENDIF
  532. IF m.unique = "ON"
  533.    SET UNIQUE ON
  534. ENDIF
  535. SET MESSAGE TO
  536. _PRETEXT = m.origpretext
  537. * Leave this array if dbglevel is defined.  Used for profiling.
  538. * IF TYPE("dbglevel") = "U"
  539. *   RELEASE ticktock
  540. * ENDIF
  541.  
  542. ON ERROR &onerror
  543. RETURN
  544.  
  545. *!*****************************************************************************
  546. *!
  547. *!      Procedure: CLEANSCRN
  548. *!
  549. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  550. *!
  551. *!*****************************************************************************
  552. PROCEDURE cleanscrn
  553. *)
  554. *) CLEANSCRN - Clean up after each screen set generation, once per platform
  555. *)
  556. PRIVATE m.i
  557. FOR m.i = 1 TO m.g_nscreens
  558.    m.g_screen = i
  559.    IF NOT EMPTY(g_screens[m.i,4])
  560.       LOOP
  561.    ENDIF
  562.    IF USED(g_screens[m.i,5])
  563.       SELECT (g_screens[m.i,5])
  564.       USE
  565.    ENDIF
  566. ENDFOR
  567. m.g_screen = 0
  568. RETURN
  569.  
  570. *!*****************************************************************************
  571. *!
  572. *!      Procedure: BUILDENABLE
  573. *!
  574. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  575. *!
  576. *!          Calls: PREPFILE           (procedure in GENSCRN.PRG)
  577. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  578. *!
  579. *!*****************************************************************************
  580. PROCEDURE buildenable
  581. *)
  582. *> BUILDENABLE - Enable code generation.
  583. *)
  584. *) Description:
  585. *) Call prepfile to open output file(s).
  586. *) If error(s) encountered in prepfile then exit, otherwise
  587. *) SET TEXTMERGE ON
  588. *)
  589. *) Returns: .T. on success; .F. on failure
  590. *)
  591. DO prepfile WITH m.g_outfile, m.g_orghandle
  592. DO prepfile WITH m.g_tmpfile, m.g_tmphandle
  593.  
  594. SET TEXTMERGE ON
  595. ON ESCAPE DO eschandler
  596. SET ESCAPE ON
  597. RETURN
  598.  
  599. *!*****************************************************************************
  600. *!
  601. *!      Procedure: BUILDDISABLE
  602. *!
  603. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  604. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  605. *!
  606. *!          Calls: CLOSEFILE          (procedure in GENSCRN.PRG)
  607. *!
  608. *!*****************************************************************************
  609. PROCEDURE builddisable
  610. *)
  611. *) BUILDDISABLE - Disable code generation.
  612. *)
  613. *) Description:
  614. *) Issue the command SET TEXTMERGE OFF.
  615. *) Close the generated output file.
  616. *) Close the temporary file.
  617. *) If anything goes wrong display appropriate message to the user.
  618. *)
  619. SET ESCAPE OFF
  620. ON ESCAPE
  621. SET TEXTMERGE OFF
  622. IF m.g_havehand
  623.    DO closefile WITH m.g_orghandle
  624.    DO closefile WITH m.g_tmphandle
  625. ENDIF
  626. RETURN
  627.  
  628. *!*****************************************************************************
  629. *!
  630. *!      Procedure: PREPPARAMS
  631. *!
  632. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  633. *!
  634. *!          Calls: CHECKPARAM()       (function  in GENSCRN.PRG)
  635. *!
  636. *!*****************************************************************************
  637. PROCEDURE prepparams
  638. *)
  639. *) PREPPARAMS - Read through each of the platforms on screen 1
  640. *)              and ensure that any parameter statements in #SECTION 1
  641. *)              are identical.
  642. *)
  643. PRIVATE m.i, m.j, m.dbalias, m.thisparam
  644. m.g_screen = 1
  645. m.dbalias = g_screens[m.g_screen,5]
  646. SELECT (m.dbalias)
  647. DO CASE
  648. CASE g_screens[m.g_screen,6] OR !multiplat()
  649.    * DOS 2.0 screen or just one 2.5 platform being generated
  650.    GO TOP
  651.    RETURN checkparam(m.g_screen)
  652.  
  653. OTHERWISE
  654.    FOR m.j = 1 TO c_maxplatforms
  655.       LOCATE FOR ALLTRIM(UPPER(platform)) = g_platlist[m.j] AND objtype = c_otscreen
  656.       DO CASE
  657.       CASE !FOUND() OR EMPTY(setupcode)
  658.          LOOP
  659.       CASE !checkparam(m.g_screen)
  660.          RETURN .F.
  661.       ENDCASE
  662.    ENDFOR
  663. ENDCASE
  664. m.g_screen = 0
  665. RETURN .T.
  666.  
  667. *!*****************************************************************************
  668. *!
  669. *!       Function: CLEANPARAM
  670. *!
  671. *!      Called by: CHECKPARAM()       (function  in GENSCRN.PRG)
  672. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  673. *!
  674. *!*****************************************************************************
  675. FUNCTION cleanparam
  676. *)
  677. *) CLEANPARAM - Clean up a parameter string so that it may be compared with another one.
  678. *)              This function replaces tabs with spaces, capitalizes the string, merges
  679. *)              forces single spacing, and strips out CR/LF characters.
  680. *)
  681. PARAMETER m.p, m.cp
  682. m.cp = UPPER(ALLTRIM(CHRTRAN(m.p,";"+CHR(13)+CHR(10),"")))   && drop CR/LF and continuation chars
  683. m.cp = CHRTRAN(m.cp,CHR(9),' ')   && tabs to spaces
  684. DO WHILE AT('  ',m.cp) > 0         && reduce multiple spaces to a single space
  685.    m.cp = STRTRAN(m.cp,'  ',' ')
  686. ENDDO
  687. DO WHILE AT(', ',m.cp) > 0         && drop spaces after commas
  688.    m.cp = STRTRAN(m.cp,', ',',')
  689. ENDDO
  690. RETURN m.cp
  691.  
  692. *!*****************************************************************************
  693. *!
  694. *!       Function: CHECKPARAM
  695. *!
  696. *!      Called by: PREPPARAMS         (procedure in GENSCRN.PRG)
  697. *!
  698. *!          Calls: GETPARAM()         (function  in GENSCRN.PRG)
  699. *!               : CLEANPARAM()       (function  in GENSCRN.PRG)
  700. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  701. *!
  702. *!*****************************************************************************
  703. FUNCTION checkparam
  704. *)
  705. *) CHECKPARAM - See if this parameter statement matches others we have found. Generate
  706. *)               an error message if it doesn't.  g_parameter is empty if we haven't
  707. *)               seen any parameter statements yet, or it contains the variables in the
  708. *)               parameter statement (but not the PARAMETERS keyword) if we have seen one
  709. *)               before.
  710. *)
  711. PARAMETER m.i
  712. PRIVATE m.thisparam
  713. m.thisparam = getparam("setupcode")  && get parameter from setup snippet at current record position
  714.  
  715. IF !EMPTY(m.thisparam)
  716.    IF !EMPTY(m.g_parameter) AND !(cleanparam(m.thisparam) == cleanparam(m.g_parameter))
  717.       DO errorhandler WITH "DOS and Windows setup code has different parameters", ;
  718.          LINENO(), c_error_3
  719.       RETURN .F.
  720.    ELSE
  721.       g_parameter = m.thisparam
  722.    ENDIF
  723. ENDIF
  724. RETURN .T.
  725.  
  726. *!*****************************************************************************
  727. *!
  728. *!      Procedure: PREPPLATFORM
  729. *!
  730. *!      Called by: GENSCRN.PRG
  731. *!
  732. *!*****************************************************************************
  733. PROCEDURE prepplatform
  734. *)
  735. *) PREPPLATFORM - Create an array of platform names in the screen set.  Make sure that
  736. *)                there is at least one common platform across all SCXs in the screen set.
  737. *)                g_platforms comes out of this procedure containing the intersection of
  738. *)                the set of platforms in each screen.  If there are no common platforms
  739. *)                across all screens, it will be empty.
  740. *)
  741. PRIVATE m.i, m.j, m.firstscrn, m.p_cur, m.tempplat, m.numtodel, m.in_area, ;
  742.    m.rcount
  743. IF m.g_nscreens <= 0
  744.    RETURN .F.
  745. ENDIF
  746.  
  747. DIMENSION t_platforms[ALEN(g_platforms)]
  748. m.in_area = SELECT()
  749. IF g_screens[1,6]         && First screen is a DOS 2.0 screen
  750.    g_platforms = ""
  751.    g_platforms[1] = "DOS"
  752. ELSE
  753.    IF _DOS
  754.       * Avoid selecting into an array to conserve memory
  755.       SELECT DISTINCT platform FROM (g_screens[1,1]) ;
  756.           WHERE IIF(INLIST(UPPER(platform), c_dos, ;
  757.             c_windows, c_mac, c_unix), .T., .F.) ;
  758.           INTO CURSOR curstemp ;
  759.          ORDER BY platform
  760.       m.rcount = _TALLY
  761.       SELECT curstemp
  762.       DIMENSION g_platforms[m.rcount]
  763.       GOTO TOP
  764.       FOR m.i = 1 TO m.rcount
  765.          g_platforms[m.i] = curstemp->platform
  766.          SKIP
  767.       ENDFOR
  768.       USE                                             && get rid of the cursor
  769.    ELSE
  770.       SELECT DISTINCT platform FROM (g_screens[1,1]) ;
  771.           WHERE IIF(INLIST(UPPER(platform), c_dos, ;
  772.             c_windows, c_mac, c_unix), .T., .F.) ;
  773.           INTO ARRAY g_platforms ;
  774.          ORDER BY platform
  775.    ENDIF
  776. ENDIF
  777.  
  778. m.numtodel = 0   && number of array elements to delete
  779. FOR m.i = 2 TO m.g_nscreens
  780.    m.g_screen = m.i
  781.    IF g_screens[m.i,6]   && DOS 2.0 screen
  782.       DIMENSION t_platforms[1]
  783.       t_platforms = ""
  784.       t_platforms[1] = "DOS"
  785.    ELSE
  786.       IF _DOS
  787.          * Avoid selecting into an array to conserve memory
  788.          SELECT DISTINCT platform FROM (g_screens[m.i,1]) ;
  789.                 WHERE IIF(INLIST(UPPER(platform), c_dos, ;
  790.                 c_windows, c_mac, c_unix), .T., .F.) ;
  791.             INTO CURSOR curstemp ;
  792.             ORDER BY platform
  793.          m.rcount = _TALLY
  794.          SELECT curstemp
  795.          DIMENSION t_platforms[m.rcount]
  796.          GOTO TOP
  797.          FOR m.k = 1 TO m.rcount
  798.             t_platforms[m.k] = curstemp->platform
  799.             SKIP
  800.          ENDFOR
  801.          USE                                             && get rid of the cursor
  802.       ELSE
  803.          SELECT DISTINCT platform FROM (g_screens[m.i,1]) ;
  804.                 WHERE IIF(INLIST(UPPER(platform), c_dos, ;
  805.                 c_windows, c_mac, c_unix), .T., .F.) ;
  806.              INTO ARRAY t_platforms ;
  807.             ORDER BY platform
  808.       ENDIF
  809.    ENDIF
  810.  
  811.    * Update g_platforms with the intersection of g_platforms
  812.    *  and t_platforms
  813.    m.j = 1
  814.    DO WHILE m.j < ALEN(g_platforms) -  m.numtodel
  815.       IF !INLIST(TYPE("g_platforms[m.j]"),"L","U") ;
  816.             AND ASCAN(t_platforms,g_platforms[m.j]) = 0
  817.          =ADEL(g_platforms,m.j)
  818.          m.numtodel = m.numtodel + 1
  819.       ELSE
  820.          m.j = m.j + 1
  821.       ENDIF
  822.    ENDDO
  823.  
  824. ENDFOR
  825. SELECT (m.in_area)
  826.  
  827. m.g_screen = 0
  828. * Shrink the unique platform array if necessary
  829. DIMENSION g_platforms[ALEN(g_platforms)-m.numtodel]
  830.  
  831. IF ALEN(g_platforms) <= 0 OR EMPTY(g_platforms[1])
  832.    WAIT WINDOW  "No common platforms in these screens.  Press any key."
  833.    CANCEL
  834. ELSE
  835.    FOR m.j = 1 TO ALEN(g_platforms)
  836.       g_platforms[m.j] = UPPER(ALLTRIM(g_platforms[m.j]))
  837.    ENDFOR
  838.  
  839.    * If the current platform is in the list of common platforms, put it at the top
  840.    m.p_cur = ASCAN(g_platforms, m.g_thisvers)
  841.    IF m.p_cur > 1
  842.       m.tempplat = g_platforms[1]
  843.       g_platforms[1] = g_platforms[m.p_cur]
  844.       g_platforms[m.p_cur] = m.tempplat
  845.    ENDIF
  846. ENDIF
  847. RETURN .T.
  848.  
  849. *!*****************************************************************************
  850. *!
  851. *!      Procedure: PREPFILE
  852. *!
  853. *!      Called by: BUILDENABLE        (procedure in GENSCRN.PRG)
  854. *!
  855. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  856. *!
  857. *!*****************************************************************************
  858. PROCEDURE prepfile
  859. *)
  860. *) PREPFILE - Create and open the application output file.
  861. *)
  862. *) Description:
  863. *) Create or open a file that will hold the generated application.
  864. *) If error(s) encountered at any time issue an error message
  865. *) and return .F.
  866. *)
  867. PARAMETER m.filename, m.ifp
  868. PRIVATE m.msg
  869. m.ifp = FCREATE(m.filename)
  870.  
  871. IF (m.ifp = -1)
  872.    m.msg = "Cannot open "+LOWER(m.filename)
  873.    m.g_havehand = .F.
  874.    DO errorhandler WITH m.msg, LINENO(), c_error_3
  875. ELSE
  876.    m.g_havehand = .T.
  877. ENDIF
  878. RETURN
  879.  
  880. *!*****************************************************************************
  881. *!
  882. *!      Procedure: CLOSEFILE
  883. *!
  884. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  885. *!               : BUILDDISABLE       (procedure in GENSCRN.PRG)
  886. *!
  887. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  888. *!
  889. *!*****************************************************************************
  890. PROCEDURE closefile
  891. *)
  892. *) CLOSEFILE - Close a low level file opened with FCREATE.
  893. *)
  894. PARAMETER m.ifp
  895. IF (m.ifp > 0) AND !FCLOSE(m.ifp)
  896.    DO errorhandler WITH "Unable to close the generated file",;
  897.       LINENO(), c_error_2
  898. ENDIF
  899. RETURN
  900.  
  901. *!*****************************************************************************
  902. *!
  903. *!       Function: PREPSCREENS
  904. *!
  905. *!      Called by: GENSCRN.PRG
  906. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  907. *!
  908. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  909. *!               : SCREENUSED()       (function  in GENSCRN.PRG)
  910. *!               : NOTEAREA           (procedure in GENSCRN.PRG)
  911. *!               : GETPLATFORM()      (function  in GENSCRN.PRG)
  912. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  913. *!               : PREPWNAMES         (procedure in GENSCRN.PRG)
  914. *!
  915. *!*****************************************************************************
  916. FUNCTION prepscreens
  917. *)
  918. *) PREPSCREENS - Prepare screen file(s) for processing.
  919. *)
  920. *) Description:
  921. *) Called once per platform.
  922. *)
  923. *) Open PJX database, index it to find all screen files belonging
  924. *) to a screen set if part of a project.
  925. *)
  926. *) Open all screen file(s).  If screen file already opened, then
  927. *) select it.  Assign unique aliases to screen with name conflicts.
  928. *) If error is encountered while opening any of the screen files
  929. *) this program will be aborted.
  930. *)
  931. PARAMETER m.gen_version
  932.  
  933. PRIVATE m.status, m.projdbf, m.saverec, m.dbname, m.dbalias
  934. m.status = .T.
  935.  
  936. SELECT (m.g_projalias)
  937. SET SAFETY OFF
  938. INDEX ON STR(scrnorder) TO (m.g_idxfile) COMPACT
  939. SET SAFETY ON
  940. GO TOP
  941. SCAN FOR NOT DELETED() AND setid = m.g_keyno AND TYPE = 's'
  942.    m.saverec = RECNO()
  943.    m.dbname  = FULLPATH(ALLTRIM(name), m.g_projpath)
  944.    if right(m.dbname,1) = ":"
  945.       m.dbname = m.dbname + justfname(name)
  946.    endif
  947.    m.g_nscreens = m.g_nscreens + 1
  948.  
  949.    IF MOD(m.g_nscreens,5)=0
  950.       DIMENSION g_screens[ALEN(g_screens,1)+5,7]
  951.       DIMENSION g_wnames [ALEN(g_wnames)+5,C_MAXPLATFORMS]
  952.       DIMENSION g_platforms [ALEN(g_platforms)+5]
  953.       DIMENSION g_firstproc [ALEN(g_firstproc)+5]
  954.    ENDIF
  955.  
  956.    m.dbalias = LEFT(basename(m.dbname), c_aliaslen)
  957.    IF screenused(m.dbalias, m.dbname)
  958.       g_screens[m.g_nscreens,4] = .T.
  959.    ELSE
  960.       g_screens[m.g_nscreens,4] = .F.
  961.         IF FILE(m.dbname)
  962.          SELECT 0
  963.          USE (m.dbname) AGAIN ALIAS (g_screens[m.g_nscreens,5])
  964.          DO notearea
  965.         ELSE
  966.            DO errorhandler WITH "Could not find SCX file: "+m.dbname, ;
  967.                LINENO(),c_error_2
  968.             RETURN .F.
  969.        ENDIF
  970.    ENDIF
  971.  
  972.    DO CASE
  973.    CASE FCOUNT() = c_scxflds
  974.       LOCATE FOR platform = m.gen_version
  975.       IF FOUND()
  976.          g_screens[m.g_nscreens,6] = .F.
  977.          g_screens[m.g_nscreens,7] = platform
  978.       ELSE
  979.          g_screens[m.g_nscreens,6] = .F.
  980.          g_screens[m.g_nscreens,7] = getplatform()
  981.       ENDIF
  982.    CASE FCOUNT() = c_20scxflds
  983.       g_screens[m.g_nscreens,6] = .T.
  984.       g_screens[m.g_nscreens,7] = "DOS"
  985.    OTHERWISE
  986.       DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  987.          c_error_2
  988.       RETURN .F.
  989.    ENDCASE
  990.    g_screens[m.g_nscreens,1] = m.dbname
  991.  
  992.    IF NOT EMPTY(STYLE)
  993.       IF EMPTY(name)
  994.          g_screens[m.g_nscreens,2] = LOWER(SYS(2015))
  995.       ELSE
  996.          g_screens[m.g_nscreens,2] = ALLTRIM(LOWER(name))
  997.       ENDIF
  998.       DO prepwnames WITH m.g_nscreens
  999.    ENDIF
  1000.  
  1001.    SELECT (m.g_projalias)
  1002.    GOTO RECORD m.saverec
  1003.    g_screens[m.g_nscreens,3] = m.saverec
  1004. ENDSCAN
  1005.  
  1006. RETURN m.status
  1007.  
  1008. *!*****************************************************************************
  1009. *!
  1010. *!       Function: NEWWINDOWS
  1011. *!
  1012. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1013. *!
  1014. *!*****************************************************************************
  1015. FUNCTION newwindows
  1016. * Initialize the windows name array and other window-related
  1017. * variables for each platform.
  1018. g_wndows = ""                  && array of window names
  1019. m.g_nwindows = 0               && number of windows
  1020. m.g_lastwindow = ""            && name of last window generated for this platform
  1021. RETURN
  1022.  
  1023. *!*****************************************************************************
  1024. *!
  1025. *!       Function: NEWSCHEMES
  1026. *!
  1027. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1028. *!
  1029. *!*****************************************************************************
  1030. FUNCTION newschemes
  1031. *)
  1032. *) NEWSCHEMES - Initialize the color schemes for each screen/platform
  1033. *)
  1034. m.g_defasch  = 0
  1035. m.g_defasch2 = 0
  1036. RETURN
  1037.  
  1038. *!*****************************************************************************
  1039. *!
  1040. *!       Function: NEWDBFS
  1041. *!
  1042. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1043. *!
  1044. *!*****************************************************************************
  1045. FUNCTION newdbfs
  1046. *)
  1047. *) NEWDBFS - Initialize the databases name array for each platform
  1048. *)
  1049. m.g_dbfs = ""
  1050. RETURN
  1051.  
  1052. *!*****************************************************************************
  1053. *!
  1054. *!      Procedure: NEWREADCLAUSES
  1055. *!
  1056. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1057. *!
  1058. *!*****************************************************************************
  1059. PROCEDURE newreadclauses
  1060. *)
  1061. *) NEWREADCLAUSES - Initialize the variables that control which READ and WINDOW clauses are
  1062. *)                    emitted.
  1063. *)
  1064. m.g_validtype  = ""
  1065. m.g_validname  = ""
  1066. m.g_whentype   = ""
  1067. m.g_whenname   = ""
  1068. m.g_actitype   = ""
  1069. m.g_actiname   = ""
  1070. m.g_deattype   = ""
  1071. m.g_deatname   = ""
  1072. m.g_showtype   = ""
  1073. m.g_showname   = ""
  1074. m.g_showexpr   = ""
  1075. RETURN
  1076.  
  1077. *!*****************************************************************************
  1078. *!
  1079. *!      Procedure: NEWDIRECTIVES
  1080. *!
  1081. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1082. *!
  1083. *!*****************************************************************************
  1084. PROCEDURE newdirectives
  1085. m.g_windclauses= ""            && #WCLAUSES directive
  1086. m.g_rddir      = .F.           && Is there a #READCLAUSES directive?
  1087. m.g_rddirno    = 0             && Number of 1st screen with #READ directive
  1088. RETURN
  1089.  
  1090. *!*****************************************************************************
  1091. *!
  1092. *!       Function: GETPLATFORM
  1093. *!
  1094. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1095. *!
  1096. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1097. *!
  1098. *!*****************************************************************************
  1099. FUNCTION getplatform
  1100. *)
  1101. *) GETPLATFORM - Find which Platform we are supposed to generate for.  If we are trying to
  1102. *)               generate for Windows, but there are no windows records in the SCX, use
  1103. *)               this function to determine which records to use.
  1104. *)
  1105. IF m.g_genvers = 'WINDOWS' OR m.g_genvers = 'MAC'
  1106.    LOCATE FOR platform = IIF(m.g_genvers = 'WINDOWS', 'MAC', 'WINDOWS')
  1107.    IF FOUND()
  1108.       RETURN platform
  1109.    ELSE
  1110.       LOCATE FOR platform = 'DOS'
  1111.       IF FOUND()
  1112.          RETURN 'DOS'
  1113.       ELSE
  1114.          LOCATE FOR platform = 'UNIX'
  1115.          IF FOUND()
  1116.             RETURN 'UNIX'
  1117.          ELSE
  1118.             DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1119.                c_error_2
  1120.          ENDIF
  1121.       ENDIF
  1122.    ENDIF
  1123. ELSE
  1124.    LOCATE FOR platform = IIF(m.g_genvers = 'DOS', 'UNIX', 'DOS')
  1125.    IF FOUND()
  1126.       RETURN platform
  1127.    ELSE
  1128.       LOCATE FOR platform = 'WINDOWS'
  1129.       IF FOUND()
  1130.          RETURN 'DOS'
  1131.       ELSE
  1132.          LOCATE FOR platform = 'MAC'
  1133.          IF FOUND()
  1134.             RETURN 'UNIX'
  1135.          ELSE
  1136.             DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1137.                c_error_2
  1138.          ENDIF
  1139.       ENDIF
  1140.    ENDIF
  1141. ENDIF
  1142. RETURN ""
  1143.  
  1144.  
  1145. *!*****************************************************************************
  1146. *!
  1147. *!      Procedure: PREPWNAMES
  1148. *!
  1149. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1150. *!
  1151. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  1152. *!               : SKIPWHITESPACE()   (function  in GENSCRN.PRG)
  1153. *!
  1154. *!*****************************************************************************
  1155. PROCEDURE prepwnames
  1156. *)
  1157. *) PREPWNAMES - Store #WNAME directive strings.  They must be in the setup snippet.
  1158. *)
  1159. PARAMETER m.scrnno
  1160. PRIVATE m.lineno, m.textline
  1161. m.lineno = ATCLINE('#WNAM',setupcode)
  1162. IF m.lineno > 0
  1163.    m.textline = MLINE(setupcode,m.lineno)
  1164.    DO killcr WITH m.textline
  1165.    IF g_screens[m.scrnno,6]   && DOS 2.0 screen
  1166.       IF ATC('#WNAM',m.textline) = 1
  1167.          g_wnames[m.scrnno, getplatnum("DOS")] = skipwhitespace(m.textline)
  1168.       ENDIF
  1169.    ELSE
  1170.       IF ATC('#WNAM',m.textline) = 1
  1171.          g_wnames[m.scrnno, getplatnum(platform)] = skipwhitespace(m.textline)
  1172.       ENDIF
  1173.    ENDIF
  1174. ENDIF
  1175. RETURN
  1176.  
  1177. *!*****************************************************************************
  1178. *!
  1179. *!       Function: SCREENUSED
  1180. *!
  1181. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1182. *!
  1183. *!          Calls: ILLEGALNAME()      (function  in GENSCRN.PRG)
  1184. *!
  1185. *!*****************************************************************************
  1186. FUNCTION screenused
  1187. *)
  1188. *) SCREENUSED - Check to see if screen file already opened.
  1189. *)
  1190. PARAMETER m.dbalias, m.fulldbname
  1191. m.dbalias = LEFT(m.dbalias,c_aliaslen)
  1192. IF NOT USED(m.dbalias)
  1193.    IF illegalname(m.dbalias)
  1194.       g_screens[m.g_nscreens,5] = "S"+SUBSTR(LOWER(SYS(3)),2,8)
  1195.    ELSE
  1196.       g_screens[m.g_nscreens,5] = m.dbalias
  1197.    ENDIF
  1198.    RETURN .F.
  1199. ENDIF
  1200. SELECT (m.dbalias)
  1201. IF RAT(".SCX",DBF())<>0 AND m.fulldbname=DBF()
  1202.    g_screens[m.g_nscreens,5] = m.dbalias
  1203.    RETURN .T.
  1204. ELSE
  1205.    g_screens[m.g_nscreens,5] = "S"+SUBSTR(LOWER(SYS(3)),2,8)
  1206. ENDIF
  1207. RETURN .F.
  1208.  
  1209. *!*****************************************************************************
  1210. *!
  1211. *!       Function: ILLEGALNAME
  1212. *!
  1213. *!      Called by: SCREENUSED()       (function  in GENSCRN.PRG)
  1214. *!
  1215. *!*****************************************************************************
  1216. FUNCTION illegalname
  1217. *)
  1218. *) ILLEGALNAME - Check if default alias will be used when this
  1219. *)               database is USEd. (i.e., 1st letter is not A-Z,
  1220. *)                a-z or '_', or any one of ramaining letters is not
  1221. *)                alphanumeric.)
  1222. *)
  1223. PARAMETER m.dname
  1224. PRIVATE m.start, m.aschar, m.length
  1225. m.length = LEN(m.dname)
  1226. m.start  = 0
  1227. IF m.length = 1
  1228.    *
  1229.    * If length 1, then check if default alias can be used,
  1230.    * i.e., name is different than A-J and a-j.
  1231.    *
  1232.    m.aschar = ASC(m.dname)
  1233.    IF (m.aschar >= 65 AND m.aschar <= 74) OR ;
  1234.          (m.aschar >= 97 AND m.aschar <= 106)
  1235.       RETURN .T.
  1236.    ENDIF
  1237. ENDIF
  1238. DO WHILE m.start < m.length
  1239.    m.start  = m.start + 1
  1240.    m.aschar = ASC(SUBSTR(m.dname, m.start, 1))
  1241.    IF m.start<>1 AND (m.aschar >= 48 AND m.aschar <= 57)
  1242.       LOOP
  1243.    ENDIF
  1244.    IF NOT ((m.aschar >= 65 AND m.aschar <= 90) OR ;
  1245.          (m.aschar >= 97 AND m.aschar <= 122) OR m.aschar = 95)
  1246.       RETURN .T.
  1247.    ENDIF
  1248. ENDDO
  1249. RETURN .F.
  1250.  
  1251. *!*****************************************************************************
  1252. *!
  1253. *!       Function: OPENPROJDBF
  1254. *!
  1255. *!      Called by: GENSCRN.PRG
  1256. *!
  1257. *!          Calls: NOTEAREA           (procedure in GENSCRN.PRG)
  1258. *!               : STRIPEXT()         (function  in GENSCRN.PRG)
  1259. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1260. *!               : REFRESHPREFS       (procedure in GENSCRN.PRG)
  1261. *!               : GETWITHLIST        (procedure in GENSCRN.PRG)
  1262. *!
  1263. *!*****************************************************************************
  1264. FUNCTION openprojdbf
  1265. *)
  1266. *) OPENPROJDBF - Prepare Project dbf for processing.
  1267. *)
  1268. *) Description:
  1269. *) Check to see if projdbf has an appropriate number of fields.
  1270. *) Find the screen set record.
  1271. *) Extract information from the SETID record.
  1272. *)
  1273. PARAMETER m.projdbf, m.recno
  1274.  
  1275. SELECT 0
  1276. IF USED("projdbf")
  1277.    m.g_projalias = "P"+SUBSTR(LOWER(SYS(3)),2,8)
  1278. ELSE
  1279.    m.g_projalias = "projdbf"
  1280. ENDIF
  1281. USE (m.projdbf) ALIAS (m.g_projalias)
  1282. DO notearea
  1283. IF versnum() > "2.5"
  1284.    SET NOCPTRANS TO devinfo, arranged, symbols, object
  1285. ENDIF
  1286. m.g_errlog = stripext(m.projdbf)
  1287. m.g_projpath = SUBSTR(m.projdbf,1,RAT("\",m.projdbf))
  1288.  
  1289. IF FCOUNT() <> c_pjxflds
  1290.    IF FCOUNT() = c_pjx20flds
  1291.       DO errorhandler WITH "Invalid 2.0 project file passed to GenScrn.",;
  1292.          LINENO(), c_error_2
  1293.    ELSE
  1294.       DO errorhandler WITH "Generator out of date.",;
  1295.          LINENO(), c_error_2
  1296.    ENDIF
  1297.    RETURN .F.
  1298. ENDIF
  1299.  
  1300. DO refreshprefs
  1301. GOTO m.recno
  1302. m.g_keyno        = setid
  1303. m.g_outfile      = ALLTRIM(SUBSTR(outfile,1,AT(c_null,outfile)-1))
  1304. m.g_outfile      = FULLPATH(m.g_outfile, m.g_projpath)
  1305. IF RIGHT(m.g_outfile,1) = ":"
  1306.    m.g_outfile = m.g_outfile + justfname(outfile)
  1307. ENDIF
  1308. m.g_openfiles    = openfiles
  1309. m.g_closefiles   = closefiles
  1310. m.g_defwin       = defwinds
  1311. m.g_relwin       = relwinds
  1312. m.g_readcycle    = readcycle
  1313. m.g_readlock     = NOLOCK
  1314. m.g_readmodal    = MODAL
  1315. m.g_readborder   = nologo
  1316. m.g_multreads    = multreads
  1317. m.g_allplatforms = !savecode
  1318. DO getwithlist
  1319. RETURN
  1320.  
  1321. *!*****************************************************************************
  1322. *!
  1323. *!      Procedure: GETWITHLIST
  1324. *!
  1325. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  1326. *!
  1327. *!*****************************************************************************
  1328. PROCEDURE getwithlist
  1329. *)
  1330. *) GETWITHLIST - Construct the list for READ level WITH clause.  The
  1331. *) window list is in the project file, stored as CR separated strings
  1332. *) possibly terminated with a NULL.
  1333. *)
  1334.  
  1335. m.g_withlist = assocwinds
  1336. * Drop any nulls
  1337. m.g_withlist = ALLTRIM(CHRTRAN(m.g_withlist, CHR(0), ""))
  1338. * Translate any CRs/LFs into commas
  1339. m.g_withlist = CHRTRAN(m.g_withlist, c_cret+c_lf, ",,")
  1340. * Sanity check for duplicate commas
  1341. m.g_withlist = STRTRAN(m.g_withlist, ",,", ",")   && shouldn't be necessary
  1342. IF RIGHT(m.g_withlist,1) = ","
  1343.    m.g_withlist = LEFT(m.g_withlist, LEN(m.g_withlist) - 1)
  1344. ENDIF
  1345. IF LEFT(m.g_withlist,1) = ","
  1346.    m.g_withlist = RIGHT(m.g_withlist, LEN(m.g_withlist) - 1)
  1347. ENDIF
  1348. RETURN
  1349.  
  1350. *!*****************************************************************************
  1351. *!
  1352. *!      Procedure: REFRESHPREFS
  1353. *!
  1354. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  1355. *!
  1356. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1357. *!               : SUBDEVINFO()       (function  in GENSCRN.PRG)
  1358. *!
  1359. *!*****************************************************************************
  1360. PROCEDURE refreshprefs
  1361. *)
  1362. *) REFRESHPREFS - Refresh Documentation and Developer preferences.
  1363. *)
  1364. *) Description:
  1365. *) Get the newest preferences for documentation style and developer
  1366. *) data from the HEADER record.
  1367. *)
  1368. PRIVATE m.start
  1369. LOCATE FOR TYPE = "H"
  1370. IF NOT FOUND ()
  1371.    DO errorhandler WITH "Missing header record in "+m.projdbf,;
  1372.       LINENO(), c_error_2
  1373.    RETURN
  1374. ENDIF
  1375. IF _MAC
  1376.     * On the Mac, the home directory will be stored in homedir unless
  1377.     * it is in a non-DOS format (e.g., contains spaces), in which case
  1378.     * it is stored in the assocwinds field.  This subterfuge is to
  1379.     * maintain cross platform compatibility of the projects.
  1380.     IF !EMPTY(assocwinds)
  1381.         m.g_homedir = ALLTRIM(SUBSTR(assocwinds,1,AT(c_null,assocwinds)-1))
  1382.     ELSE
  1383.         m.g_homedir = ALLTRIM(SUBSTR(homedir,1,AT(c_null,homedir)-1))
  1384.         IF RIGHT(m.g_homedir,1) <> "\"
  1385.            m.g_homedir = m.g_homedir + "\"
  1386.         ENDIF
  1387.     ENDIF
  1388.     * There is a potential problem with the setting of the home directory on the
  1389.     * Mac when we generate a screen that isn't inside a true project. The home directory
  1390.     * will be set to the temporary file directory, which is not where we want to look for
  1391.     * relative paths. Adjust it here.
  1392.     IF UPPER(ALLTRIM(justpath(m.g_homedir))) == UPPER(sys(2023)) AND alldigits(juststem(m.g_homedir))
  1393.         SKIP
  1394.         m.g_target = name
  1395.         IF AT(CHR(0), name) > 0
  1396.             m.g_target = ALLTRIM(justpath(SUBSTR(name,1,AT(c_null,name)-1)))
  1397.         ENDIF
  1398.         m.g_homedir = FULLPATH(m.g_target, m.g_homedir)
  1399.            IF RIGHT(m.g_homedir,1) <> "\"
  1400.                m.g_homedir = m.g_homedir + "\"
  1401.         ENDIF
  1402.         SKIP -1
  1403.     ENDIF
  1404. ELSE
  1405.     m.g_homedir = ALLTRIM(SUBSTR(homedir,1,AT(c_null,homedir)-1))
  1406.     IF RIGHT(m.g_homedir,1) <> "\"
  1407.        m.g_homedir = m.g_homedir + "\"
  1408.     ENDIF
  1409. ENDIF
  1410.  
  1411. m.start = 1
  1412. m.g_devauthor = subdevinfo(m.start,c_authorlen,m.g_devauthor)
  1413.  
  1414. m.start = m.start + c_authorlen + 1
  1415. m.g_devcompany = subdevinfo(m.start,c_complen,m.g_devcompany)
  1416.  
  1417. m.start = m.start + c_complen + 1
  1418. m.g_devaddress = subdevinfo(m.start,c_addrlen,m.g_devaddress)
  1419.  
  1420. m.start = m.start + c_addrlen + 1
  1421. m.g_devcity = subdevinfo(m.start,c_citylen,m.g_devcity)
  1422.  
  1423. m.start = m.start + c_citylen + 1
  1424. m.g_devstate = subdevinfo(m.start,c_statlen,m.g_devstate)
  1425.  
  1426. m.start = m.start + c_statlen + 1
  1427. m.g_devzip = subdevinfo(m.start,c_ziplen,m.g_devzip)
  1428.  
  1429. m.start = m.start + c_ziplen + 1
  1430. m.g_devctry = subdevinfo(m.start,c_countrylen,m.g_devctry)
  1431.  
  1432. IF cmntstyle = 0
  1433.    m.g_corn1 = "╓"
  1434.    m.g_corn2 = "╖"
  1435.    m.g_corn3 = "╙"
  1436.    m.g_corn4 = "╜"
  1437.    m.g_corn5 = "╟"
  1438.    m.g_corn6 = "╢"
  1439.    m.g_horiz = "─"
  1440.    m.g_verti1 = "║"
  1441.    m.g_verti2= "║"
  1442. ENDIF
  1443. RETURN
  1444.  
  1445. *!*****************************************************************************
  1446. *!
  1447. *!       Function: ALLDIGITS
  1448. *!
  1449. *!*****************************************************************************
  1450. FUNCTION alldigits
  1451. PARAMETER m.strg
  1452. PRIVATE m.i, m.thechar, m.retval
  1453. m.retval = .T.
  1454. FOR m.i = 1 TO LEN(m.strg)
  1455.    m.thechar = SUBSTR(m.strg, m.i , 1)
  1456.    IF m.thechar < '0' OR m.thechar > '9'
  1457.       m.retval = .F.
  1458.    ENDIF
  1459. ENDFOR
  1460. RETURN m.retval
  1461.  
  1462.  
  1463. *!*****************************************************************************
  1464. *!
  1465. *!       Function: SUBDEVINFO
  1466. *!
  1467. *!      Called by: REFRESHPREFS       (procedure in GENSCRN.PRG)
  1468. *!
  1469. *!*****************************************************************************
  1470. FUNCTION subdevinfo
  1471. *)
  1472. *) SUBDEVINFO - Extract strings from the DEVINFO memo field.
  1473. *)
  1474. PARAMETER m.start, m.stop, m.default
  1475. PRIVATE m.string
  1476. m.string = SUBSTR(devinfo, m.start, m.stop+1)
  1477. m.string = SUBSTR(m.string, 1, AT(c_null,m.string)-1)
  1478. RETURN IIF(EMPTY(m.string), m.default, m.string)
  1479.  
  1480. **
  1481. ** High Level Controlling Structures in Format file generation.
  1482. **
  1483.  
  1484. *!*****************************************************************************
  1485. *!
  1486. *!      Procedure: BUILD
  1487. *!
  1488. *!      Called by: GENSCRN.PRG
  1489. *!
  1490. *!          Calls: BUILDENABLE        (procedure in GENSCRN.PRG)
  1491. *!               : ACTTHERM           (procedure in GENSCRN.PRG)
  1492. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1493. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1494. *!               : COMBINE            (procedure in GENSCRN.PRG)
  1495. *!               : BUILDDISABLE       (procedure in GENSCRN.PRG)
  1496. *!               : DEACTTHERMO        (procedure in GENSCRN.PRG)
  1497. *!
  1498. *!*****************************************************************************
  1499. PROCEDURE BUILD
  1500. *)
  1501. *) BUILD - Controlling procedure for building of a format file.
  1502. *)
  1503. *) Description:
  1504. *) This procedure is a controlling procedure for the process of
  1505. *) generating a screen file.  It enables building, activates the
  1506. *) thermometer, calls BUILDCTRL and combines two output files,
  1507. *) and finally disables building.
  1508. *) This procedure also makes calls to UPDTHERM to
  1509. *) update the thermometer display.
  1510. *)
  1511.  
  1512. DO buildenable
  1513. DO acttherm WITH "Generating Screen Code..."
  1514. DO updtherm WITH c_therm1 * m.g_numplatforms     && 5%
  1515.  
  1516. DO dispatchbuild
  1517.  
  1518. DO updtherm WITH c_therm7 * m.g_numplatforms     && 95%
  1519. DO combine
  1520. DO updtherm WITH 100 * m.g_numplatforms   && force thermometer to complete
  1521. DO builddisable
  1522.  
  1523. DO deactthermo
  1524. RETURN
  1525.  
  1526. *!*****************************************************************************
  1527. *!
  1528. *!      Procedure: DISPATCHBUILD
  1529. *!
  1530. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  1531. *!
  1532. *!          Calls: COUNTPLATFORMS     (procedure in GENSCRN.PRG)
  1533. *!               : PREPPARAMS         (procedure in GENSCRN.PRG)
  1534. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  1535. *!               : SCANPROC           (procedure in GENSCRN.PRG)
  1536. *!               : GENPARAMETER       (procedure in GENSCRN.PRG)
  1537. *!               : LOOKUPPLATFORM     (procedure in GENSCRN.PRG)
  1538. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  1539. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  1540. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  1541. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1542. *!               : NEWWINDOWS()       (function  in GENSCRN.PRG)
  1543. *!               : NEWDBFS()          (function  in GENSCRN.PRG)
  1544. *!               : NEWREADCLAUSES     (procedure in GENSCRN.PRG)
  1545. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  1546. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  1547. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  1548. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1549. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  1550. *!
  1551. *!*****************************************************************************
  1552. PROCEDURE dispatchbuild
  1553. *)
  1554. *) DISPATCHBUILD - Determines which platforms are to be generated and
  1555. *)                  calls BUILDCTRL for each one.
  1556. *)
  1557. PRIVATE m.i, m.thisplat, m.j
  1558. m.g_numplatforms = countplatforms()
  1559.  
  1560. DO prepparams
  1561.  
  1562. _TEXT = m.g_orghandle
  1563. _PRETEXT = ""
  1564.  
  1565. DO CASE
  1566. CASE multiplat()
  1567.    * Emit code for all common platforms in the screen set and put CASE statements
  1568.    * around the code for each one.  The g_platforms array contains the list of
  1569.    * platforms to generate for.
  1570.  
  1571.    * If generating for multiple platforms, scan all cleanup snippets and assemble an
  1572.    * array of unique procedure names.  This process is designed to handle procedure name
  1573.    * collisions across platforms.
  1574.    DO scanproc
  1575.  
  1576.    DO header   && main heading at top of program
  1577.  
  1578.    * Special case when there are multiple platforms being sent to the
  1579.    * same SPR.  Since the SPR can only have a single parameter statement,
  1580.    * and since it has to appear before the CASE _platform code, put it
  1581.    * here.
  1582.    DO genparameter
  1583.  
  1584.    m.thisplat = "X"   && placeholder value
  1585.    m.i = 1
  1586.    DO WHILE !EMPTY(m.thisplat)
  1587.       m.thisplat = lookupplatform(m.i)
  1588.       IF !EMPTY(m.thisplat)
  1589.          DO putmsg WITH "Generating code for "+versioncap(m.thisplat, m.g_dualoutput)
  1590.  
  1591.          IF m.i = 1
  1592.             \DO CASE
  1593.          ELSE
  1594.             \
  1595.          ENDIF
  1596.          DO gencasestmt WITH m.thisplat
  1597.          \
  1598.  
  1599.          * Switch the platform to generate for
  1600.          m.g_genvers = m.thisplat
  1601.  
  1602.          * Update screen array entries for the new platform, unless it's the currently
  1603.          * executing platform, in which case we did this just above.
  1604.          IF !(m.thisplat == m.g_thisvers)
  1605.             * Start with a fresh set of screens.  Prepscreens() fills in the details.
  1606.             g_nscreens = 0
  1607.             IF !prepscreens(m.thisplat)
  1608.                DO errorhandler WITH "Error initializing screens for ";
  1609.                   +PROPER(m.thisplat)+".", LINENO(), c_error_3
  1610.                CANCEL
  1611.             ENDIF
  1612.             DO newwindows      && initialize the window array
  1613.             DO newdbfs         && initialize the DBF name array
  1614.             DO newreadclauses  && initialize the read clause variables
  1615.             DO newdirectives   && initialize the directives that change from platform to platform
  1616.             DO newschemes      && initialize the scheme variables
  1617.          ENDIF
  1618.  
  1619.          DO pushindent
  1620.          DO buildctrl WITH m.thisplat, m.i, .F.
  1621.          DO popindent
  1622.       ENDIF
  1623.       m.i = m.i + 1
  1624.    ENDDO
  1625.    \
  1626.    \ENDCASE
  1627.    \
  1628.    _TEXT = m.g_tmphandle
  1629.    m.thispretext = _PRETEXT
  1630.    _PRETEXT = ""
  1631.    DO updtherm WITH c_therm6 * m.g_numplatforms  && 70%
  1632.    DO genprocedures
  1633.    _TEXT = m.g_orghandle
  1634.    _PRETEXT = m.thispretext
  1635.  
  1636. OTHERWISE                         && just outputing one platform.
  1637.    * If we are generating for a platform other than the one we are running
  1638.    * on, run through prepscreens again to assign the right platform
  1639.    * name to each of these screens.
  1640.    IF (_DOS AND g_platforms[1] <> "DOS") ;
  1641.          OR (_WINDOWS AND g_platforms[1] <> "WINDOWS") ;
  1642.          OR (_MAC AND g_platforms[1] <> "MAC") ;
  1643.          OR (_UNIX AND g_platforms[1] <> "UNIX")
  1644.       g_nscreens = 0
  1645.       IF !prepscreens(g_platforms[1])
  1646.          DO errorhandler WITH "Error initializing screens for ";
  1647.             +PROPER(m.thisplat)+".", LINENO(), c_error_3
  1648.          CANCEL
  1649.       ENDIF
  1650.    ENDIF
  1651.  
  1652.    m.g_allplatforms = .F.
  1653.    m.g_numplatforms = 1
  1654.    m.g_genvers      = g_platforms[1]
  1655.  
  1656.    DO newwindows      && Initialize the array of window names
  1657.    DO newdbfs         && Initialize the array of DBF names
  1658.    DO newreadclauses  && Initialize the read clause variables for each platform
  1659.    DO newdirectives   && Initialize the directives that change from platform to platform
  1660.    DO newschemes      && initialize the scheme variables
  1661.  
  1662.    DO header
  1663.    DO buildctrl WITH g_platforms[1], 1, .T.
  1664.  
  1665.    DO updtherm WITH  c_therm6   && 70%
  1666.    DO genprocedures
  1667. ENDCASE
  1668. RETURN
  1669.  
  1670.  
  1671. **
  1672. ** Code Associated With Building of the Control Program.
  1673. **
  1674. *!*****************************************************************************
  1675. *!
  1676. *!      Procedure: BUILDCTRL
  1677. *!
  1678. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1679. *!
  1680. *!          Calls: HEADER             (procedure in GENSCRN.PRG)
  1681. *!               : GENPARAMETER       (procedure in GENSCRN.PRG)
  1682. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  1683. *!               : GENSETENVIRON      (procedure in GENSCRN.PRG)
  1684. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  1685. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1686. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  1687. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  1688. *!               : DEFPOPUPS          (procedure in GENSCRN.PRG)
  1689. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  1690. *!               : GENCLNENVIRON      (procedure in GENSCRN.PRG)
  1691. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  1692. *!
  1693. *!*****************************************************************************
  1694. PROCEDURE buildctrl
  1695. *)
  1696. *) BUILDCTRL - Generate Format control file.
  1697. *)
  1698. *) Description:
  1699. *) Buildctrl controls the generation process.  It invokes procedures
  1700. *) which build the output program from a set of screens.
  1701. *)
  1702. PARAMETERS m.pltfrm, m.pnum, m.putparam, m.dbalias
  1703. PRIVATE m.i
  1704.  
  1705. IF m.putparam
  1706.    * Bracketed code is handled elsewhere.  We are only emitting the parameter
  1707.    * from this platform.  Go get it again to make sure we have the right one.
  1708.    * At this point, g_parameter could contain the parameter from any platform.
  1709.  
  1710.    * Open the database for the first screen since it's the only one we can generate
  1711.    * a parameter statement for.
  1712.    m.dbalias = g_screens[1,5]
  1713.    SELECT (m.dbalias)
  1714.    DO seekheader WITH 1
  1715.  
  1716.    m.g_parameter = getparam("setupcode")
  1717.  
  1718.    DO genparameter
  1719. ENDIF
  1720. DO gensect1                                && SECTION 1 setup code
  1721. DO gensetenviron                        && environment setup code
  1722. IF m.g_openfiles
  1723.    DO genopendbfs                        && USE ... INDEX ... statements
  1724. ENDIF
  1725. DO updtherm WITH thermadj(m.pnum,c_therm2,c_therm5)    && and SET RELATIONS
  1726.  
  1727. DO defwindows                             && window definitions
  1728. DO gensect2                                && SECTION 2 setup code
  1729. DO defpopups                            && lists
  1730. DO updtherm WITH thermadj(m.pnum,c_therm3,c_therm5)
  1731.  
  1732. DO buildfmt WITH m.pnum            && @ ... SAY/GET statements
  1733.  
  1734. DO updtherm WITH thermadj(m.pnum,c_therm4,c_therm5)
  1735. IF m.g_windows AND m.g_relwin AND !m.g_noread
  1736.    * If the READ is omitted, don't produce the code to release the window.
  1737.    FOR m.i = 1 TO m.g_nwindows
  1738.       \RELEASE WINDOW <<g_wndows[m.i,1]>>
  1739.    ENDFOR
  1740. ENDIF
  1741.  
  1742. IF m.g_moddesktop AND m.g_relwin AND INLIST(m.g_genvers,"WINDOWS","MAC")
  1743.    \MODIFY WINDOW SCREEN
  1744. ENDIF
  1745.  
  1746. DO genclnenviron                        && environment cleanup code
  1747. DO updtherm WITH thermadj(m.pnum,c_therm5,c_therm5)
  1748. DO gencleanup                       && cleanup code, but not procedures/functions
  1749.  
  1750. *!*****************************************************************************
  1751. *!
  1752. *!      Procedure: GENSETENVIRON
  1753. *!
  1754. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1755. *!
  1756. *!*****************************************************************************
  1757. PROCEDURE gensetenviron
  1758. *)
  1759. *) GENSETENVIRON - Generate environment code for the .SPR
  1760. *)
  1761. IF !m.g_noreadplain
  1762.    \
  1763.    \#REGION 0
  1764.    \REGIONAL m.currarea, m.talkstat, m.compstat
  1765.    \
  1766.    \IF SET("TALK") = "ON"
  1767.    \    SET TALK OFF
  1768.    \    m.talkstat = "ON"
  1769.    \ELSE
  1770.    \    m.talkstat = "OFF"
  1771.    \ENDIF
  1772.    \m.compstat = SET("COMPATIBLE")
  1773.    \SET COMPATIBLE FOXPLUS
  1774.  
  1775.    IF INLIST(m.g_genvers,"WINDOWS","MAC")
  1776.       \
  1777.       \m.rborder = SET("READBORDER")
  1778.       \SET READBORDER <<IIF(m.g_readborder, "ON", "OFF")>>
  1779.    ENDIF
  1780. ENDIF
  1781.  
  1782. IF m.g_closefiles
  1783.    \
  1784.    \m.currarea = SELECT()
  1785.    \
  1786. ENDIF
  1787. RETURN
  1788.  
  1789. *!*****************************************************************************
  1790. *!
  1791. *!      Procedure: GENCLNENVIRON
  1792. *!
  1793. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1794. *!
  1795. *!          Calls: GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  1796. *!               : RELPOPUPS          (procedure in GENSCRN.PRG)
  1797. *!
  1798. *!*****************************************************************************
  1799. PROCEDURE genclnenviron
  1800. *)
  1801. *) GENCLNENVIRON - Generate environment code for the .SPR
  1802. *)
  1803. IF m.g_closefiles
  1804.    DO genclosedbfs
  1805. ENDIF
  1806. IF m.g_somepops
  1807.    DO relpopups
  1808. ENDIF
  1809. IF !m.g_noreadplain
  1810.    \
  1811.    \#REGION 0
  1812.    IF INLIST(m.g_genvers,"WINDOWS","MAC")
  1813.       \
  1814.       \SET READBORDER &rborder
  1815.       \
  1816.    ENDIF
  1817.    \IF m.talkstat = "ON"
  1818.    \    SET TALK ON
  1819.    \ENDIF
  1820.    \IF m.compstat = "ON"
  1821.    \    SET COMPATIBLE ON
  1822.    \ENDIF
  1823.    \
  1824. ENDIF
  1825. RETURN
  1826.  
  1827. *!*****************************************************************************
  1828. *!
  1829. *!      Procedure: GENCLEANUP
  1830. *!
  1831. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1832. *!
  1833. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  1834. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  1835. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  1836. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  1837. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  1838. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  1839. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  1840. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  1841. *!
  1842. *!*****************************************************************************
  1843. PROCEDURE gencleanup
  1844. *)
  1845. *) GENCLEANUP - Generate Cleanup Code.
  1846. *)
  1847. PRIVATE m.i, m.dbalias, m.msg
  1848.  
  1849. IF m.g_graphic
  1850.    m.msg = 'Generating Cleanup Code'
  1851.    IF multiplat()
  1852.       m.msg = m.msg + " for "+versioncap(m.g_genvers, m.g_dualoutput)
  1853.    ENDIF
  1854.    DO putmsg WITH  m.msg
  1855. ENDIF
  1856.  
  1857. * Generate the actual cleanup code--the code that precedes procedures
  1858. * and function declarations.
  1859. FOR m.i = 1 TO m.g_nscreens
  1860.    m.g_screen = m.i
  1861.    m.dbalias = g_screens[m.i,5]
  1862.    SELECT (m.dbalias)
  1863.  
  1864.    DO seekheader WITH m.i
  1865.    IF EMPTY (proccode)
  1866.       g_firstproc[m.i] = 0
  1867.       LOOP
  1868.    ENDIF
  1869.  
  1870.    * Find the line number where the first procedure or function
  1871.    * declaration occurs
  1872.    g_firstproc[m.i] = getfirstproc("PROCCODE")
  1873.  
  1874.    IF g_firstproc[m.i] <> 1
  1875.       * Either there aren't any procedures/functions, or they
  1876.       * are below the actual cleanup code.  Emit the cleanup code.
  1877.       DO commentblock WITH g_screens[m.i,1], " Cleanup Code"
  1878.       \#REGION <<INT(m.i)>>
  1879.       DO writecode WITH proccode, getplatname(m.i), c_fromone, g_firstproc[m.i], m.i
  1880.    ENDIF
  1881. ENDFOR
  1882. m.g_screen = 0
  1883.  
  1884. RETURN
  1885.  
  1886. *!*****************************************************************************
  1887. *!
  1888. *!      Procedure: GENPROCEDURES
  1889. *!
  1890. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1891. *!
  1892. *!          Calls: PUTMSG             (procedure in GENSCRN.PRG)
  1893. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  1894. *!               : PUTPROCHEAD        (procedure in GENSCRN.PRG)
  1895. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  1896. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  1897. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  1898. *!               : ISGENPLAT()        (function  in GENSCRN.PRG)
  1899. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  1900. *!
  1901. *!*****************************************************************************
  1902. PROCEDURE genprocedures
  1903. *)
  1904. *) GENPROCEDURES - Generate Procedures and Functions from cleanup code.
  1905. *)
  1906. PRIVATE m.i, m.dbalias
  1907. m.msg = 'Generating Procedures and Functions'
  1908. DO putmsg WITH m.msg
  1909.  
  1910. * Go back through each of the screens and output any procedures and
  1911. * functions that are in the cleanup snippet.
  1912. FOR m.i = 1 TO m.g_nscreens
  1913.    m.g_screen = m.i
  1914.    m.g_isfirstproc = .T.  && reset this for each screen
  1915.    m.dbalias = g_screens[m.i,5]
  1916.    SELECT (m.dbalias)
  1917.    DO seekheader WITH m.i
  1918.  
  1919.    DO CASE
  1920.    CASE g_screens[m.i,6]    && DOS 2.0 screen
  1921.       IF g_firstproc[m.i] > 0
  1922.          DO putprochead WITH m.i, g_screens[m.i,1]
  1923.          DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1924.       ENDIF
  1925.    CASE multiplat()
  1926.       * Multiple 2.5 platforms
  1927.       IF m.g_procsmatch   && all cleanup snippets in the file are the same
  1928.          * Get all the screen/platform headers from this screen file
  1929.          IF g_firstproc[m.i] > 0
  1930.             DO putprochead WITH m.i, g_screens[m.i,1]
  1931.             DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1932.          ENDIF
  1933.       ELSE
  1934.          * The are some differences.  Look for procedure name collisions among the
  1935.          * cleanup snippets in the platforms we are generating.
  1936.          SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  1937.             IF EMPTY(proccode)
  1938.                LOOP
  1939.             ENDIF
  1940.             DO putprochead WITH m.i, g_screens[m.i,1]
  1941.             DO extractprocs WITH m.i
  1942.          ENDSCAN
  1943.       ENDIF
  1944.    OTHERWISE  && just generating one 2.5 platform
  1945.       IF g_firstproc[m.i] > 0
  1946.          DO putprochead WITH m.i, g_screens[m.i,1]
  1947.          DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1948.       ENDIF
  1949.    ENDCASE
  1950. ENDFOR
  1951. m.g_screen = 0
  1952. RETURN
  1953.  
  1954. *!*****************************************************************************
  1955. *!
  1956. *!       Function: PROCSMATCH
  1957. *!
  1958. *!      Called by: SCANPROC           (procedure in GENSCRN.PRG)
  1959. *!
  1960. *!          Calls: ISGENPLAT()        (function  in GENSCRN.PRG)
  1961. *!
  1962. *!*****************************************************************************
  1963. FUNCTION procsmatch
  1964. *)
  1965. *) PROCSMATCH - Are the CRCs for the cleanup snippets the same for all platforms in the
  1966. *)                current screen that are being generated?
  1967. *)
  1968. PRIVATE m.crccode, m.thiscode, m.in_rec
  1969.  
  1970. m.in_rec = IIF(!EOF(),RECNO(),1)
  1971. m.crccode = "0"
  1972. * Get the headers for all the platforms we are generating
  1973. SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  1974.    m.thiscode = ALLTRIM(SYS(2007,proccode))
  1975.    DO CASE
  1976.    CASE m.crccode = "0"
  1977.       m.crccode = m.thiscode
  1978.    CASE m.thiscode <> m.crccode AND m.crccode <> "0"
  1979.       RETURN .F.
  1980.    ENDCASE
  1981. ENDSCAN
  1982. GOTO m.in_rec
  1983. RETURN .T.
  1984.  
  1985. *!*****************************************************************************
  1986. *!
  1987. *!       Function: ISGENPLAT
  1988. *!
  1989. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  1990. *!               : PROCSMATCH()       (function  in GENSCRN.PRG)
  1991. *!               : SCANPROC           (procedure in GENSCRN.PRG)
  1992. *!
  1993. *!*****************************************************************************
  1994. FUNCTION isgenplat
  1995. *)
  1996. *) ISGENPLAT - Is this platform one of the ones being generated?
  1997. *)
  1998. PARAMETER m.platname
  1999. RETURN IIF(ASCAN(g_platforms,ALLTRIM(UPPER(m.platname))) > 0, .T. , .F. )
  2000.  
  2001. *!*****************************************************************************
  2002. *!
  2003. *!      Procedure: PUTPROCHEAD
  2004. *!
  2005. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  2006. *!
  2007. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2008. *!
  2009. *!*****************************************************************************
  2010. PROCEDURE putprochead
  2011. *)
  2012. *) PUTPROCHEAD - Emit the procedure and function heading if we haven't done
  2013. *)
  2014. PARAMETER m.scrnno, m.filname
  2015. IF m.g_isfirstproc
  2016.    \
  2017.    DO commentblock WITH g_screens[m.scrnno,1], " Supporting Procedures and Functions "
  2018.    \#REGION <<INT(m.scrnno)>>
  2019.    m.g_isfirstproc = .F.
  2020. ENDIF
  2021. RETURN
  2022.  
  2023. *!*****************************************************************************
  2024. *!
  2025. *!      Procedure: EXTRACTPROCS
  2026. *!
  2027. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  2028. *!
  2029. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2030. *!               : MATCH()            (function  in GENSCRN.PRG)
  2031. *!               : GETPROCNUM()       (function  in GENSCRN.PRG)
  2032. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  2033. *!               : HASCONFLICT()      (function  in GENSCRN.PRG)
  2034. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2035. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  2036. *!               : PROCCOMMENTBLOCK   (procedure in GENSCRN.PRG)
  2037. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  2038. *!
  2039. *!*****************************************************************************
  2040. PROCEDURE extractprocs
  2041. *)
  2042. *) EXTRACTPROCS - Output the procedures for the current platform in the current screen
  2043. *)
  2044. * We only get here if we are emitting for multiple platforms and the cleanup snippets
  2045. * for all platforms are not identical.  We are positioned on a screen header record for
  2046. * the g_genvers platform.
  2047. PARAMETER m.scrnno
  2048.  
  2049. PRIVATE m.hascontin, m.iscontin, m.sniplen, m.i, m.thisline, m.pnum, m.word1, m.word2
  2050.  
  2051. _MLINE = 0
  2052. m.sniplen   = LEN(proccode)
  2053. m.numlines  = MEMLINES(proccode)
  2054. m.hascontin = .F.
  2055. DO WHILE _MLINE < m.sniplen
  2056.    m.thisline  = UPPER(ALLTRIM(MLINE(proccode,1, _MLINE)))
  2057.    DO killcr WITH m.thisline
  2058.    m.iscontin  = m.hascontin
  2059.    m.hascontin = RIGHT(m.thisline,1) = ';'
  2060.    IF LEFT(m.thisline,1) $ "PF" AND !m.iscontin
  2061.       m.word1 = wordnum(m.thisline, 1)
  2062.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2063.          m.word2 = wordnum(m.thisline,2)
  2064.          * Does this procedure have a name conflict?
  2065.          m.pnum = getprocnum(m.word2)
  2066.          IF pnum > 0
  2067.             DO CASE
  2068.             CASE g_procs[m.pnum,C_MAXPLATFORMS+2]
  2069.                * This one has already been generated.  Skip past it now.
  2070.                DO emitproc WITH .F., m.thisline, m.sniplen, m.scrnno
  2071.                LOOP
  2072.             CASE hasconflict(pnum)
  2073.                * Name collision detected.  Output bracketed code for all platforms
  2074.                DO putmsg WITH "Generating code for procedure/function ";
  2075.                   +LOWER(g_procs[m.pnum,1])
  2076.                DO updtherm WITH thermadj(m.pnum,c_therm6 + (c_therm7-c_therm6)/m.g_procnames,c_therm7)
  2077.                DO proccommentblock WITH g_screens[m.scrnno,1], " "+PROPER(word1);
  2078.                   +" " + g_procs[m.pnum,1]
  2079.                DO emitbracket WITH m.pnum, m.scrnno
  2080.             OTHERWISE
  2081.                * This procedure has no name collision and has not been emitted yet.
  2082.                DO putmsg WITH "Generating code for procedure/function ";
  2083.                   +LOWER(g_procs[m.pnum,1])
  2084.                DO updtherm WITH thermadj(m.pnum,c_therm6 + (c_therm7-c_therm6)/m.g_procnames,c_therm7)
  2085.                *DO updtherm WITH (c_therm6 + ((c_therm7-c_therm6)/g_procnames) * m.pnum) * m.g_numplatforms
  2086.                DO proccommentblock WITH g_screens[m.scrnno,1], " "+PROPER(word1);
  2087.                   +" " + g_procs[m.pnum,1]
  2088.                DO emitproc WITH .T., m.thisline, m.sniplen, m.scrnno
  2089.             ENDCASE
  2090.             g_procs[pnum,C_MAXPLATFORMS+2] = .T.
  2091.          ENDIF
  2092.       ENDIF
  2093.    ENDIF
  2094. ENDDO
  2095. RETURN
  2096.  
  2097. *!*****************************************************************************
  2098. *!
  2099. *!      Procedure: EMITPROC
  2100. *!
  2101. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2102. *!
  2103. *!          Calls: WRITELINE          (procedure in GENSCRN.PRG)
  2104. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  2105. *!               : MATCH()            (function  in GENSCRN.PRG)
  2106. *!
  2107. *!*****************************************************************************
  2108. PROCEDURE emitproc
  2109. *)
  2110. *) EMITPROC - Scan through the next procedure/function in the current cleanup snippet.
  2111. *)            If dowrite is TRUE, emit the code as we go.  Otherwise, just skip over it
  2112. *)            and advance _MLINE.
  2113. *)
  2114. * We are positioned on the PROCEDURE or FUNCTION line now and there isn't a name
  2115. * conflict.
  2116. PARAMETER m.dowrite, m.thisline, m.sniplen, m.scrnno
  2117. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  2118.    m.iscontin, m.hascontin, m.platnum
  2119.  
  2120. m.hascontin = .F.
  2121. m.done = .F.
  2122.  
  2123. * Write the PROCEDURE/FUNCTION statement
  2124. m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2125.  
  2126. IF g_screens[m.scrnno,6]   && DOS 2.0 screen
  2127.    m.platnum = getplatnum("DOS")
  2128. ELSE
  2129.    m.platnum = getplatnum(m.g_genvers)
  2130. ENDIF
  2131.  
  2132. IF m.dowrite    && actually emit the procedure?
  2133.    DO writeline WITH m.thisline, m.g_genvers, m.platnum, m.upline, m.scrnno
  2134. ENDIF
  2135.  
  2136. * Write the body of the procedure
  2137. DO WHILE !m.done AND _MLINE < m.sniplen
  2138.    m.lastmline = _MLINE          && note where this line started
  2139.  
  2140.    m.line = MLINE(proccode,1, _MLINE)
  2141.    DO killcr WITH m.line
  2142.    m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2143.  
  2144.    m.iscontin = m.hascontin
  2145.    m.hascontin = RIGHT(m.upline,1) = ';'
  2146.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2147.       m.word1 = wordnum(m.upline, 1)
  2148.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2149.          done = .T.
  2150.          _MLINE = m.lastmline    && drop back one line and stop writing
  2151.          LOOP
  2152.       ENDIF
  2153.    ENDIF
  2154.  
  2155.    IF m.dowrite    && actually emit the procedure?
  2156.       DO writeline WITH m.line, m.g_genvers, m.platnum, m.upline, m.scrnno
  2157.    ENDIF
  2158.  
  2159. ENDDO
  2160. RETURN
  2161.  
  2162. *!*****************************************************************************
  2163. *!
  2164. *!      Procedure: EMITBRACKET
  2165. *!
  2166. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2167. *!
  2168. *!          Calls: PUSHINDENT         (procedure in GENSCRN.PRG)
  2169. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  2170. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  2171. *!
  2172. *!*****************************************************************************
  2173. PROCEDURE emitbracket
  2174. *)
  2175. *) EMITBRACKET - Emit DO CASE/CASE _DOS brackets and call putproc to emit code for this procedure
  2176. *)
  2177. PARAMETER m.pnum, m.scrnno
  2178. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  2179.    m.iscontin, m.hascontin, m.i
  2180. m.hascontin = .F.
  2181. m.done = .F.
  2182. \
  2183. \PROCEDURE <<g_procs[m.pnum,1]>>
  2184. IF !EMPTY(g_procs[m.pnum,C_MAXPLATFORMS+3])
  2185.    \PARAMETERS <<g_procs[m.pnum,C_MAXPLATFORMS+3]>>
  2186. ENDIF
  2187. \DO CASE
  2188.  
  2189. * Peek ahead and get the parameter statement
  2190. FOR m.platnum = 1 TO c_maxplatforms
  2191.    IF g_procs[m.pnum,m.platnum+1] < 0
  2192.       * There was no procedure for this platform
  2193.       LOOP
  2194.    ENDIF
  2195.    \CASE <<"_"+g_platlist[m.platnum]>>
  2196.    DO pushindent
  2197.    DO putproc WITH m.platnum, m.pnum, m.scrnno
  2198.    DO popindent
  2199. ENDFOR
  2200. \ENDCASE
  2201. RETURN
  2202.  
  2203. *!*****************************************************************************
  2204. *!
  2205. *!      Procedure: PUTPROC
  2206. *!
  2207. *!      Called by: EMITBRACKET        (procedure in GENSCRN.PRG)
  2208. *!
  2209. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2210. *!               : MATCH()            (function  in GENSCRN.PRG)
  2211. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2212. *!
  2213. *!*****************************************************************************
  2214. PROCEDURE putproc
  2215. *)
  2216. *) PUTPROC - Write actual code for procedure procnum in platform platnum
  2217. *)
  2218. PARAMETER m.platnum, m.procnum, m.scrnno
  2219. PRIVATE m.in_rec, m.oldmine, m.done, m.line, m.upline, m.iscontin, m.hascontin, ;
  2220.    m.word1, m.word2, m.platnum
  2221.  
  2222. m.in_rec    = RECNO()
  2223. * Store the _MLINE position in the original snippet
  2224. m.oldmline  = _MLINE
  2225. m.hascontin = .F.       && the previous line was not a continuation line.
  2226. LOCATE FOR platform = g_platlist[m.platnum] AND objtype = c_otscreen
  2227. IF FOUND()
  2228.    * go to the PROCEDURE/FUNCTION statement
  2229.    _MLINE = g_procs[m.procnum,m.platnum+1]
  2230.    * Skip the PROCEDURE line, since we've already output one.
  2231.    m.line = MLINE(proccode,1, _MLINE)
  2232.    DO killcr WITH m.line
  2233.  
  2234.    * We are now positioned at the line following the procedure statement.
  2235.    * Write until the end of the snippet or the next procedure.
  2236.    m.done = .F.
  2237.    DO WHILE !m.done
  2238.       m.line = MLINE(proccode,1, _MLINE)
  2239.       DO killcr WITH m.line
  2240.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2241.       m.iscontin = m.hascontin
  2242.       m.hascontin = RIGHT(m.upline,1) = ';'
  2243.       IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2244.          m.word1 = wordnum(m.upline, 1)
  2245.          IF RIGHT(m.word1,1) = ';'
  2246.             m.word1 = LEFT(m.word1,LEN(m.word1)-1)
  2247.          ENDIF
  2248.  
  2249.          DO CASE
  2250.          CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2251.             * Stop when we encounter the next snippet
  2252.             m.done = .T.
  2253.             LOOP
  2254.          CASE match(m.word1,"PARAMETERS")
  2255.             * Don't output it, but keep scanning for other code
  2256.             DO WHILE m.hascontin
  2257.                m.line = MLINE(proccode,1, _MLINE)
  2258.                DO killcr WITH m.line
  2259.                m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2260.                m.hascontin = RIGHT(m.upline,1) = ';'
  2261.             ENDDO
  2262.             LOOP
  2263.          ENDCASE
  2264.       ENDIF
  2265.  
  2266.       DO writeline WITH m.line, g_platlist[m.platnum], m.platnum, m.upline, m.scrnno
  2267.  
  2268.       * Stop if we've run out of snippet
  2269.       IF _MLINE >= LEN(proccode)
  2270.          m.done = .T.
  2271.       ENDIF
  2272.    ENDDO
  2273. ENDIF
  2274.  
  2275. GOTO m.in_rec
  2276. * Restore the _MLINE position in the main snippet we are outputing
  2277. _MLINE = m.oldmline
  2278. RETURN
  2279.  
  2280. *!*****************************************************************************
  2281. *!
  2282. *!       Function: GETPROCNUM
  2283. *!
  2284. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2285. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2286. *!
  2287. *!*****************************************************************************
  2288. FUNCTION getprocnum
  2289. *)
  2290. *) GETPROCNUM - Return the g_procs array position of the procedure named pname
  2291. *)
  2292. PARAMETER m.pname
  2293. PRIVATE m.i
  2294. FOR m.i = 1 TO g_procnames
  2295.    IF g_procs[m.i,1] == m.pname
  2296.       RETURN m.i
  2297.    ENDIF
  2298. ENDFOR
  2299. RETURN  0
  2300.  
  2301. *!*****************************************************************************
  2302. *!
  2303. *!       Function: HASCONFLICT
  2304. *!
  2305. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2306. *!
  2307. *!*****************************************************************************
  2308. FUNCTION hasconflict
  2309. *)
  2310. *) HASCONFLICT - Is there a name collision for procedure number num?
  2311. *)
  2312. PARAMETER m.num
  2313. PRIVATE m.i, m.cnt
  2314. m.cnt = 0
  2315. FOR m.i = 1 TO c_maxplatforms
  2316.    IF g_procs[m.num,m.i+1] > 0
  2317.       m.cnt = m.cnt +1
  2318.    ENDIF
  2319. ENDFOR
  2320. RETURN IIF(m.cnt > 1,.T.,.F.)
  2321.  
  2322.  
  2323. *!*****************************************************************************
  2324. *!
  2325. *!       Function: GETFIRSTPROC
  2326. *!
  2327. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  2328. *!
  2329. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2330. *!               : MATCH()            (function  in GENSCRN.PRG)
  2331. *!
  2332. *!*****************************************************************************
  2333. FUNCTION getfirstproc
  2334. *)
  2335. *) GETFIRSTPROC - Find first PROCEDURE or FUNCTION statement in a cleanup
  2336. *)                snippet and return the line number on which it occurs.
  2337. *)
  2338. PARAMETER m.snipname
  2339. PRIVATE proclineno, numlines, word1, first_space
  2340. _MLINE = 0
  2341. m.numlines = MEMLINES(&snipname)
  2342. FOR m.proclineno = 1 TO m.numlines
  2343.    m.line  = MLINE(&snipname, 1, _MLINE)
  2344.    DO killcr WITH m.line
  2345.    m.line  = UPPER(LTRIM(m.line))
  2346.    m.word1 = wordnum(m.line,1)
  2347.    IF !EMPTY(m.word1) AND (match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION"))
  2348.       RETURN m.proclineno
  2349.    ENDIF
  2350. ENDFOR
  2351. RETURN 0
  2352.  
  2353. *!*****************************************************************************
  2354. *!
  2355. *!      Procedure: SCANPROC
  2356. *!
  2357. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  2358. *!
  2359. *!          Calls: PROCSMATCH()       (function  in GENSCRN.PRG)
  2360. *!               : ISGENPLAT()        (function  in GENSCRN.PRG)
  2361. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2362. *!
  2363. *!*****************************************************************************
  2364. PROCEDURE scanproc
  2365. *)
  2366. *) SCANPROC - Find unique procedure names in cleanup snippets for all platforms
  2367. *)
  2368. PRIVATE m.in_rec
  2369. * See if all the cleanup snippets are the same.  If so, stop now.
  2370. m.g_procsmatch = .T.
  2371. FOR m.g_screen = 1 TO m.g_nscreens
  2372.    m.dbalias = g_screens[m.g_screen,5]
  2373.    SELECT (m.dbalias)
  2374.    IF !g_screens[m.g_screen,6]      && not applicable for FoxPro 2.0 screens
  2375.       m.g_procsmatch = m.g_procsmatch AND procsmatch()
  2376.     ENDIF
  2377. ENDFOR
  2378.  
  2379. IF !m.g_procsmatch
  2380.    FOR m.g_screen = 1 TO m.g_nscreens
  2381.       m.dbalias = g_screens[m.g_screen,5]
  2382.       SELECT (m.dbalias)
  2383.  
  2384.       IF !g_screens[m.g_screen,6]      && not applicable for FoxPro 2.0 screens
  2385.          SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  2386.             DO updprocarray
  2387.          ENDSCAN
  2388.       ENDIF
  2389.    ENDFOR
  2390.    m.g_screen = 0
  2391. ENDIF
  2392. RETURN
  2393.  
  2394. *!*****************************************************************************
  2395. *!
  2396. *!      Procedure: UPDPROCARRAY
  2397. *!
  2398. *!      Called by: SCANPROC           (procedure in GENSCRN.PRG)
  2399. *!
  2400. *!          Calls: VERSIONCAP()       (function  in GENSCRN.PRG)
  2401. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2402. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  2403. *!               : MATCH()            (function  in GENSCRN.PRG)
  2404. *!               : ADDPROCNAME        (procedure in GENSCRN.PRG)
  2405. *!               : GETPROCNUM()       (function  in GENSCRN.PRG)
  2406. *!               : CLEANPARAM()       (function  in GENSCRN.PRG)
  2407. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  2408. *!
  2409. *!*****************************************************************************
  2410. PROCEDURE updprocarray
  2411. *)
  2412. *) UPDPROCARRAY - Pick out the procedures names in the current cleanup snippet and call
  2413. *)                  AddProcName to update the g_procs array.
  2414. *)
  2415. PRIVATE m.i, m.numlines, m.line, m.upline, m.word1, m.word2, m.iscontin, m.hascontin, ;
  2416.    m.lastmline, m.thisproc
  2417.  
  2418. DO putmsg WITH "Scanning cleanup snippet for ";
  2419.    +versioncap( IIF(TYPE("platform")<>"U",platform,"DOS"), m.g_dualoutput )
  2420.  
  2421. _MLINE = 0
  2422. m.numlines = MEMLINES(proccode)
  2423. m.hascontin = .F.
  2424. FOR m.i = 1 TO m.numlines
  2425.    m.lastmline = _MLINE                && note starting position of this line
  2426.    m.line      = MLINE(proccode,1, _MLINE)
  2427.    DO killcr WITH m.line
  2428.    m.upline    = UPPER(ALLTRIM(m.line))
  2429.    m.iscontin  = m.hascontin
  2430.    m.hascontin = RIGHT(m.upline,1) = ';'
  2431.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2432.       m.word1 = CHRTRAN(wordnum(m.upline, 1),';','')
  2433.       DO CASE
  2434.       CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2435.          m.word2 = wordnum(m.upline,2)
  2436.          DO addprocname WITH m.word2, platform, m.i, m.lastmline
  2437.          m.lastproc = m.word2
  2438.       CASE match(m.word1,"PARAMETERS")
  2439.          * Associate this parameter statement with the last procedure or function
  2440.          m.thisproc = getprocnum(m.lastproc)
  2441.          IF m.thisproc > 0
  2442.             m.thisparam = ALLTRIM(SUBSTR(m.upline,AT(' ',m.upline)+1))
  2443.             * Deal with continued PARAMETER lines
  2444.             DO WHILE m.hascontin AND m.i <= m.numlines
  2445.                m.lastmline = _MLINE                && note the starting position of this line
  2446.                m.line   = MLINE(proccode,1, _MLINE)
  2447.                DO killcr WITH m.line
  2448.                m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2449.                m.thisparam = ;
  2450.                   m.thisparam + CHR(13)+CHR(10) + m.line
  2451.                m.hascontin = RIGHT(m.upline,1) = ';'
  2452.                m.i = m.i + 1
  2453.             ENDDO
  2454.             * Make sure that this parameter matches any others we've seen for this function
  2455.             DO CASE
  2456.             CASE EMPTY(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2457.                * First occurrence, or one platform has a parameter statement and another doesn't
  2458.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  2459.             CASE cleanparam(m.thisparam) == cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2460.                * It matches--do nothing
  2461.             CASE cleanparam(m.thisparam) = cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2462.                * The new one is a superset of the existing one.  Use the longer one.
  2463.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  2464.             CASE cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3]) = cleanparam(m.thisparam)
  2465.                * The old one is a superset of the new one.  Keep the longer one.
  2466.             OTHERWISE
  2467.                DO errorhandler WITH "Different parameters for "+g_procs[m.thisproc,1],;
  2468.                   LINENO(),c_error_3
  2469.             ENDCASE
  2470.          ENDIF
  2471.       ENDCASE
  2472.    ENDIF
  2473. ENDFOR
  2474. RETURN
  2475.  
  2476. *!*****************************************************************************
  2477. *!
  2478. *!      Procedure: ADDPROCNAME
  2479. *!
  2480. *!      Called by: UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2481. *!
  2482. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2483. *!
  2484. *!*****************************************************************************
  2485. PROCEDURE addprocname
  2486. *)
  2487. *) ADDPROCNAME - Update g_procs with pname data
  2488. *)
  2489. PARAMETER m.pname, m.platname, m.linenum, m.lastmline
  2490. PRIVATE m.rnum, m.platformcol, m.i, m.j
  2491. IF EMPTY(m.pname)
  2492.    RETURN
  2493. ENDIF
  2494.  
  2495. * Look up this name in the procedures array
  2496. m.rnum = 0
  2497. FOR m.i = 1 TO m.g_procnames
  2498.    IF g_procs[m.i,1] == m.pname
  2499.       m.rnum = m.i
  2500.       EXIT
  2501.    ENDIF
  2502. ENDFOR
  2503.  
  2504. IF m.rnum = 0
  2505.    * New name
  2506.    g_procnames = m.g_procnames + 1
  2507.    DIMENSION g_procs[m.g_procnames,C_MAXPLATFORMS+3]
  2508.    g_procs[m.g_procnames,1] = UPPER(ALLTRIM(m.pname))
  2509.    FOR m.j = 1 TO c_maxplatforms
  2510.       g_procs[m.g_procnames,m.j + 1] = -1
  2511.    ENDFOR
  2512.    g_procs[m.g_procnames,C_MAXPLATFORMS+2] = .F.   && not emitted yet
  2513.    g_procs[m.g_procnames,C_MAXPLATFORMS+3] = ""    && parameter statement
  2514.    m.rnum = m.g_procnames
  2515. ENDIF
  2516.  
  2517. m.platformcol = getplatnum(m.platname) + 1
  2518. IF m.platformcol > 1
  2519.    g_procs[m.rnum, m.platformcol] = m.lastmline
  2520. ENDIF
  2521. RETURN
  2522.  
  2523. *!*****************************************************************************
  2524. *!
  2525. *!       Function: GETPLATNUM
  2526. *!
  2527. *!      Called by: PREPWNAMES         (procedure in GENSCRN.PRG)
  2528. *!               : ADDPROCNAME        (procedure in GENSCRN.PRG)
  2529. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2530. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2531. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  2532. *!
  2533. *!*****************************************************************************
  2534. FUNCTION getplatnum
  2535. *)
  2536. *) GETPLATNUM - Return the g_platlist array index given a platform name
  2537. *)
  2538. PARAMETER m.platname
  2539. PRIVATE m.i
  2540. FOR m.i = 1 TO c_maxplatforms
  2541.    IF g_platlist[m.i] == UPPER(ALLTRIM(m.platname))
  2542.       RETURN m.i
  2543.    ENDIF
  2544. ENDFOR
  2545. RETURN 0
  2546.  
  2547. *!*****************************************************************************
  2548. *!
  2549. *!      Procedure: GENCASESTMT
  2550. *!
  2551. *!*****************************************************************************
  2552. PROCEDURE gencasestmt
  2553. *)
  2554. *) GENCASESTMT - Generate the CASE ... statement
  2555. *)
  2556. PARAMETER m.thisplat
  2557. DO CASE
  2558. CASE m.thisplat = "WINDOWS" and !hasrecords("MAC") and hasrecords("WINDOWS")
  2559.    \CASE _WINDOWS OR _MAC   && no MAC records in screen
  2560.     m.g_dualoutput = .T.
  2561. CASE m.thisplat = "MAC" and !hasrecords("WINDOWS") and hasrecords("MAC")
  2562.    \CASE _MAC OR _WINDOWS   && no Windows records in screen
  2563.     m.g_dualoutput = .T.
  2564. CASE m.thisplat = "UNIX" and !hasrecords("DOS") and hasrecords("UNIX")
  2565.    \CASE _UNIX OR _DOS      && no DOS records in screen
  2566.     m.g_dualoutput = .T.
  2567. CASE m.thisplat = "DOS" and !hasrecords("UNIX") and hasrecords("DOS")
  2568.    \CASE _DOS OR _UNIX      && no UNIX records in screen
  2569.     m.g_dualoutput = .T.
  2570. OTHERWISE
  2571.    \CASE _<<m.thisplat>>
  2572.     m.g_dualoutput = .F.
  2573. ENDCASE
  2574. RETURN
  2575.  
  2576. *!*****************************************************************************
  2577. *!
  2578. *!      Procedure: GENPARAMETER
  2579. *!
  2580. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  2581. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  2582. *!
  2583. *!*****************************************************************************
  2584. PROCEDURE genparameter
  2585. *)
  2586. *) GENPARAMETER - Generate the PARAMETER statement
  2587. *)
  2588. IF !EMPTY(m.g_parameter)
  2589.    \PARAMETERS <<m.g_parameter>>
  2590. ENDIF
  2591. RETURN
  2592.  
  2593. *!*****************************************************************************
  2594. *!
  2595. *!      Procedure: GENSECT1
  2596. *!
  2597. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  2598. *!
  2599. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  2600. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  2601. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2602. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  2603. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  2604. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2605. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  2606. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2607. *!
  2608. *!*****************************************************************************
  2609. PROCEDURE gensect1
  2610. *)
  2611. *) GENSECT1 - Generate #SECTION 1 code for all screens.
  2612. *)
  2613. PRIVATE m.i, m.dbalias, m.string, m.loop, m.j, m.end, m.msg, m.thisline
  2614. m.msg =  'Generating Setup Code'
  2615. IF multiplat()
  2616.    m.msg = m.msg + " for "+versioncap(m.g_genvers, m.g_dualoutput)
  2617. ENDIF
  2618. DO putmsg WITH m.msg
  2619. m.string = " Setup Code - SECTION 1"
  2620.  
  2621. FOR m.i = 1 TO m.g_nscreens
  2622.    m.g_screen = m.i
  2623.  
  2624.    m.dbalias = g_screens[m.i,5]
  2625.    SELECT (m.dbalias)
  2626.    DO seekheader WITH m.i
  2627.    IF EMPTY (setupcode)
  2628.       LOOP
  2629.    ENDIF
  2630.  
  2631.    m.g_sect1start= c_fromone
  2632.    m.g_sect2start= c_untilend
  2633.    m.loop  = .F.
  2634.  
  2635.    IF ATCLINE("#SECT", setupcode) <> 0
  2636.       m.g_sect1start = findsection(1, setupcode)+1
  2637.       m.g_sect2start = findsection(2, setupcode)
  2638.    ENDIF
  2639.  
  2640.    DO notedirectives WITH (m.i)
  2641.  
  2642.    * See if there are nondirective statements in SECTION 1
  2643.    IF m.g_sect2start-m.g_sect1start <= 3
  2644.       IF m.g_sect2start = 0
  2645.          m.end = MEMLINES(setupcode)
  2646.       ELSE
  2647.          m.end = m.g_sect2start-1
  2648.       ENDIF
  2649.       m.loop = .T.
  2650.       m.j = m.g_sect1start
  2651.       DO WHILE m.j <= m.end
  2652.          m.thisline = MLINE(setupcode,m.j)
  2653.          DO killcr WITH m.thisline
  2654.          IF AT('#',m.thisline) <> 1 OR AT('#INSE',m.thisline) = 1
  2655.             m.loop = .F.
  2656.             EXIT
  2657.          ENDIF
  2658.          m.j = m.j + 1
  2659.       ENDDO
  2660.    ENDIF
  2661.    IF m.loop
  2662.       LOOP
  2663.    ENDIF
  2664.    IF NOT (m.g_sect1start=1 OR (m.g_sect1start=m.g_sect2start) OR ;
  2665.          (m.g_sect2start<>0 AND m.g_sect1start>m.g_sect2start))
  2666.  
  2667.       DO commentblock WITH g_screens[m.i,1], m.string
  2668.       \#REGION <<INT(m.i)>>
  2669.       _MLINE = 0
  2670.       DO writecode WITH setupcode, getplatname(m.i), m.g_sect1start, m.g_sect2start, m.i, 'setup'
  2671.    ENDIF
  2672. ENDFOR
  2673. m.g_screen = 0
  2674. RETURN
  2675.  
  2676. *!*****************************************************************************
  2677. *!
  2678. *!      Procedure: GENSECT2
  2679. *!
  2680. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  2681. *!
  2682. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  2683. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  2684. *!               : NOTEDIRECTIVES     (procedure in GENSCRN.PRG)
  2685. *!               : COUNTDIRECTIVES()  (function  in GENSCRN.PRG)
  2686. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2687. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  2688. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2689. *!
  2690. *!*****************************************************************************
  2691. PROCEDURE gensect2
  2692. *)
  2693. *) GENSECT2 - Generate Setup code #SECTION 2.
  2694. *)
  2695. PRIVATE m.i, m.dbalias, m.string, m.endline, m.srtline, ;
  2696.    m.linecnt, m.lcnt, m.sect1, m.sect2
  2697. m.string = " Setup Code - SECTION 2"
  2698.  
  2699. FOR m.i = 1 TO m.g_nscreens
  2700.    m.g_screen = m.i
  2701.    m.dbalias = g_screens[m.i,5]
  2702.    SELECT (m.dbalias)
  2703.    DO seekheader WITH m.i
  2704.    IF EMPTY (setupcode)
  2705.       LOOP
  2706.    ENDIF
  2707.  
  2708.    m.g_sect1start= c_fromone
  2709.    m.g_sect2start= c_untilend
  2710.    m.loop  = .F.
  2711.  
  2712.    IF ATCLINE("#SECT", setupcode)<>0
  2713.       m.g_sect1start = findsection(1, setupcode)+1
  2714.       m.g_sect2start = findsection(2, setupcode)
  2715.    ENDIF
  2716.  
  2717.    m.sect1 = m.g_sect1start <> 0
  2718.    m.sect2 = m.g_sect2start <> 0
  2719.  
  2720.    DO notedirectives WITH (m.i)
  2721.    m.lcnt = countdirectives(m.sect1, m.sect2, m.i)
  2722.  
  2723.    IF m.g_sect2start = 0 AND m.g_sect1start > 1
  2724.       * No Section2 to emit
  2725.       LOOP
  2726.    ENDIF
  2727.  
  2728.    m.linecnt = MEMLINES(setupcode)
  2729.  
  2730.    IF m.linecnt > m.lcnt AND m.g_sect2start < m.linecnt
  2731.       DO commentblock WITH g_screens[m.i,1], m.string
  2732.       \#REGION <<INT(m.i)>>
  2733.       DO writecode WITH setupcode, getplatname(m.i), m.g_sect2start, c_untilend, m.i, 'setup'
  2734.    ENDIF
  2735. ENDFOR
  2736. m.g_screen = 0
  2737. RETURN
  2738.  
  2739. *!*****************************************************************************
  2740. *!
  2741. *!       Function: COUNTDIRECTIVES
  2742. *!
  2743. *!      Called by: GENSECT2           (procedure in GENSCRN.PRG)
  2744. *!
  2745. *!*****************************************************************************
  2746. FUNCTION countdirectives
  2747. *)
  2748. *) COUNTDIRECTIVES - Count directives in setup snippet.
  2749. *)
  2750. *) This function counts the directives in setup.  It is used to figure out if there
  2751. *) are any non-directive statements in the setup snippet.
  2752. PARAMETER m.sect1, m.sect2, m.scrnno
  2753. PRIVATE m.numlines, m.i, m.lcnt, m.thisline, m.upline
  2754. m.lcnt = 0
  2755. IF AT('#',setupcode) > 0
  2756.    * AT test is optimization to avoid processing the snippet when there are no directives
  2757.    m.numlines = MEMLINES(setupcode)
  2758.    _MLINE = 0
  2759.    FOR m.i = 1 TO m.numlines
  2760.       m.thisline = MLINE(setupcode, 1, _MLINE)
  2761.       DO killcr WITH m.thisline
  2762.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2763.       IF LEFT(m.upline,1) = '#' AND !(LEFT(m.upline,5) = "#INSE")
  2764.          m.lcnt = m.lcnt + 1
  2765.       ENDIF
  2766.    ENDFOR
  2767. ENDIF
  2768. RETURN m.lcnt
  2769.  
  2770. *!*****************************************************************************
  2771. *!
  2772. *!      Procedure: NOTEDIRECTIVES
  2773. *!
  2774. *!      Called by: GENSECT2           (procedure in GENSCRN.PRG)
  2775. *!
  2776. *!*****************************************************************************
  2777. PROCEDURE notedirectives
  2778. *)
  2779. *) NOTEDIRECTIVES - Check for global directives such as #READCLAUSES, #NOREAD
  2780. *)
  2781. *) This function notes certain directives in the setup snippet and populates various
  2782. *) global variables so that we don't have to keep going back to the snippet to find
  2783. *) things.
  2784. PARAMETERS m.scrnno
  2785. PRIVATE m.numlines, m.i, m.thisline, m.upline
  2786. m.g_noread    = .F.
  2787. m.g_noreadplain = .F.
  2788. IF AT('#',setupcode) > 0
  2789.    * AT test is optimization to avoid processing the snippet when there are no directives
  2790.    m.numlines = MEMLINES(setupcode)
  2791.    _MLINE = 0
  2792.    FOR m.i = 1 TO m.numlines
  2793.       m.thisline = MLINE(setupcode, 1, _MLINE)
  2794.       DO killcr WITH m.thisline
  2795.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2796.       IF LEFT(m.upline,1) = '#'
  2797.          DO CASE
  2798.          CASE LEFT(m.upline,5) = "#READ"   && #READCLAUSES - Additional READ clauses
  2799.             IF m.g_rddir = .F.
  2800.                m.g_rddir = .T.
  2801.                m.g_rddirno = m.scrnno
  2802.             ENDIF
  2803.          CASE LEFT(m.upline,5) = "#NORE"   && #NOREAD - omit the READ statement
  2804.             m.g_noread = .T.
  2805.             IF AT(m.g_dblampersand,m.upline) > 0
  2806.                m.upline = LEFT(m.upline,AT(m.g_dblampersand,m.upline)-1)
  2807.             ENDIF
  2808.             m.g_noreadplain = IIF(ATC(' PLAI',m.upline) > 0,.T.,.F.)
  2809.             IF m.g_noreadplain
  2810.                 m.g_openfiles    = .F.
  2811.                     m.g_closefiles   = .F.
  2812.                     m.g_defwin       = .F.
  2813.                     m.g_relwin       = .F.
  2814.             ENDIF
  2815.          ENDCASE
  2816.       ENDIF
  2817.    ENDFOR
  2818. ENDIF
  2819. RETURN
  2820.  
  2821. *!*****************************************************************************
  2822. *!
  2823. *!       Function: FINDSECTION
  2824. *!
  2825. *!      Called by: GENSECT1           (procedure in GENSCRN.PRG)
  2826. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  2827. *!
  2828. *!*****************************************************************************
  2829. FUNCTION findsection
  2830. *)
  2831. *) FINDSECTION - Find #SECT... directive.
  2832. *)
  2833. *) Description:
  2834. *) Locate and return the line on which the generator directive '#SECT'
  2835. *) is located on.  If no valid directive found, return 0.
  2836. *)
  2837. PARAMETER m.sectionid, m.memo
  2838. PRIVATE m.line, m.linecnt, m.textline
  2839. m.line    = ATCLINE("#SECT", m.memo)
  2840. m.linecnt = MEMLINE(m.memo)
  2841. DO WHILE m.line <= m.linecnt
  2842.    m.textline = LTRIM(MLINE(m.memo, m.line))
  2843.    DO killcr WITH m.textline
  2844.    IF ATC("#SECT", m.textline)=1
  2845.       IF m.sectionid = 1
  2846.          IF AT("1", m.textline)<>0
  2847.             m.sect1 = .T.
  2848.             RETURN m.line
  2849.          ELSE
  2850.             RETURN 0
  2851.          ENDIF
  2852.       ELSE
  2853.          IF AT("2", m.textline)<>0
  2854.             m.sect2 = .T.
  2855.             RETURN m.line
  2856.          ENDIF
  2857.       ENDIF
  2858.    ENDIF
  2859.    m.line = m.line + 1
  2860. ENDDO
  2861. RETURN 0
  2862.  
  2863. *!*****************************************************************************
  2864. *!
  2865. *!      Procedure: WRITECODE
  2866. *!
  2867. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  2868. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  2869. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  2870. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  2871. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  2872. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  2873. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  2874. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  2875. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  2876. *!               : INSERTFILE         (procedure in GENSCRN.PRG)
  2877. *!
  2878. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2879. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  2880. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  2881. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  2882. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  2883. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2884. *!
  2885. *!*****************************************************************************
  2886. PROCEDURE writecode
  2887. *)
  2888. *) WRITECODE - Write contents of a memo to a low level file.
  2889. *)
  2890. *) Description:
  2891. *) Receive a memo field as a parameter and write its contents out
  2892. *) to the currently opened low level file whose handle is stored
  2893. *) in the system memory variable _TEXT.  Contents of the system
  2894. *) memory variable _PRETEXT will affect the positioning of the
  2895. *) generated text.
  2896. *)
  2897. PARAMETER m.memo, m.platname, m.start, m.end, m.scrnno, m.insetup
  2898. PRIVATE m.linecnt, m.i, m.line, m.upline, m.expr, m.platnum, m.at, m.in_exact
  2899.  
  2900. m.in_exact = SET("EXACT")
  2901. SET EXACT OFF
  2902.  
  2903. _MLINE = 0
  2904.  
  2905. m.start = MAX(1,m.start)  && if zero, start at 1
  2906.  
  2907. IF m.end > m.start
  2908.    m.linecnt = m.end-1
  2909. ELSE
  2910.    m.linecnt = MEMLINES(m.memo)
  2911. ENDIF
  2912.  
  2913. m.platnum = getplatnum(m.platname)
  2914.  
  2915. FOR m.i = 1 TO m.start - 1
  2916.    m.line = MLINE(m.memo, 1, _MLINE)
  2917. ENDFOR
  2918.  
  2919. * Window substitution names
  2920. m.subwindname = g_wnames[m.scrnno,m.platnum]
  2921. m.emptysubwind = IIF(EMPTY(m.subwindname),.T.,.F.)
  2922.  
  2923. IF NOT EMPTY(m.insetup)
  2924.    FOR m.i = m.start TO m.linecnt
  2925.       m.line = MLINE(m.memo, 1, _MLINE)
  2926.       DO killcr WITH m.line
  2927.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2928.       IF !geninsertcode(@upline,m.scrnno, m.insetup, m.platname)
  2929.          m.isparam =  isparameter(@upline)
  2930.          DO CASE
  2931.          CASE m.isparam
  2932.             * Accumulate continuation line but don't output it.
  2933.             DO WHILE RIGHT(m.upline,1) = ';'
  2934.                m.line = MLINE(m.memo, 1, _MLINE)
  2935.                m.upline = m.upline + ALLTRIM(UPPER(m.line))
  2936.                m.i = m.i + 1
  2937.             ENDDO
  2938.             DO killcr WITH m.line
  2939.          CASE m.upline = "#"
  2940.                * don't output a generator directive, but #DEFINES are OK
  2941.                IF LEFT(m.upline,5) = "#DEFI" ;
  2942.                     OR LEFT(m.upline,3) = "#IF" ;
  2943.                     OR LEFT(m.upline,5) = "#ELSE" ;
  2944.                     OR LEFT(m.upline,6) = "#ENDIF" ;
  2945.                     OR LEFT(m.upline,8) = "#INCLUDE"
  2946.                 \<<m.line>>
  2947.                 ENDIF
  2948.            CASE m.emptysubwind    && the most common case
  2949.             \<<m.line>>
  2950.          OTHERWISE
  2951.             m.at = atwname(m.subwindname, m.line)
  2952.             IF m.at <> 0 AND !iscomment(@upline)
  2953.                m.expr = STUFF(m.line, m.at, ;
  2954.                   LEN(m.subwindname), ;
  2955.                   g_screens[m.scrnno,2])
  2956.                \<<m.expr>>
  2957.             ELSE
  2958.                \<<m.line>>
  2959.             ENDIF
  2960.          ENDCASE
  2961.       ENDIF
  2962.    ENDFOR
  2963. ELSE   && not in setup
  2964.    FOR m.i = m.start TO m.linecnt
  2965.       m.line = MLINE(m.memo, 1, _MLINE)
  2966.       DO killcr WITH m.line
  2967.       m.upline = UPPER(LTRIM(CHRTRAN(m.line,chr(9),' ')))
  2968.       DO writeline WITH m.line, m.platname, m.platnum, m.upline, m.scrnno
  2969.    ENDFOR
  2970. ENDIF
  2971. SET EXACT &in_exact
  2972. RETURN
  2973.  
  2974. *!*****************************************************************************
  2975. *!
  2976. *!      Procedure: WRITELINE
  2977. *!
  2978. *!      Called by: EMITPROC           (procedure in GENSCRN.PRG)
  2979. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  2980. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2981. *!
  2982. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2983. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  2984. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  2985. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  2986. *!
  2987. *!*****************************************************************************
  2988. PROCEDURE writeline
  2989. *)
  2990. *) WRITELINE - Emit a single line
  2991. *)
  2992. PARAMETER m.line, m.platname, m.platnum, m.upline, m.scrnno
  2993. PRIVATE m.at, m.expr
  2994.  
  2995. IF !geninsertcode(@upline, m.scrnno, .F., m.platname)   && by reference to save time
  2996.    IF !EMPTY(g_wnames[m.scrnno, m.platnum])
  2997.       m.at = atwname(g_wnames[m.scrnno, m.platnum], m.line)
  2998.       IF m.at <> 0 AND !iscomment(@upline)
  2999.          m.expr = STUFF(m.line, m.at, ;
  3000.             LEN(g_wnames[m.scrnno, m.platnum]), ;
  3001.             g_screens[m.scrnno,2])
  3002.          \<<m.expr>>
  3003.       ELSE
  3004.          IF !INLIST(LEFT(m.upline,2),"*!","*:") ;
  3005.                AND AT('#NAME', m.upline) <> 1
  3006.             \<<m.line>>
  3007.          ENDIF
  3008.       ENDIF
  3009.    ELSE
  3010.        * This code relies upon partial matching (e.g., "*! Comment" will equal "*")
  3011.       DO CASE
  3012.         CASE m.upline = "*"
  3013.            IF !(m.upline = "*!" OR m.upline = "*:")
  3014.             \<<m.line>>
  3015.             ENDIF
  3016.         CASE m.upline = "#"
  3017.            * don't output a generator directive, but #DEFINES are OK
  3018.            IF LEFT(m.upline,5) = "#DEFI" ;
  3019.                     OR LEFT(m.upline,3) = "#IF" ;
  3020.                     OR LEFT(m.upline,5) = "#ELSE" ;
  3021.                     OR LEFT(m.upline,6) = "#ENDIF" ;
  3022.                     OR LEFT(m.upline,8) = "#INCLUDE"
  3023.             \<<m.line>>
  3024.            ENDIF
  3025.         OTHERWISE
  3026.          \<<m.line>>
  3027.       ENDCASE
  3028.    ENDIF
  3029. ENDIF
  3030. RETURN
  3031.  
  3032. *!*****************************************************************************
  3033. *!
  3034. *!      Procedure: GENINSERTCODE
  3035. *!
  3036. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3037. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3038. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3039. *!
  3040. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  3041. *!               : INSERTFILE         (procedure in GENSCRN.PRG)
  3042. *!
  3043. *!*****************************************************************************
  3044. PROCEDURE geninsertcode
  3045. *)
  3046. *) GENINSERTCODE - Emit code from the #insert file, if any
  3047. *)
  3048. *) Strg has to be trimmed before entering GenInsertCode.  It may be passed by reference.
  3049. PARAMETER m.strg, m.scrnno, m.insetup, m.platname
  3050. PRIVATE m.word1, m.filname
  3051. IF AT("#INSE",m.strg) = 1
  3052.    m.word1 = wordnum(m.strg,1)
  3053.    m.filname = SUBSTR(m.strg,LEN(m.word1)+1)
  3054.    m.filname = ALLTRIM(CHRTRAN(m.filname,CHR(9)," "))
  3055.    DO insertfile WITH m.filname, m.scrnno, m.insetup, m.platname
  3056.    RETURN .T.
  3057. ELSE
  3058.    RETURN .F.
  3059. ENDIF
  3060. RETURN
  3061.  
  3062. *!*****************************************************************************
  3063. *!
  3064. *!       Function: ISPARAMETER
  3065. *!
  3066. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3067. *!
  3068. *!          Calls: MATCH()            (function  in GENSCRN.PRG)
  3069. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  3070. *!
  3071. *!*****************************************************************************
  3072. FUNCTION isparameter
  3073. *)
  3074. *) ISPARAMETER - Determine if strg is a PARAMETERS statement
  3075. *)
  3076. PARAMETER m.strg
  3077. PRIVATE m.ispar
  3078. m.ispar = .F.
  3079. IF !EMPTY(strg) AND match(CHRTRAN(wordnum(strg,1),';',''),"PARAMETERS")
  3080.    m.ispar = .T.
  3081. ENDIF
  3082. RETURN m.ispar
  3083.  
  3084. *!*****************************************************************************
  3085. *!
  3086. *!       Function: ATWNAME
  3087. *!
  3088. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3089. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3090. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3091. *!
  3092. *!*****************************************************************************
  3093. FUNCTION atwname
  3094. *)
  3095. *) ATWNAME - Determine if valid m.string is in this line.
  3096. *)
  3097. *) Description:
  3098. *) Make sure that if m.string is in fact the string we want to do
  3099. *) the substitution on.
  3100. *)
  3101. PARAMETER m.string, m.line
  3102. PRIVATE m.pos, m.before, m.after
  3103. m.pos = AT(m.string,m.line)
  3104. IF m.pos = 0
  3105.    RETURN 0
  3106. ENDIF
  3107. IF m.pos = 1
  3108.    m.pos = AT(m.string+" ",m.line)
  3109. ELSE
  3110.    IF m.pos = LEN(m.line) - LEN(m.string) + 1
  3111.       m.pos = AT(" "+m.string,m.line)
  3112.       m.pos = IIF(m.pos<>0, m.pos+1,m.pos)
  3113.    ELSE
  3114.       m.before = SUBSTR(m.line,m.pos-1,1)
  3115.  
  3116.       IF m.before = c_under OR ;
  3117.             (m.before >= '0' AND m.before <= '9') OR ;
  3118.             (m.before >= 'a' AND m.before <= 'z') OR ;
  3119.             (m.before >= 'A' AND m.before <= 'Z')
  3120.  
  3121.          RETURN 0
  3122.       ENDIF
  3123.       m.after = SUBSTR(m.line,m.pos+LEN(m.string),1)
  3124.  
  3125.       IF m.after = c_under OR ;
  3126.             (m.after >= '0' AND m.after <= '9') OR ;
  3127.             (m.after >= 'a' AND m.after <= 'z') OR ;
  3128.             (m.after >= 'A' AND m.after <= 'Z')
  3129.  
  3130.          RETURN 0
  3131.       ENDIF
  3132.    ENDIF
  3133. ENDIF
  3134. RETURN m.pos
  3135.  
  3136. *!*****************************************************************************
  3137. *!
  3138. *!       Function: ISCOMMENT
  3139. *!
  3140. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3141. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3142. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3143. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  3144. *!
  3145. *!*****************************************************************************
  3146. FUNCTION iscomment
  3147. *)
  3148. *) ISCOMMENT - Determine if textline is a comment line.
  3149. *)
  3150. PARAMETER m.textline
  3151. PRIVATE m.asterisk, m.isnote, m.ampersand, m.statement
  3152. IF EMPTY(m.textline)
  3153.    RETURN .F.
  3154. ENDIF
  3155. m.statement = UPPER(LTRIM(m.textline))
  3156.  
  3157. m.asterisk  = AT("*", m.statement)
  3158. m.ampersand = AT(m.g_dblampersand, m.statement)
  3159. m.isnote    = AT("NOTE", m.statement)
  3160.  
  3161. DO CASE
  3162. CASE (m.asterisk = 1 OR m.ampersand = 1)
  3163.    RETURN .T.
  3164. CASE (m.isnote = 1 ;
  3165.       AND (LEN(m.statement) <= 4 OR SUBSTR(m.statement,5,1) = ' '))
  3166.    * Don't be fooled by something like "notebook = 7"
  3167.    RETURN .T.
  3168. ENDCASE
  3169. RETURN .F.
  3170.  
  3171. *!*****************************************************************************
  3172. *!
  3173. *!      Procedure: GENCLAUSECODE
  3174. *!
  3175. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  3176. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  3177. *!
  3178. *!          Calls: VALICLAUSE         (procedure in GENSCRN.PRG)
  3179. *!               : WHENCLAUSE         (procedure in GENSCRN.PRG)
  3180. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  3181. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  3182. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  3183. *!
  3184. *!*****************************************************************************
  3185. PROCEDURE genclausecode
  3186. *)
  3187. *) GENCLAUSECODE - Generate code for all read-level clauses.
  3188. *)
  3189. *) Description:
  3190. *) Generate functions containing the code from each screen's
  3191. *) READ level valid, show, when, activate, and deactivate clauses.
  3192. *)
  3193. PARAMETER m.screenno
  3194. DO valiclause WITH m.screenno
  3195. DO whenclause WITH m.screenno
  3196. DO acticlause WITH m.screenno
  3197. DO deatclause WITH m.screenno
  3198. DO showclause WITH m.screenno
  3199. RETURN
  3200.  
  3201. *!*****************************************************************************
  3202. *!
  3203. *!      Procedure: VALICLAUSE
  3204. *!
  3205. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3206. *!
  3207. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3208. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  3209. *!
  3210. *!*****************************************************************************
  3211. PROCEDURE valiclause
  3212. *)
  3213. *) VALICLAUSE - Generate Read level Valid clause function.
  3214. *)
  3215. *) Description:
  3216. *) Generate the function containing the code segment(s) provided
  3217. *) by the user for the read level VALID clause.
  3218. *) If multiple reads have been chosen, then this procedure generates
  3219. *) a function for a single screen.
  3220. *) If single read has been chosen and there are multiple screens,
  3221. *) we will concatenate valid clause code segments form all screens
  3222. *) to form a single function.
  3223. *)
  3224. PARAMETER m.screenno
  3225. PRIVATE m.i, m.dbalias, m.thispretext
  3226.  
  3227. IF m.g_validtype = "EXPR" OR EMPTY(m.g_validtype)
  3228.    RETURN
  3229. ENDIF
  3230. DO genfuncheader WITH m.g_validname, "Read Level Valid", .T.
  3231. \FUNCTION <<m.g_validname>>     && Read Level Valid
  3232.  
  3233. m.thispretext = _PRETEXT
  3234. _PRETEXT = ""
  3235. IF m.g_multreads
  3236.    DO genvalidbody WITH m.screenno
  3237. ELSE
  3238.    FOR m.i = 1 TO m.g_nscreens
  3239.       m.g_screen = m.i
  3240.       m.dbalias = g_screens[m.i,5]
  3241.       SELECT (m.dbalias)
  3242.       DO genvalidbody WITH m.i
  3243.    ENDFOR
  3244.    m.g_screen = 0
  3245. ENDIF
  3246. _PRETEXT = m.thispretext
  3247. RETURN
  3248.  
  3249. *!*****************************************************************************
  3250. *!
  3251. *!      Procedure: GENVALIDBODY
  3252. *!
  3253. *!      Called by: VALICLAUSE         (procedure in GENSCRN.PRG)
  3254. *!
  3255. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  3256. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3257. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3258. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3259. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3260. *!
  3261. *!*****************************************************************************
  3262. PROCEDURE genvalidbody
  3263. *)
  3264. *) GENVALIDBODY - Put out contents of a valid memo field.
  3265. *)
  3266. PARAMETER m.region
  3267. PRIVATE m.name, m.pos
  3268.  
  3269. IF g_screens[m.region, 6]
  3270.    LOCATE FOR objtype = c_otscreen
  3271. ELSE
  3272.    LOCATE FOR platform = g_screens[m.region, 7] AND objtype = c_otscreen
  3273. ENDIF
  3274. IF NOT FOUND()
  3275.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3276.       LINENO(), c_error_3
  3277.    RETURN
  3278. ENDIF
  3279. IF NOT EMPTY(VALID) AND validtype<>0
  3280.    IF NOT m.g_multread
  3281.       m.name  = basename(DBF())
  3282.       DO gencomment WITH "Valid Code from screen: "+m.name
  3283.    ENDIF
  3284.    \#REGION <<INT(m.region)>>
  3285.    DO writecode WITH VALID, getplatname(m.region), c_fromone, c_untilend, m.region
  3286. ENDIF
  3287. RETURN
  3288.  
  3289. *!*****************************************************************************
  3290. *!
  3291. *!      Procedure: WHENCLAUSE
  3292. *!
  3293. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3294. *!
  3295. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3296. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  3297. *!
  3298. *!*****************************************************************************
  3299. PROCEDURE whenclause
  3300. *)
  3301. *) WHENCLAUSE - Generate Read level When clause function.
  3302. *)
  3303. *) Description:
  3304. *) Generate the function containing the code segment(s) provided
  3305. *) by the user for the read level WHEN clause.
  3306. *) If multiple reads have been chosen, then this procedure generates
  3307. *) a function for a single screen (i.e., the one it has been called for).
  3308. *) If single read has been chosen and there are multiple screens,
  3309. *) we will concatenate when clause code segments from all screens
  3310. *) to form a single function.
  3311. *)
  3312. PARAMETER m.screenno
  3313. PRIVATE m.i, m.dbalias, m.thispretext
  3314.  
  3315. IF m.g_whentype = "EXPR" OR EMPTY(m.g_whentype)
  3316.    RETURN
  3317. ENDIF
  3318. DO genfuncheader WITH m.g_whenname, "Read Level When", .T.
  3319. \FUNCTION <<m.g_whenname>>     && Read Level When
  3320.  
  3321. m.thispretext = _PRETEXT
  3322. _PRETEXT = ""
  3323. IF m.g_multreads
  3324.    DO genwhenbody WITH m.screenno
  3325. ELSE
  3326.    FOR m.i = 1 TO m.g_nscreens
  3327.       m.g_screen = m.i
  3328.       m.dbalias = g_screens[m.i,5]
  3329.       SELECT (m.dbalias)
  3330.       DO genwhenbody WITH m.i
  3331.    ENDFOR
  3332.    m.g_screen = 0
  3333. ENDIF
  3334. _PRETEXT = m.thispretext
  3335. RETURN
  3336.  
  3337. *!*****************************************************************************
  3338. *!
  3339. *!      Procedure: GENWHENBODY
  3340. *!
  3341. *!      Called by: WHENCLAUSE         (procedure in GENSCRN.PRG)
  3342. *!
  3343. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  3344. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3345. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3346. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3347. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3348. *!
  3349. *!*****************************************************************************
  3350. PROCEDURE genwhenbody
  3351. *)
  3352. *) GENWHENBODY - Put out contents of when memo field.
  3353. *)
  3354. PARAMETER m.region
  3355. PRIVATE m.name, m.pos
  3356.  
  3357. IF g_screens[m.region, 6]
  3358.    LOCATE FOR objtype = c_otscreen
  3359. ELSE
  3360.    LOCATE FOR platform = g_screens[m.region, 7] AND objtype = c_otscreen
  3361. ENDIF
  3362. IF NOT FOUND()
  3363.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3364.       LINENO(), c_error_3
  3365.    RETURN
  3366. ENDIF
  3367.  
  3368. IF NOT EMPTY(WHEN) AND whentype<>0
  3369.    IF NOT m.g_multread
  3370.       m.name = basename(DBF())
  3371.       DO gencomment WITH "When Code from screen: "+m.name
  3372.    ENDIF
  3373.    \#REGION <<INT(m.region)>>
  3374.    DO writecode WITH WHEN, getplatname(m.region), c_fromone, c_untilend, m.region
  3375. ENDIF
  3376. RETURN
  3377.  
  3378. *!*****************************************************************************
  3379. *!
  3380. *!      Procedure: ACTICLAUSE
  3381. *!
  3382. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3383. *!
  3384. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3385. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3386. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3387. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3388. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3389. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3390. *!
  3391. *!*****************************************************************************
  3392. PROCEDURE acticlause
  3393. *)
  3394. *) ACTICLAUSE - Generate Read level Activate clause function.
  3395. *)
  3396. *) Description:
  3397. *) Generate the function containing the code segment(s) provided
  3398. *) by the user for the read level ACTIVATE clause.
  3399. *) If multiple reads have been chosen, then this procedure generates
  3400. *) a function for a single screen (i.e., the one it has been called for).
  3401. *) If single read has been chosen and there are multiple screens,
  3402. *) we will concatenate activate clause code segments from all screens
  3403. *) to form a single function.  Each individual screen's code
  3404. *) segment will be enclosed in "IF WOUTPUT('windowname')" statement.
  3405. *) Desk top will be represented by a null character. The above
  3406. *) mentioned is performed by the procedure genactibody.
  3407. *)
  3408. PARAMETER m.screenno
  3409. PRIVATE m.i, m.name
  3410.  
  3411. IF m.g_actitype = "EXPR" OR EMPTY(m.g_actitype)
  3412.    RETURN
  3413. ENDIF
  3414. DO genfuncheader WITH m.g_actiname, "Read Level Activate", .T.
  3415. \FUNCTION <<m.g_actiname>>     && Read Level Activate
  3416.  
  3417. IF m.g_multreads
  3418.    IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3419.       \#REGION <<INT(m.screenno)>>
  3420.       DO writecode WITH ACTIVATE, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3421.    ENDIF
  3422. ELSE
  3423.    FOR m.i = 1 TO m.g_nscreens
  3424.       m.g_screen = m.i
  3425.       m.dbalias = g_screens[m.i,5]
  3426.       SELECT (m.dbalias)
  3427.       IF g_screens[m.i, 6]
  3428.          LOCATE FOR objtype = c_otscreen
  3429.       ELSE
  3430.          LOCATE FOR platform = g_screens[m.i, 7] AND objtype = c_otscreen
  3431.       ENDIF
  3432.       IF NOT FOUND()
  3433.          DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3434.             LINENO(), c_error_3
  3435.          RETURN
  3436.       ENDIF
  3437.       IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3438.          m.name = basename(g_screens[m.i,1])
  3439.          DO gencomment WITH "Activate Code from screen: "+;
  3440.             m.name
  3441.       ENDIF
  3442.       IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3443.          \#REGION <<INT(m.i)>>
  3444.          DO writecode WITH ACTIVATE, getplatname(m.i), c_fromone, c_untilend, m.i
  3445.       ENDIF
  3446.    ENDFOR
  3447.    m.g_screen = 0
  3448. ENDIF
  3449. RETURN
  3450.  
  3451. *!*****************************************************************************
  3452. *!
  3453. *!      Procedure: DEATCLAUSE
  3454. *!
  3455. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3456. *!
  3457. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3458. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3459. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3460. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3461. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3462. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3463. *!
  3464. *!*****************************************************************************
  3465. PROCEDURE deatclause
  3466. *)
  3467. *) DEATCLAUSE - Generate Read level deactivate clause function.
  3468. *)
  3469. *) Description:
  3470. *) Generate the function containing the code segment(s) provided
  3471. *) by the user for the read level DEACTIVATE clause.
  3472. *) If multiple reads have been chosen, then this procedure generates
  3473. *) a function for a single screen (i.e., the one it has been called for).
  3474. *) If single read has been chosen and there are multiple screens,
  3475. *) we will concatenate deactivate clause code segments from all screens
  3476. *) to form a single function.  Each individual screen's code
  3477. *) segment will be enclosed in "IF WOUTPUT('windowname')" statement.
  3478. *) Desk top will be represented by a null character. The above
  3479. *) mentioned is performed by the procedure gendeatbody.
  3480. *)
  3481. PARAMETER m.screenno
  3482. PRIVATE m.i, m.name
  3483.  
  3484. IF m.g_deattype = "EXPR" OR EMPTY(m.g_deattype)
  3485.    RETURN
  3486. ENDIF
  3487. DO genfuncheader WITH m.g_deatname, "Read Level Deactivate", .T.
  3488. \FUNCTION <<m.g_deatname>>     && Read Level Deactivate
  3489.  
  3490. IF m.g_multreads
  3491.    IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3492.       \#REGION <<INT(m.screenno)>>
  3493.       DO writecode WITH DEACTIVATE, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3494.    ENDIF
  3495. ELSE
  3496.    FOR m.i = 1 TO m.g_nscreens
  3497.       m.g_screen = m.i
  3498.       m.dbalias = g_screens[m.i,5]
  3499.       SELECT (m.dbalias)
  3500.       IF g_screens[m.i,6]
  3501.          LOCATE FOR objtype = c_otscreen
  3502.       ELSE
  3503.          LOCATE FOR platform = g_screens[m.i, 7] AND objtype = c_otscreen
  3504.       ENDIF
  3505.       IF NOT FOUND()
  3506.          DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3507.             LINENO(), c_error_3
  3508.          RETURN
  3509.       ENDIF
  3510.       IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3511.          m.name = basename(g_screens[m.i,1])
  3512.          DO gencomment WITH "Deactivate Code from screen: "+;
  3513.             m.name
  3514.       ENDIF
  3515.       IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3516.          \#REGION <<INT(m.i)>>
  3517.          DO writecode WITH DEACTIVATE, getplatname(m.i), c_fromone, c_untilend, m.i
  3518.       ENDIF
  3519.    ENDFOR
  3520.    m.g_screen = 0
  3521. ENDIF
  3522. RETURN
  3523.  
  3524. *!*****************************************************************************
  3525. *!
  3526. *!      Procedure: SHOWCLAUSE
  3527. *!
  3528. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3529. *!
  3530. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3531. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3532. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3533. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3534. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  3535. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3536. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3537. *!
  3538. *!*****************************************************************************
  3539. PROCEDURE showclause
  3540. *)
  3541. *) SHOWCLAUSE - Generate Read level Show clause procedure.
  3542. *)
  3543. *) Description:
  3544. *) Generate the function containing the code segment(s) provided
  3545. *) by the user for the read level SHOW clause.  The function generated
  3546. *) for the show clause will consist of refreshable @...SAY code and
  3547. *) code segment(s) if applicable. If multiple reads have been chosen,
  3548. *) then this procedure generates a function for a single screen
  3549. *) (i.e., the one it has been called for).  If single read has been
  3550. *) chosen and there are multiple screens, we will concatenate show
  3551. *) clause code segments from all screens to form a single function.
  3552. *) Each individual screen's refreshable SAYs will be enclosed in
  3553. *) "IF SYS(2016)=('windowname') OR SYS(2016) = '*'" statement.
  3554. *) (Desk top will be represented by a null character.)
  3555. *)
  3556. PARAMETER m.screenno
  3557. PRIVATE m.i, m.comment, m.name, m.thispretext, m.oldshow, m.showmod
  3558.  
  3559. IF m.g_showtype = "EXPR" OR EMPTY(m.g_showtype)
  3560.    RETURN
  3561. ENDIF
  3562. DO genfuncheader WITH m.g_showname, "Read Level Show", .T.
  3563.  
  3564. \FUNCTION <<m.g_showname>>     && Read Level Show
  3565. \PRIVATE currwind
  3566.  
  3567. \STORE WOUTPUT() TO currwind
  3568. m.thispretext = _PRETEXT
  3569. _PRETEXT = ""
  3570.  
  3571. IF m.g_multreads
  3572.    DO seekheader WITH m.screenno
  3573.    m.oldshow = Show
  3574.  
  3575.    m.showmod = ChkShow()
  3576.  
  3577.    m.comment = .T.
  3578.    \#REGION <<INT(m.screenno)>>
  3579.    IF NOT EMPTY(show) AND showtype<>0
  3580.       DO writecode WITH show, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3581.    ENDIF
  3582.    DO placesays WITH m.comment, m.g_showname, m.screenno
  3583.    IF m.showmod
  3584.       REPLACE show WITH m.oldshow
  3585.    ENDIF
  3586. ELSE
  3587.    FOR m.i = 1 TO m.g_nscreens
  3588.       m.g_screen = m.i
  3589.       m.dbalias = g_screens[m.i,5]
  3590.       SELECT (m.dbalias)
  3591.       m.comment = .F.
  3592.  
  3593.       DO seekheader WITH m.i
  3594.  
  3595.       m.name = basename(g_screens[m.i,1])
  3596.       IF NOT EMPTY(show) AND showtype<>0
  3597.          m.oldshow = Show   && record show snippet
  3598.          m.showmod = ChkShow()         && may modify show snippet directly
  3599.  
  3600.          DO gencomment WITH "Show Code from screen: "+m.name
  3601.          \#REGION <<INT(m.i)>>
  3602.          m.comment = .T.
  3603.          DO writecode WITH show, getplatname(m.i), c_fromone, c_untilend, m.i
  3604.          IF m.showmod
  3605.             REPLACE show WITH m.oldshow
  3606.          ENDIF
  3607.       ENDIF
  3608.       DO seekheader WITH m.i
  3609.       DO placesays WITH m.comment, m.name, m.i
  3610.    ENDFOR
  3611.    m.g_screen = 0
  3612. ENDIF
  3613. _PRETEXT = m.thispretext
  3614.  
  3615. IF !m.g_noreadplain
  3616.    \IF NOT EMPTY(currwind)
  3617.    \    ACTIVATE WINDOW (currwind) SAME
  3618.    \ENDIF
  3619. ENDIF
  3620. RETURN
  3621.  
  3622. *!*****************************************************************************
  3623. *!
  3624. *!      Function: CHKSHOW
  3625. *!
  3626. *!*****************************************************************************
  3627. FUNCTION chkshow
  3628. PRIVATE m.thelineno, m.theline, m.oldmline, m.upline, m.newshow, m.found_one, m.leadspace, ;
  3629.    m.oldtext, m.theword, m.getsonly, m.j
  3630. * Check for a poisonous SHOW GETS in the SHOW snippet.  If one if executed
  3631. * there, runaway recursion results.
  3632. IF c_checkshow == 0   && check to see if this safety feature is enabled.
  3633.    RETURN .F.
  3634. ENDIF
  3635. m.thelineno = ATCLINE("SHOW GETS",show)
  3636. m.oldmline = _MLINE
  3637. m.oldtext = _TEXT
  3638. m.found_one = .F.
  3639. IF m.thelineno > 0
  3640.    * Step through the SHOW snippet a line at a time, commenting out any SHOW GETS or
  3641.    * SHOW GETS OFF statements.
  3642.    m.newshow = ""
  3643.    _MLINE = 0
  3644.    DO WHILE _MLINE < LEN(show)
  3645.       m.theline = MLINE(show,1,_MLINE)
  3646.       DO killcr WITH m.theline
  3647.       m.upline  = UPPER(LTRIM(m.theline))
  3648.       IF wordnum(m.upline,1) == "SHOW" AND wordnum(m.upline,2) == "GETS" ;
  3649.              AND (EMPTY(wordnum(m.upline,3)) OR wordnum(m.upline,3) == "OFF")
  3650.          m.leadspace = LEN(m.theline) - LEN(m.upline)
  3651.          m.newshow = m.newshow + SPACE(m.leadspace) + ;
  3652.             "* Commented out by GENSCRN: " + LTRIM(m.theline) + CHR(13) + CHR(10)
  3653.          DO errorhandler WITH "SHOW GETS statement commented out of SHOW snippet.",;
  3654.               LINENO(),c_error_1
  3655.          m.found_one = .T.
  3656.       ELSE
  3657.          m.newshow = m.newshow + m.theline + CHR(13) + CHR(10)
  3658.       ENDIF
  3659.    ENDDO
  3660.    IF m.found_one
  3661.       REPLACE show WITH m.newshow
  3662.    ENDIF
  3663. ENDIF
  3664. _MLINE = m.oldmline
  3665. _TEXT  = m.oldtext
  3666. RETURN m.found_one
  3667.  
  3668. *!*****************************************************************************
  3669. *!
  3670. *!      Procedure: PLACESAYS
  3671. *!
  3672. *!      Called by: SHOWCLAUSE         (procedure in GENSCRN.PRG)
  3673. *!
  3674. *!          Calls: GENCOMMENT         (procedure in GENSCRN.PRG)
  3675. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  3676. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  3677. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  3678. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  3679. *!               : ANYPICTURE         (procedure in GENSCRN.PRG)
  3680. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  3681. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  3682. *!
  3683. *!*****************************************************************************
  3684. PROCEDURE placesays
  3685. *)
  3686. *) PLACESAYS - Generate @...SAY for refreshable says in the .PRG file.
  3687. *)
  3688. *) Description:
  3689. *) Place @...SAY code for all refreshable say statements into
  3690. *) the generated SHOW clause function.
  3691. *)
  3692. PARAMETER m.comment, m.scrnname, m.g_thisscreen
  3693. PRIVATE m.iswindow, m.sayfound, m.windowname, m.theexpr, m.occur, m.pos
  3694.  
  3695. IF EMPTY(STYLE)
  3696.    m.iswindow = .F.
  3697. ELSE
  3698.    m.iswindow = .T.
  3699.    m.windowname = g_screens[m.g_thisscreen,2]
  3700. ENDIF
  3701. m.sayfound = .T.
  3702. SCAN FOR ((objtype = c_otfield AND objcode = c_sgsay) OR ;
  3703.       (objtype = c_otpicture)) AND ;
  3704.       REFRESH = .T. AND (g_screens[m.g_thisscreen, 6] OR platform = g_screens[m.g_thisscreen, 7])
  3705.    IF m.sayfound
  3706.       IF NOT m.comment
  3707.          DO gencomment WITH "Show Code from screen: "+m.scrnname
  3708.          \#REGION <<INT(m.g_thisscreen)>>
  3709.       ENDIF
  3710.       IF !m.g_noreadplain    && not just emitting plain @ SAYs/GETs
  3711.          \IF SYS(2016) =
  3712.          IF m.iswindow
  3713.             \\ "<<UPPER(m.windowname)>>" OR SYS(2016) = "*"
  3714.             \    ACTIVATE WINDOW <<m.windowname>> SAME
  3715.          ELSE
  3716.             \\ "" OR SYS(2016) = "*"
  3717.             \    ACTIVATE SCREEN
  3718.          ENDIF
  3719.       ENDIF
  3720.       m.sayfound = .F.
  3721.    ENDIF
  3722.  
  3723.    IF objtype = c_otpicture
  3724.       DO genpicture
  3725.    ELSE
  3726.       m.theexpr = expr
  3727.       IF g_screens[m.g_thisscreen, 7] = 'WINDOWS' OR g_screens[m.g_thisscreen, 7] = 'MAC'
  3728.          SET DECIMALS TO 3
  3729.          m.occur = 1
  3730.          m.pos = AT(CHR(13), m.theexpr, m.occur)
  3731.  
  3732.          * Sometimes the screen builder surrounds text with single quotes and other
  3733.          * times with double quotes.
  3734.          q1 = LEFT(LTRIM(m.theexpr),1)
  3735.  
  3736.          DO WHILE m.pos > 0
  3737.             IF q1 = "'"
  3738.                m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  3739.                   "' + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "'" ;
  3740.                   + SUBSTR(m.theexpr, m.pos + 1)
  3741.             ELSE
  3742.                m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  3743.                   '" + CHR(13) + ;' + CHR(13)  + CHR(9) + CHR(9) + '"' ;
  3744.                   + SUBSTR(m.theexpr, m.pos + 1)
  3745.             ENDIF
  3746.             m.occur = m.occur + 1
  3747.             m.pos = AT(CHR(13), m.theexpr, m.occur)
  3748.          ENDDO
  3749.          IF mode = 1 AND objtype = c_otfield  AND objcode = c_sgsay    && transparent SAY text
  3750.             * Clear the space that the SAY is going into.  This makes refreshable SAYS
  3751.             * work with transparent fonts.
  3752.             \    @ <<Vpos>>,<<Hpos>> CLEAR TO <<Vpos+Height>>,<<Hpos+Width>>
  3753.          ENDIF
  3754.       ENDIF
  3755.       \    @ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  3756.       \        SIZE <<Height>>,<<Width>>, <<Spacing>>
  3757.       SET DECIMALS TO 0
  3758.       DO pushindent
  3759.       DO anyfont
  3760.       DO anystyle
  3761.       DO anypicture
  3762.       DO anyscheme
  3763.       DO popindent
  3764.    ENDIF
  3765. ENDSCAN
  3766. IF NOT m.sayfound
  3767.    \ENDIF
  3768. ENDIF
  3769. RETURN
  3770.  
  3771. *!*****************************************************************************
  3772. *!
  3773. *!      Procedure: GENCLOSEDBFS
  3774. *!
  3775. *!      Called by: GENCLNENVIRON      (procedure in GENSCRN.PRG)
  3776. *!
  3777. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  3778. *!               : UNIQUEDBF()        (function  in GENSCRN.PRG)
  3779. *!
  3780. *!*****************************************************************************
  3781. PROCEDURE genclosedbfs
  3782. *)
  3783. *) GENCLOSEDBFS - Generate code to close all previously opened databases.
  3784. *)
  3785. PRIVATE m.i, m.dbalias, m.dbfcnt, m.firstfound
  3786. m.firstfound = .T.
  3787. m.dbfcnt = 0
  3788. g_dbfs = ""
  3789. FOR m.i = 1 TO m.g_nscreens
  3790.    m.g_screen = m.i
  3791.    m.dbalias = g_screens[m.i,5]
  3792.    SELECT (m.dbalias)
  3793.    SCAN FOR objtype = c_otworkarea AND (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  3794.       IF m.firstfound
  3795.          DO commentblock WITH ""," Closing Databases"
  3796.          m.firstfound = .F.
  3797.       ENDIF
  3798.       IF uniquedbf(TAG)
  3799.          m.dbfcnt = m.dbfcnt + 1
  3800.          DIMENSION g_dbfs[m.dbfcnt]
  3801.          g_dbfs[m.dbfcnt] = TAG
  3802.       ELSE
  3803.          LOOP
  3804.       ENDIF
  3805.       \IF USED("<<LOWER(stripext(strippath(Tag)))>>")
  3806.       \    SELECT <<LOWER(stripext(strippath(Tag)))>>
  3807.       \    USE
  3808.       \ENDIF
  3809.       \
  3810.    ENDSCAN
  3811. ENDFOR
  3812. m.g_screen = 0
  3813. IF m.g_closefiles
  3814.    \SELECT (m.currarea)
  3815.    \
  3816. ENDIF
  3817. DIMENSION g_dbfs[1]
  3818. RETURN
  3819.  
  3820. *!*****************************************************************************
  3821. *!
  3822. *!      Procedure: GENOPENDBFS
  3823. *!
  3824. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  3825. *!
  3826. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  3827. *!               : UNIQUEDBF()        (function  in GENSCRN.PRG)
  3828. *!               : GENUSESTMTS        (procedure in GENSCRN.PRG)
  3829. *!               : STRIPPATH()        (function  in GENSCRN.PRG)
  3830. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3831. *!               : GENRELATIONS       (procedure in GENSCRN.PRG)
  3832. *!
  3833. *!*****************************************************************************
  3834. PROCEDURE genopendbfs
  3835. *)
  3836. *) GENOPENDBFS - Generate USE... statement(s).
  3837. *)
  3838. *) Description:
  3839. *) Generate code to open databases, set indexes, and relations as
  3840. *) specified by the user.
  3841. *)
  3842. PRIVATE m.dbalias, m.i, m.dbfcnt, m.string, m.msg, m.firstfound
  3843. m.firstfound = .T.
  3844. FOR m.i = 1 TO m.g_nscreens
  3845.    m.g_screen = m.i
  3846.    m.dbalias = g_screens[m.i,5]
  3847.    SELECT (m.dbalias)
  3848.    m.dbfcnt = 0
  3849.    SCAN FOR objtype = c_otworkarea AND (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  3850.       IF m.firstfound
  3851.          DO commentblock WITH m.dbalias, ;
  3852.             " Databases, Indexes, Relations"
  3853.          m.firstfound = .F.
  3854.       ENDIF
  3855.       IF uniquedbf(TAG)
  3856.          m.dbfcnt = m.dbfcnt + 1
  3857.          DIMENSION g_dbfs[m.dbfcnt]
  3858.          g_dbfs[m.dbfcnt] = TAG
  3859.       ELSE
  3860.          LOOP
  3861.       ENDIF
  3862.       DO genusestmts WITH m.i
  3863.    ENDSCAN
  3864.  
  3865.    IF m.dbfcnt > 1
  3866.       IF NOT EMPTY(m.g_current)
  3867.          \SELECT <<m.g_current>>
  3868.       ELSE
  3869.          m.msg = "Please RE-SAVE screen environment... SCREEN: "+;
  3870.             strippath(g_screens[m.i,1])
  3871.          DO errorhandler WITH m.msg, LINENO(), c_error_1
  3872.       ENDIF
  3873.       \
  3874.    ENDIF
  3875. ENDFOR
  3876. m.g_screen = 0
  3877. DO genrelations
  3878. RETURN
  3879.  
  3880. *!*****************************************************************************
  3881. *!
  3882. *!       Function: UNIQUEDBF
  3883. *!
  3884. *!      Called by: GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  3885. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  3886. *!
  3887. *!*****************************************************************************
  3888. FUNCTION uniquedbf
  3889. *)
  3890. *) UNIQUEDBF - Check if database name already seen.
  3891. *)
  3892. PARAMETER m.dbfname
  3893. RETURN IIF(ASCAN(g_dbfs, m.dbfname)=0,.T.,.F.)
  3894.  
  3895. *!*****************************************************************************
  3896. *!
  3897. *!      Procedure: GENUSESTMTS
  3898. *!
  3899. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  3900. *!
  3901. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  3902. *!               : GENORDER           (procedure in GENSCRN.PRG)
  3903. *!               : GENINDEXES()       (function  in GENSCRN.PRG)
  3904. *!
  3905. *!*****************************************************************************
  3906. PROCEDURE genusestmts
  3907. *)
  3908. *) GENUSESTMTS - Generate USE... statements
  3909. *)
  3910. *) Description:
  3911. *) Generate USE... statements for each database encoded in the
  3912. *) screen database.  Generate ORDER statement if appropriate.
  3913. *)
  3914. PARAMETER m.i
  3915. PRIVATE m.workarea, saverecno, MARGIN, m.name, m.order, m.tag
  3916. m.workarea  = objcode
  3917. saverecno = RECNO()
  3918. m.order   = LOWER(ALLTRIM(ORDER))
  3919. m.tag     = LOWER(ALLTRIM(tag2))
  3920. m.name    = LOWER(TAG)
  3921. m.relpath = LOWER(findrelpath(name))
  3922.  
  3923. IF UNIQUE AND EMPTY(m.g_current)
  3924.    m.g_current = m.name
  3925. ENDIF
  3926.  
  3927. MARGIN = 4
  3928. IF EMPTY(name)
  3929.    \SELECT <<m.name>>
  3930.    RETURN
  3931. ENDIF
  3932. \IF USED("<<m.name>>")
  3933. \    SELECT <<m.name>>
  3934. IF genindexes ("select", m.i)=0
  3935.    indexfound = 0
  3936.    \    SET ORDER TO
  3937.    DO genorder WITH indexfound,m.order,m.tag,m.name
  3938. ELSE
  3939.    indexfound = 1
  3940.    \\ ADDITIVE ;
  3941.    \        ORDER
  3942.    DO genorder WITH indexfound,m.order,m.tag,m.name
  3943. ENDIF
  3944.  
  3945. \ELSE
  3946. \    SELECT 0
  3947. \    USE (LOCFILE("<<m.relpath>>","DBF",
  3948. \\"Where is <<basename(m.relpath)>>?"));
  3949. \        AGAIN ALIAS <<m.name>>
  3950. MARGIN = 42+LEN(m.relpath)+2*LEN(m.name)
  3951. = genindexes("use", m.i)
  3952.  
  3953. GOTO saverecno
  3954. \\ ;
  3955. \        ORDER
  3956. DO genorder WITH indexfound,m.order,m.tag,m.name
  3957. \ENDIF
  3958. \
  3959. RETURN
  3960.  
  3961. *!*****************************************************************************
  3962. *!
  3963. *!       Function: FINDRELPATH
  3964. *!
  3965. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3966. *!               : GENINDEXES()       (function  in GENSCRN.PRG)
  3967. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  3968. *!               : ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  3969. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  3970. *!               : ANYICON            (procedure in GENSCRN.PRG)
  3971. *!
  3972. *!*****************************************************************************
  3973. FUNCTION findrelpath
  3974. *)
  3975. *) FINDRELPATH - Find relative path for DATABASES.
  3976. *)
  3977. PARAMETER m.name
  3978. PRIVATE m.fullpath, m.relpath
  3979. m.fullpath = UPPER(FULLPATH(m.name, g_screens[1,1]))
  3980. m.relpath  = SYS(2014, m.fullpath, UPPER(m.g_homedir))
  3981. RETURN m.relpath
  3982.  
  3983. *!*****************************************************************************
  3984. *!
  3985. *!      Procedure: GENORDER
  3986. *!
  3987. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3988. *!
  3989. *!*****************************************************************************
  3990. PROCEDURE genorder
  3991. *)
  3992. *) GENORDER - Generate ORDER clause.
  3993. *)
  3994. PARAMETER m.indexfound, m.order, m.tag, m.dbfname
  3995. IF EMPTY(m.order) AND EMPTY(m.tag)
  3996.    \\ 0
  3997.    RETURN
  3998. ENDIF
  3999. IF m.indexfound=0
  4000.    \\ TAG "<<m.tag>>"
  4001. ELSE
  4002.    IF EMPTY(m.tag)
  4003.       \\ <<basename(m.order)>>
  4004.    ELSE
  4005.       \\ TAG "<<m.tag>>"
  4006.       IF NOT EMPTY (m.order)
  4007.          \\ OF <<m.order>>
  4008.       ENDIF
  4009.    ENDIF
  4010. ENDIF
  4011. RETURN
  4012.  
  4013. *!*****************************************************************************
  4014. *!
  4015. *!       Function: GENINDEXES
  4016. *!
  4017. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  4018. *!
  4019. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  4020. *!
  4021. *!*****************************************************************************
  4022. FUNCTION genindexes
  4023. *)
  4024. *) GENINDEXES - Generate index names for a USE statement.
  4025. *)
  4026. PARAMETER m.placement, m.i
  4027. PRIVATE m.idxcount, m.relpath
  4028. m.idxcount = 0
  4029.  
  4030. SCAN FOR objtype = c_otindex AND objcode = WORKAREA AND;
  4031.       (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4032.    m.relpath = LOWER(findrelpath(name))
  4033.    IF m.idxcount > 0
  4034.       IF MARGIN > 55
  4035.          MARGIN = 8 + LEN(m.relpath)
  4036.          \\, ;
  4037.          \        <<m.relpath>>
  4038.       ELSE
  4039.          \\, <<m.relpath>>
  4040.          MARGIN = MARGIN + 2 + LEN(m.relpath)
  4041.       ENDIF
  4042.    ELSE
  4043.       IF m.placement = "use"
  4044.          \\ ;
  4045.          \        INDEX <<m.relpath>>
  4046.          MARGIN = 8 + LEN(m.relpath)
  4047.       ELSE
  4048.          \    SET INDEX TO <<m.relpath>>
  4049.          MARGIN = 17
  4050.          MARGIN = MARGIN + LEN(m.relpath)
  4051.       ENDIF
  4052.    ENDIF
  4053.    m.idxcount = m.idxcount + 1
  4054. ENDSCAN
  4055. RETURN m.idxcount
  4056.  
  4057. *!*****************************************************************************
  4058. *!
  4059. *!      Procedure: GENRELATIONS
  4060. *!
  4061. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  4062. *!
  4063. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  4064. *!               : GENRELSTMTS        (procedure in GENSCRN.PRG)
  4065. *!
  4066. *!*****************************************************************************
  4067. PROCEDURE genrelations
  4068. *)
  4069. *) GENRELATIONS - Generate code to set all existing relations as they
  4070. *)                 are encoded in the screen file(s).
  4071. *)
  4072. *) Description:
  4073. *) Generate code for all relations as encoded in the screen database.
  4074. *)
  4075. PRIVATE m.dbalias, m.i
  4076. FOR m.i = 1 TO m.g_nscreens
  4077.    m.g_screen = m.i
  4078.    m.dbalias  = g_screens[m.i,5]
  4079.    SELECT (m.dbalias)
  4080.  
  4081.    DO seekheader WITH m.i
  4082.    DO genrelstmts WITH m.i
  4083. ENDFOR
  4084. m.g_screen = 0
  4085. RETURN
  4086.  
  4087. *!*****************************************************************************
  4088. *!
  4089. *!      Procedure: GENRELSTMTS
  4090. *!
  4091. *!      Called by: GENRELATIONS       (procedure in GENSCRN.PRG)
  4092. *!
  4093. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  4094. *!
  4095. *!*****************************************************************************
  4096. PROCEDURE genrelstmts
  4097. *)
  4098. *) GENRELSTMTS - Generate relation statements.
  4099. *)
  4100. PARAMETER m.i
  4101. PRIVATE m.saverec, m.last, m.firstrel, m.firstsel, m.dbalias, m.setskip
  4102. m.dbalias  = ""
  4103. m.firstrel = .T.
  4104. m.firstsel = .T.
  4105. m.last     = 0
  4106. m.setskip  = ""
  4107.  
  4108. SCAN FOR objtype = c_otrel AND ;
  4109.       (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4110.    IF m.last<> objcode
  4111.       IF NOT (m.firstrel OR EMPTY(m.setskip))
  4112.          \SET SKIP TO <<m.setskip>>
  4113.          \
  4114.       ENDIF
  4115.       m.saverec = RECNO()
  4116.       m.last= objcode
  4117.  
  4118.       SCAN FOR objtype = c_otworkarea AND objcode = m.last AND ;
  4119.             (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4120.          m.dbalias = LOWER(basename(TAG))
  4121.          IF NOT (m.firstrel AND m.g_current = m.dbalias)
  4122.             \SELECT <<m.dbalias>>
  4123.          ENDIF
  4124.          m.setskip = ALLTRIM(LOWER(expr))
  4125.       ENDSCAN
  4126.  
  4127.       GOTO RECORD m.saverec
  4128.       m.firstrel = .F.
  4129.    ENDIF
  4130.  
  4131.    IF !(m.firstsel AND LOWER(tag2) == LOWER(m.g_current))
  4132.       \SELECT <<LOWER(Tag2)>>
  4133.       \
  4134.    ENDIF
  4135.    \SET RELATION OFF INTO <<LOWER(Tag)>>
  4136.    \SET RELATION TO <<LOWER(Expr)>> INTO <<LOWER(Tag)>> ADDITIVE
  4137.    \
  4138.  
  4139.    m.firstsel = .F.
  4140. ENDSCAN
  4141.  
  4142. IF m.last<> 0
  4143.    IF NOT EMPTY(m.setskip)
  4144.       \SET SKIP TO <<m.setskip>>
  4145.       \
  4146.    ENDIF
  4147.    IF NOT EMPTY(m.g_current)
  4148.       \SELECT <<m.g_current>>
  4149.    ENDIF
  4150. ENDIF
  4151. RETURN
  4152.  
  4153. **
  4154. ** Code Associated With Building of the Format file statements.
  4155. **
  4156.  
  4157. *!*****************************************************************************
  4158. *!
  4159. *!      Procedure: BUILDFMT
  4160. *!
  4161. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4162. *!
  4163. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  4164. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  4165. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  4166. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  4167. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4168. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4169. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  4170. *!               : ANYWINDOWS         (procedure in GENSCRN.PRG)
  4171. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  4172. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  4173. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  4174. *!               : GENLINES           (procedure in GENSCRN.PRG)
  4175. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  4176. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  4177. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  4178. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  4179. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  4180. *!               : GENLIST            (procedure in GENSCRN.PRG)
  4181. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  4182. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  4183. *!               : GENACTISTMTS       (procedure in GENSCRN.PRG)
  4184. *!               : PLACEREAD          (procedure in GENSCRN.PRG)
  4185. *!
  4186. *!*****************************************************************************
  4187. PROCEDURE buildfmt
  4188. *)
  4189. *) BUILDFMT - Build Format file statements.
  4190. *)
  4191. *) Description:
  4192. *) Generate all boxes, text, fields, push buttons, radio buttons,
  4193. *) popups, check boxes and scrollable lists encoded in a screen set.
  4194. *)
  4195. PARAMETER pnum   && platform number
  4196. PRIVATE m.pos, m.dbalias, m.adjuster, m.recadjust, m.increment, m.i, m.sn
  4197. m.msg = 'Generating Screen Code'
  4198. IF multiplat()
  4199.    m.msg = m.msg + " for "+versioncap(m.g_genvers, m.g_dualoutput)
  4200. ENDIF
  4201. DO putmsg WITH m.msg
  4202. m.g_nwindows = 0
  4203. m.adjuster   = INT((c_therm4-c_therm3)/m.g_nscreens)  && total therm. range to cover
  4204. m.recadjust  = c_therm3                 && starting position for thermometer
  4205. FOR m.sn = 1 TO m.g_nscreens
  4206.    m.g_screen = m.sn
  4207.    m.dbalias = g_screens[m.sn,5]
  4208.    SELECT (m.dbalias)
  4209.    DO seekheader WITH m.sn
  4210.  
  4211.    DO commentblock WITH g_screens[m.sn,1], " Screen Layout"
  4212.    \#REGION <<INT(m.sn)>>
  4213.    IF ATC('#ITSE',setupcode)<>0
  4214.       DO gendirective WITH ;
  4215.          MLINE(setupcode,ATCLINE('#ITSE',setupcode)),;
  4216.          '#ITSE'
  4217.    ENDIF
  4218.  
  4219.    * Figure out thermometer increment
  4220.    IF g_screens[m.sn, 6] OR m.g_numplatforms = 1
  4221.       m.recs = RECCOUNT()
  4222.    ELSE
  4223.       GOTO TOP
  4224.       COUNT FOR platform = g_screens[m.sn, 7] TO m.recs
  4225.    ENDIF
  4226.    m.increment = m.adjuster/m.recs
  4227.  
  4228.    SCAN FOR (g_screens[m.sn, 6] OR platform = g_screens[m.sn, 7])
  4229.       m.recadjust = m.recadjust + m.increment
  4230.  
  4231.       DO updtherm WITH thermadj(m.pnum,INT(m.recadjust),c_therm5)
  4232.  
  4233.       DO genusercode WITH c_premode
  4234.  
  4235.       DO CASE
  4236.       CASE objtype = c_otscreen
  4237.          DO anywindows WITH (m.sn)
  4238.       CASE objtype = c_ottext
  4239.          DO gentext
  4240.       CASE objtype = c_otfield
  4241.          DO genfields
  4242.       CASE objtype = c_otbox
  4243.          DO genboxes
  4244.       CASE objtype = c_otline
  4245.          DO genlines
  4246.       CASE objtype = c_ottxtbut
  4247.          DO genpush
  4248.       CASE objtype = c_otradbut
  4249.          DO genradbut
  4250.       CASE objtype = c_otinvbut
  4251.          DO geninvbut
  4252.       CASE objtype = c_otpopup
  4253.          DO genpopup
  4254.       CASE objtype = c_otchkbox
  4255.          DO genchkbox
  4256.       CASE objtype = c_otlist
  4257.          DO genlist
  4258.       CASE objtype = c_otpicture
  4259.          DO genpicture
  4260.       CASE objtype = c_otspinner
  4261.          DO genspinner
  4262.       ENDCASE
  4263.  
  4264.       DO genusercode WITH c_postmode
  4265.  
  4266.    ENDSCAN
  4267.    DO genactistmts WITH (m.sn)
  4268.    IF !m.g_noread
  4269.       DO placeread WITH (m.sn)
  4270.    ENDIF
  4271. ENDFOR
  4272. m.g_screen = 0
  4273. RETURN
  4274.  
  4275.  
  4276. *!*****************************************************************************
  4277. *!
  4278. *!      Procedure: GENUSERCODE
  4279. *!
  4280. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4281. *!
  4282. *!*****************************************************************************
  4283. PROCEDURE genusercode
  4284. PARAMETER usermode
  4285. PRIVATE m.thelinenum, m.theline, m.thecommand, m.tagline
  4286.  
  4287. IF m.usermode = c_premode
  4288.     m.tagline = c_userprecode
  4289. ELSE
  4290.      m.tagline = c_userpostcode
  4291. ENDIF
  4292.  
  4293. m.thelinenum = ATCLINE(m.tagline, comment)
  4294. IF m.thelinenum > 0
  4295.     m.theline = MLINE(comment, m.thelinenum)
  4296.     m.thecommand = ALLTRIM(SUBSTR(m.theline, LEN(m.tagline)+1))
  4297.     \<<m.thecommand>>
  4298. ENDIF
  4299.  
  4300. *!*****************************************************************************
  4301. *!
  4302. *!      Procedure: ANYWINDOWS
  4303. *!
  4304. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4305. *!
  4306. *!          Calls: GENACTWINDOW       (procedure in GENSCRN.PRG)
  4307. *!
  4308. *!*****************************************************************************
  4309. PROCEDURE anywindows
  4310. *)
  4311. *) ANYWINDOWS - Issue ACTIVATE WINDOW ... SAME.
  4312. *)
  4313. *) Description:
  4314. *) If windows present issue ACTIVATE WINDOW...SAME to make sure
  4315. *) that the windows stack on screen in the correct order.
  4316. *)
  4317. PARAMETER m.scrnno
  4318. PRIVATE m.pos
  4319. IF m.g_noreadplain
  4320.    RETURN
  4321. ENDIF
  4322.  
  4323. IF NOT EMPTY(STYLE)
  4324.    DO genactwindow WITH m.scrnno
  4325.  
  4326.    m.g_lastwindow = g_screens[m.scrnno,2]
  4327.    m.pos = ASCAN(g_wndows, m.g_lastwindow)
  4328.    * m.pos contains the element number (not the row) that matches.
  4329.    * The element number + 1 is a number representing window sequence.
  4330.    IF EMPTY(g_wndows[m.pos+1])
  4331.       m.g_nwindows = m.g_nwindows + 1
  4332.       g_wndows[m.pos+1] = m.g_nwindows
  4333.    ENDIF
  4334.  
  4335.    m.g_defasch1 = SCHEME
  4336.    m.g_defasch2 = scheme2
  4337. ELSE
  4338.    m.g_defasch1 = 0
  4339.    m.g_defasch2 = 0
  4340.  
  4341.    IF m.g_lastwindow<>""
  4342.       \HIDE WINDOW ALL
  4343.       \ACTIVATE SCREEN
  4344.       m.g_lastwindow = ""
  4345.    ENDIF
  4346. ENDIF
  4347. RETURN
  4348.  
  4349. *!*****************************************************************************
  4350. *!
  4351. *!      Procedure: GENACTISTMTS
  4352. *!
  4353. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4354. *!
  4355. *!*****************************************************************************
  4356. PROCEDURE genactistmts
  4357. *)
  4358. *) GENACTISTMTS - Generate Activate window statements.
  4359. *)
  4360. *) Description:
  4361. *) Generate ACTIVATE WINDOW... statements in order to activate all
  4362. *) windows which have been previously activated with SAME clause.
  4363. *)
  4364. PARAMETER m.scrnno
  4365. PRIVATE m.j, m.pos
  4366. \
  4367. IF m.scrnno=m.g_nscreens AND NOT m.g_multreads AND NOT m.g_noreadplain
  4368.    IF m.g_nwindows = 1
  4369.       \IF NOT WVISIBLE("<<g_wndows[1,1]>>")
  4370.       \    ACTIVATE WINDOW <<g_wndows[1,1]>>
  4371.       \ENDIF
  4372.       RETURN
  4373.    ENDIF
  4374.    FOR m.j = m.g_nwindows TO 1 STEP -1
  4375.       m.pos = ASCAN(g_wndows, m.j)
  4376.       * pos contains the element *numbered* j.  This will be somewhere in g_wndows[*,2].
  4377.       * Look to the preceding element to get the window name.
  4378.       IF m.pos<>0
  4379.          \IF NOT WVISIBLE("<<g_wndows[m.pos-1]>>")
  4380.          \    ACTIVATE WINDOW <<g_wndows[m.pos-1]>>
  4381.          \ENDIF
  4382.       ENDIF
  4383.    ENDFOR
  4384.    \
  4385. ENDIF
  4386. RETURN
  4387.  
  4388. *!*****************************************************************************
  4389. *!
  4390. *!      Procedure: PLACEREAD
  4391. *!
  4392. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4393. *!
  4394. *!          Calls: ANYMODAL           (procedure in GENSCRN.PRG)
  4395. *!               : ANYLOCK            (procedure in GENSCRN.PRG)
  4396. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4397. *!               : GENWITHCLAUSE      (procedure in GENSCRN.PRG)
  4398. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  4399. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4400. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4401. *!               : GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4402. *!               : GENCLAUSECODE      (procedure in GENSCRN.PRG)
  4403. *!
  4404. *!*****************************************************************************
  4405. PROCEDURE placeread
  4406. *)
  4407. *) PLACEREAD - Generate a 'READ' statement.
  4408. *)
  4409. *) Description:
  4410. *) Called once per screen in the screen set.
  4411. *) Generate a READ statement.  Depending on whether this is a single
  4412. *) or multiread the read statement may be generated between @...SAY/GETs
  4413. *) from each screen or at the end of a set of all @...SAY/GETs.
  4414. *)
  4415. PARAMETER m.scrnno
  4416. PRIVATE thispretext
  4417.  
  4418. \
  4419. IF m.g_multreads
  4420.    DO newreadclauses
  4421.    \READ
  4422.    IF m.g_readcycle AND m.scrnno = m.g_nscreens
  4423.       \\ CYCLE
  4424.    ENDIF
  4425.    DO anymodal
  4426.    DO anylock
  4427.    DO doplaceclause WITH m.scrnno
  4428.    DO genwithclause
  4429.    DO gengivenread WITH m.scrnno
  4430. ELSE
  4431.    IF NOT EMPTY(m.g_rddir) AND m.scrnno = m.g_nscreens
  4432.       DO commentblock WITH "","READ contains clauses from SCREEN "+;
  4433.          LOWER(g_screens[m.g_rddirno,5])
  4434.    ENDIF
  4435.    DO findreadclauses WITH m.scrnno
  4436.    IF m.scrnno = m.g_nscreens
  4437.       \READ
  4438.       IF m.g_readcycle
  4439.          \\ CYCLE
  4440.       ENDIF
  4441.       DO anymodal
  4442.       DO anylock
  4443.       DO genreadclauses
  4444.       DO genwithclause
  4445.       DO gengivenread WITH m.scrnno
  4446.       _TEXT = m.g_tmphandle
  4447.       m.thispretext = _PRETEXT
  4448.       _PRETEXT = ""
  4449.       DO genclausecode WITH m.scrnno
  4450.       _TEXT = m.g_orghandle
  4451.       _PRETEXT = m.thispretext
  4452.    ENDIF
  4453. ENDIF
  4454. \
  4455. RETURN
  4456.  
  4457. *!*****************************************************************************
  4458. *!
  4459. *!      Procedure: ANYMODAL
  4460. *!
  4461. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4462. *!
  4463. *!*****************************************************************************
  4464. *)
  4465. *) ANYMODAL - Generate MODAL clause on READ.
  4466. *)
  4467. PROCEDURE anymodal
  4468. IF m.g_readmodal
  4469.    \\ MODAL
  4470. ENDIF
  4471. RETURN
  4472.  
  4473. *!*****************************************************************************
  4474. *!
  4475. *!      Procedure: ANYLOCK
  4476. *!
  4477. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4478. *!
  4479. *!*****************************************************************************
  4480. PROCEDURE anylock
  4481. *)
  4482. *) ANYLOCK - Generate LOCK/NOLOCK clause on READ.
  4483. *)
  4484. IF m.g_readlock
  4485.    \\ NOLOCK
  4486. ENDIF
  4487. RETURN
  4488.  
  4489. *!*****************************************************************************
  4490. *!
  4491. *!      Procedure: GENWITHCLAUSE
  4492. *!
  4493. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4494. *!
  4495. *!*****************************************************************************
  4496. PROCEDURE genwithclause
  4497. *)
  4498. *) GENWITHCLAUSE - Generate WITH clause on a READ.
  4499. *)
  4500. IF NOT EMPTY(m.g_withlist)
  4501.    \\ ;
  4502.    \    WITH <<m.g_withlist>>
  4503. ENDIF
  4504. RETURN
  4505.  
  4506. *!*****************************************************************************
  4507. *!
  4508. *!      Procedure: DOPLACECLAUSE
  4509. *!
  4510. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4511. *!
  4512. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  4513. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4514. *!               : GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4515. *!               : GENCLAUSECODE      (procedure in GENSCRN.PRG)
  4516. *!
  4517. *!*****************************************************************************
  4518. PROCEDURE doplaceclause
  4519. *)
  4520. *) DOPLACECLAUSE - Place READ level clauses for multiple reads.
  4521. *)
  4522. *) Description:
  4523. *) According to the read level clauses encoded in the screen file
  4524. *) set variables holding information about each clause.
  4525. *)
  4526. PARAMETER m.scrnno
  4527. PRIVATE thispretext
  4528. IF g_screens[m.scrnno, 6]
  4529.    LOCATE FOR objtype = c_otscreen
  4530. ELSE
  4531.    LOCATE FOR platform = g_screens[m.scrnno, 7] AND objtype = c_otscreen
  4532. ENDIF
  4533. IF NOT FOUND()
  4534.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  4535.       LINENO(), c_error_3
  4536.    RETURN
  4537. ENDIF
  4538.  
  4539. DO findreadclauses WITH m.scrnno
  4540. DO genreadclauses
  4541. _TEXT = m.g_tmphandle
  4542. m.thispretext = _PRETEXT
  4543. _PRETEXT = ""
  4544.  
  4545. DO genclausecode WITH m.scrnno
  4546. _TEXT = m.g_orghandle
  4547. _PRETEXT = m.thispretext
  4548. RETURN
  4549.  
  4550. *!*****************************************************************************
  4551. *!
  4552. *!      Procedure: FINDREADCLAUSES
  4553. *!
  4554. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4555. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4556. *!
  4557. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  4558. *!               : SETCLAUSEFLAGS     (procedure in GENSCRN.PRG)
  4559. *!               : ORCLAUSEFLAGS      (procedure in GENSCRN.PRG)
  4560. *!
  4561. *!*****************************************************************************
  4562. PROCEDURE findreadclauses
  4563. *)
  4564. *) FINDREADCLAUSES - Find clauses for the final READ statement.
  4565. *)
  4566. *) Description:
  4567. *) Keep track of clauses that were already seen to determine what
  4568. *) clauses are placed on final read.  If this procedure is called for
  4569. *) a multiple read setting, flag's settings apply only to the current
  4570. *) screen.
  4571. *)
  4572. PARAMETER m.scrnno
  4573. PRIVATE m.dbalias, m.cur_rec
  4574. IF g_screens[m.scrnno,6]
  4575.    LOCATE FOR objtype = c_otscreen
  4576. ELSE
  4577.    LOCATE FOR platform = g_screens[m.scrnno, 7] AND objtype = c_otscreen
  4578. ENDIF
  4579. IF NOT FOUND()
  4580.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  4581.       LINENO(), c_error_3
  4582.    RETURN
  4583. ENDIF
  4584.  
  4585. IF EMPTY(m.g_validtype) AND !EMPTY(VALID)
  4586.    DO setclauseflags WITH validtype, VALID, m.g_validname,;
  4587.       m.g_validtype
  4588. ENDIF
  4589. IF EMPTY(m.g_whentype) AND !EMPTY(WHEN)
  4590.    DO setclauseflags  WITH whentype, WHEN, m.g_whenname,;
  4591.       m.g_whentype
  4592. ENDIF
  4593. IF EMPTY(m.g_actitype) AND !EMPTY(ACTIVATE)
  4594.    DO setclauseflags WITH activtype, ACTIVATE, m.g_actiname,;
  4595.       m.g_actitype
  4596. ENDIF
  4597. IF EMPTY(m.g_deattype) AND !EMPTY(DEACTIVATE)
  4598.    DO setclauseflags WITH deacttype, DEACTIVATE, m.g_deatname,;
  4599.       m.g_deattype
  4600. ENDIF
  4601.  
  4602. * SHOW is a special case since it can be generated with both procedures (for refreshable
  4603. * SAYs or just regular procedures) and expressions.  OR the flags together.
  4604. IF !EMPTY(SHOW)
  4605.    IF showtype != c_genexpr
  4606.       DO orclauseflags WITH showtype, SHOW, m.g_showname, m.g_showtype
  4607.    ELSE
  4608.       m.cur_rec = RECNO()
  4609.       * It's an expression, but look for refreshable SAYs too.
  4610.       LOCATE FOR ((objtype = c_otfield AND objcode = c_sgsay) OR (objtype = c_otpicture)) AND ;
  4611.          REFRESH = .T. AND (g_screens[m.scrnno, 6] OR platform = g_screens[m.scrnno, 7])
  4612.       IF FOUND()
  4613.          GOTO m.cur_rec
  4614.          DO orclauseflags WITH c_genboth, SHOW,   m.g_showname, m.g_showtype
  4615.       ELSE
  4616.          GOTO m.cur_rec
  4617.          DO orclauseflags WITH c_genexpr, SHOW,   m.g_showname, m.g_showtype
  4618.       ENDIF
  4619.       m.g_showexpr = m.g_showname
  4620.    ENDIF
  4621. ELSE
  4622.    * Look for refreshable SAYS
  4623.    LOCATE FOR ((objtype = c_otfield AND objcode = c_sgsay) OR (objtype = c_otpicture)) AND ;
  4624.       REFRESH = .T. AND (g_screens[m.scrnno, 6] OR platform = g_screens[m.scrnno, 7])
  4625.    IF FOUND()
  4626.       DO orclauseflags WITH c_gencode, SHOW,   m.g_showname, m.g_showtype
  4627.    ENDIF
  4628. ENDIF
  4629. RETURN
  4630.  
  4631. *!*****************************************************************************
  4632. *!
  4633. *!      Procedure: SETCLAUSEFLAGS
  4634. *!
  4635. *!      Called by: FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4636. *!
  4637. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  4638. *!
  4639. *!*****************************************************************************
  4640. PROCEDURE setclauseflags
  4641. *)
  4642. *) SETCLAUSEFLAGS - Load global flags with information about clauses.
  4643. *)
  4644. *) Description:
  4645. *) If a clause is a snippet then a generic name is provided for the
  4646. *) clause call statement in the READ and that same name is used to
  4647. *) construct the corresponding function.
  4648. *)
  4649. *) The BOTH setting is used for SHOW clauses that are defined as expressions,
  4650. *) in screens that also contain refreshable SAYS.  We have to generate a
  4651. *) procedure to contain the code to refresh the SAYS.
  4652. *)
  4653. PARAMETER m.flagtype, m.memo, m.name, m.type
  4654. DO CASE
  4655. CASE m.flagtype = c_genexpr
  4656.    m.name = m.memo
  4657.    m.type = "EXPR"
  4658. CASE m.flagtype = c_genboth
  4659.    m.name = m.memo
  4660.    m.type = "BOTH"
  4661. OTHERWISE
  4662.    m.name = getcname(m.memo)
  4663.    m.type = "CODE"
  4664. ENDCASE
  4665. RETURN
  4666.  
  4667. *!*****************************************************************************
  4668. *!
  4669. *!      Procedure: ORCLAUSEFLAGS
  4670. *!
  4671. *!      Called by: FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4672. *!
  4673. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  4674. *!
  4675. *!*****************************************************************************
  4676. PROCEDURE orclauseflags
  4677. *)
  4678. *) ORCLAUSEFLAGS - Logical OR two flagtypes
  4679. *)
  4680. PARAMETER m.flagtype, m.memo, m.name, m.type
  4681. DO CASE
  4682. CASE m.flagtype = c_genexpr
  4683.    m.name = m.memo
  4684.    IF INLIST(m.type,"BOTH","CODE")
  4685.       m.type = "BOTH"
  4686.    ELSE
  4687.       m.type = "EXPR"
  4688.    ENDIF
  4689. CASE m.flagtype = c_genboth
  4690.    m.name = m.memo
  4691.    m.type = "BOTH"
  4692. OTHERWISE
  4693.    * Code of some sort.  The expr code is different for expanded snippets, closed snippets, etc.
  4694.    * It is 2 for expanded snippets and 3 for minimized snippets, for example.
  4695.    m.name = getcname(m.memo)
  4696.    IF INLIST(m.type,"BOTH","EXPR")
  4697.       m.type = "BOTH"
  4698.    ELSE
  4699.       m.type = "CODE"
  4700.    ENDIF
  4701. ENDCASE
  4702. RETURN
  4703.  
  4704. *!*****************************************************************************
  4705. *!
  4706. *!      Procedure: GENREADCLAUSES
  4707. *!
  4708. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4709. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4710. *!
  4711. *!          Calls: GENCLAUSE          (procedure in GENSCRN.PRG)
  4712. *!
  4713. *!*****************************************************************************
  4714. PROCEDURE genreadclauses
  4715. *)
  4716. *) GENREADCLAUSES - Generate Clauses on a READ.
  4717. *)
  4718. *) Description:
  4719. *) Check if clause is appropriate, if so call GENCLAUSE to
  4720. *) generate the clause keyword.
  4721. *)
  4722. IF NOT EMPTY(m.g_validtype)
  4723.    DO genclause WITH "VALID", m.g_validname, m.g_validtype
  4724. ENDIF
  4725. IF NOT EMPTY(m.g_whentype)
  4726.    DO genclause WITH "WHEN", m.g_whenname, m.g_whentype
  4727. ENDIF
  4728. IF NOT EMPTY(m.g_actitype)
  4729.    DO genclause WITH "ACTIVATE", m.g_actiname, m.g_actitype
  4730. ENDIF
  4731. IF NOT EMPTY(m.g_deattype)
  4732.    DO genclause WITH "DEACTIVATE", m.g_deatname, m.g_deattype
  4733. ENDIF
  4734. IF NOT EMPTY(m.g_showtype)
  4735.    DO genclause WITH "SHOW", m.g_showname, m.g_showtype, m.g_showexpr
  4736. ENDIF
  4737. RETURN
  4738.  
  4739. *!*****************************************************************************
  4740. *!
  4741. *!      Procedure: GENCLAUSE
  4742. *!
  4743. *!      Called by: GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4744. *!
  4745. *!*****************************************************************************
  4746. PROCEDURE genclause
  4747. *)
  4748. *) GENCLAUSE - Generate Read Level Clause keyword.
  4749. *)
  4750. *) Description:
  4751. *) Generate SHOW,ACTIVATE,WHEN, or VALID clause keyword for a
  4752. *) READ statement.
  4753. *)
  4754. PARAMETER m.keyword, m.name, m.type, m.expr
  4755. PRIVATE m.codename
  4756. \\ ;
  4757. \    <<m.keyword>>
  4758. DO CASE
  4759. CASE m.type = "CODE"
  4760.    \\ <<m.name>>
  4761.    \\()
  4762. CASE m.type = "EXPR"
  4763.    \\ <<stripCR(m.name)>>
  4764. CASE m.type = "BOTH"
  4765.    * This is tricky.  We need to generate the user's expression followed by
  4766.    * a procedure, presumably containing code to handle refreshable SAYS in
  4767.    * a READ ... SHOW clause.  Right now, the name variable contains the
  4768.    * expression.  Emit it, generate a random name for the SHOW snippet, then
  4769.    * record that random name in the m.name field so that we can remember it
  4770.    * later.  The expression needs to come second (due to the boolean short-cutting
  4771.    * optimization in the interpreter).
  4772.    IF EMPTY(m.expr)
  4773.       m.codename = LOWER(SYS(2015))
  4774.       \\ <<m.codename>>() AND (<<stripCR(m.name)>>)
  4775.       m.name     = m.codename
  4776.    ELSE
  4777.       * There was an explicit expression passed to us.  Use it.
  4778.       m.codename = LOWER(SYS(2015))
  4779.       \\ <<m.codename>>() AND (<<stripCR(m.expr)>>)
  4780.       m.name     = m.codename
  4781.    ENDIF
  4782. ENDCASE
  4783. RETURN
  4784.  
  4785. *!*****************************************************************************
  4786. *!
  4787. *!      Procedure: GENGIVENREAD
  4788. *!
  4789. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4790. *!
  4791. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  4792. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4793. *!
  4794. *!*****************************************************************************
  4795. PROCEDURE gengivenread
  4796. *)
  4797. *) GENGIVENREAD - Generate another clause on the READ.
  4798. *)
  4799. PARAMETER m.screen
  4800. PRIVATE m.i, m.dbalias
  4801. IF m.g_multreads
  4802.    DO seekheader WITH m.screen
  4803.  
  4804.    IF ATC('#READ',setupcode) <> 0
  4805.       DO gendirective WITH ;
  4806.          MLINE(setupcode,ATCLINE('#READ',setupcode)),'#READ'
  4807.    ENDIF
  4808. ELSE
  4809.    FOR m.i = 1 TO m.g_nscreens
  4810.       m.g_screen = m.i
  4811.       m.dbalias = g_screens[m.i,5]
  4812.       SELECT (m.dbalias)
  4813.       DO seekheader WITH m.i
  4814.  
  4815.       IF ATC('#READ',setupcode)<>0
  4816.          DO gendirective WITH ;
  4817.             MLINE(setupcode,ATCLINE('#READ',setupcode)),'#READ'
  4818.          RETURN
  4819.       ENDIF
  4820.    ENDFOR
  4821.    m.g_screen = 0
  4822. ENDIF
  4823. RETURN
  4824.  
  4825. *!*****************************************************************************
  4826. *!
  4827. *!      Procedure: GENDIRECTIVE
  4828. *!
  4829. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4830. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  4831. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  4832. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  4833. *!
  4834. *!          Calls: SKIPWHITESPACE()   (function  in GENSCRN.PRG)
  4835. *!
  4836. *!*****************************************************************************
  4837. PROCEDURE gendirective
  4838. *)
  4839. *) GENDIRECTIVE - Process #ITSEXPRESSION, #READCLAUSES generator directives.
  4840. *)
  4841. PARAMETER m.line, m.directive
  4842. PRIVATE m.newline
  4843. IF ATC(m.directive,m.line)=1
  4844.    IF UPPER(m.directive) = '#REDE'
  4845.       m.g_redefi = .T.
  4846.       RETURN
  4847.    ENDIF
  4848.    m.newline = skipwhitespace(m.line)
  4849.    IF NOT EMPTY(m.newline)
  4850.       DO CASE
  4851.       CASE UPPER(m.directive) = '#READ'
  4852.          \\ ;
  4853.          \    <<UPPER(m.newline)>>
  4854.       CASE UPPER(m.directive) = '#WCLA'
  4855.          \\ ;
  4856.          \    <<UPPER(m.newline)>>
  4857.       CASE UPPER(m.directive) = '#ITSE'
  4858.          m.g_itse = SUBSTR(m.newline,1,1)
  4859.       ENDCASE
  4860.    ENDIF
  4861. ENDIF
  4862. RETURN
  4863.  
  4864. *!*****************************************************************************
  4865. *!
  4866. *!       Function: SKIPWHITESPACE
  4867. *!
  4868. *!      Called by: PREPWNAMES         (procedure in GENSCRN.PRG)
  4869. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4870. *!
  4871. *!*****************************************************************************
  4872. FUNCTION skipwhitespace
  4873. *)
  4874. *) SKIPWHITESPACE - Trim all white space from parameter string.
  4875. *)
  4876. PARAMETER m.line
  4877. PRIVATE m.whitespace
  4878. m.whitespace = AT(' ',m.line)
  4879. IF m.whitespace = 0
  4880.    m.whitespace = AT(CHR(9),m.line)
  4881. ENDIF
  4882. m.line = ALLTRIM(SUBSTR(m.line,m.whitespace))
  4883. DO WHILE SUBSTR(m.line,1,1) = CHR(9)
  4884.    m.line = ALLTRIM(SUBSTR(m.line, 2))
  4885. ENDDO
  4886. RETURN m.line
  4887.  
  4888. **
  4889. ** Code Generating Various Screen Objects
  4890. **
  4891.  
  4892. *!*****************************************************************************
  4893. *!
  4894. *!      Procedure: DEFPOPUPS
  4895. *!
  4896. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4897. *!
  4898. *!          Calls: GENPOPDEFI         (procedure in GENSCRN.PRG)
  4899. *!
  4900. *!*****************************************************************************
  4901. PROCEDURE defpopups
  4902. *)
  4903. *) DEFPOPUPS - Define popups used in scrollable list definition.
  4904. *)
  4905. *) Description:
  4906. *) Define popup which is later used in the definition of a
  4907. *) scrollable list.
  4908. *)
  4909. PRIVATE m.i, m.dbalias, m.cnt, m.anylists
  4910. m.cnt = 0
  4911. FOR m.i = 1 TO m.g_nscreens
  4912.    m.g_screen = m.i
  4913.    m.anylists = .F.
  4914.    m.dbalias = g_screens[m.i,5]
  4915.    SELECT (m.dbalias)
  4916.    SCAN FOR objtype = c_otlist AND STYLE > 1 AND ;
  4917.          (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4918.       IF NOT m.anylists
  4919.          \
  4920.          \#REGION <<INT(m.i)>>
  4921.          m.anylists = .T.
  4922.          m.g_somepops = .T.
  4923.       ENDIF
  4924.       m.cnt = m.cnt + 1
  4925.       g_popups[m.cnt,1] = m.dbalias
  4926.       g_popups[m.cnt,2] = RECNO()
  4927.       g_popups[m.cnt,3] = LOWER(SYS(2015))
  4928.  
  4929.       IF MOD(m.cnt,25)=0
  4930.          DIMENSION g_popups[ALEN(g_popups,1)+25,3]
  4931.       ENDIF
  4932.  
  4933.       DO genpopdefi
  4934.    ENDSCAN
  4935. ENDFOR
  4936. m.g_screen = 0
  4937. RETURN
  4938.  
  4939. *!*****************************************************************************
  4940. *!
  4941. *!      Procedure: GENPOPDEFI
  4942. *!
  4943. *!      Called by: DEFPOPUPS          (procedure in GENSCRN.PRG)
  4944. *!
  4945. *!*****************************************************************************
  4946. PROCEDURE genpopdefi
  4947. *)
  4948. *) GENPOPDEFI
  4949. *)
  4950. IF m.g_noreadplain
  4951.    RETURN
  4952. ENDIF
  4953.  
  4954. \DEFINE POPUP <<g_popups[m.cnt,3]>> ;
  4955. DO CASE
  4956. CASE STYLE = 2
  4957.    \    PROMPT STRUCTURE
  4958. CASE STYLE = 3
  4959.    \    PROMPT FIELD <<ALLTRIM(Expr)>>
  4960. CASE STYLE = 4
  4961.    \    PROMPT FILES
  4962.    IF NOT EMPTY(expr)
  4963.       \\ LIKE <<ALLTRIM(Expr)>>
  4964.    ENDIF
  4965. ENDCASE
  4966. \\ ;
  4967. \    SCROLL
  4968. IF m.g_genvers = 'DOS' OR m.g_genvers = 'UNIX'
  4969.    \\ ;
  4970.    \    MARGIN ;
  4971.    \    MARK ""
  4972.    \
  4973. ENDIF
  4974. RETURN
  4975.  
  4976. *!*****************************************************************************
  4977. *!
  4978. *!      Procedure: RELPOPUPS
  4979. *!
  4980. *!      Called by: GENCLNENVIRON      (procedure in GENSCRN.PRG)
  4981. *!
  4982. *!*****************************************************************************
  4983. PROCEDURE relpopups
  4984. *)
  4985. *) RELPOPUPS - Generate code to release generated popups.
  4986. *)
  4987. *) Description:
  4988. *) Generate code to release all popups defined by the generator
  4989. *) in conjunction with generating scrollable lists.
  4990. *)
  4991. PRIVATE m.popcnt, m.i, m.margin
  4992. m.popcnt = ALEN(g_popups,1)
  4993. m.margin = 16
  4994.  
  4995. IF EMPTY(g_popups[1,1]) OR m.g_noreadplain
  4996.    RETURN
  4997. ENDIF
  4998.  
  4999. \RELEASE POPUPS <<g_popups[1,3]>>
  5000. m.i = 2
  5001. DO WHILE m.i <= m.popcnt
  5002.    IF EMPTY(g_popups[m.i,1])
  5003.       RETURN
  5004.    ENDIF
  5005.    IF m.margin > 60
  5006.       m.margin = 4
  5007.       \\,;
  5008.       \    <<g_popups[m.i,3]>>
  5009.    ELSE
  5010.       \\, <<g_popups[m.i,3]>>
  5011.    ENDIF
  5012.    m.margin = m.margin + 3 + LEN(g_popups[m.i,3])
  5013.    m.i = m.i + 1
  5014. ENDDO
  5015. \
  5016. RETURN
  5017.  
  5018. *!*****************************************************************************
  5019. *!
  5020. *!      Procedure: DEFWINDOWS
  5021. *!
  5022. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  5023. *!
  5024. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  5025. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  5026. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  5027. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  5028. *!
  5029. *!*****************************************************************************
  5030. PROCEDURE defwindows
  5031. *)
  5032. *) DEFWINDOWS - Generate code for windows.
  5033. *)
  5034. *) Description:
  5035. *) Generate code to define windows designed in the screen builder.
  5036. *) Process all SCX databases and if window definitions found
  5037. *) call GENWINDEFI to define the windows.
  5038. *)
  5039. PRIVATE m.dbalias, m.pos, m.savearea, m.row, m.col, m.firstfound, m.i
  5040. m.firstfound = .T.
  5041. m.savearea = SELECT()
  5042. FOR m.i = 1 TO m.g_nscreens
  5043.    m.g_screen = m.i
  5044.    m.dbalias = g_screens[m.i,5]
  5045.    SELECT (m.dbalias)
  5046.  
  5047.    SCAN FOR objtype = c_otscreen AND ;
  5048.          (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  5049.  
  5050.       IF m.firstfound AND !m.g_noreadplain
  5051.          DO commentblock WITH ""," Window definitions"
  5052.          m.firstfound = .F.
  5053.       ENDIF
  5054.  
  5055.       IF NOT EMPTY(STYLE)
  5056.          IF ATC('#ITSE',setupcode)<>0
  5057.             DO gendirective WITH ;
  5058.                MLINE(setupcode,ATCLINE('#ITSE',setupcode)),'#ITSE'
  5059.          ENDIF
  5060.          IF ATC('#REDE',setupcode)<>0
  5061.             DO gendirective WITH ;
  5062.                MLINE(setupcode,ATCLINE('#REDE',setupcode)),'#REDE'
  5063.          ENDIF
  5064.          DO genwindefi WITH m.i
  5065.       ELSE
  5066.          IF ATC('#ITSE',setupcode)<>0
  5067.             DO gendirective WITH ;
  5068.                MLINE(setupcode,ATCLINE('#ITSE',setupcode)),'#ITSE'
  5069.          ENDIF
  5070.          DO gendesktop WITH m.i
  5071.       ENDIF
  5072.    ENDSCAN
  5073. ENDFOR
  5074. m.g_screen = 0
  5075. SELECT (m.savearea)
  5076. RETURN
  5077.  
  5078. *!*****************************************************************************
  5079. *!
  5080. *!      Procedure: GENDESKTOP
  5081. *!
  5082. *!      Called by: DEFWINDOWS         (procedure in GENSCRN.PRG)
  5083. *!
  5084. *!          Calls: WINDOWFROMTO       (procedure in GENSCRN.PRG)
  5085. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  5086. *!               : ANYTITLEORFOOTER   (procedure in GENSCRN.PRG)
  5087. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5088. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5089. *!               : ANYWINDOWCHARS     (procedure in GENSCRN.PRG)
  5090. *!               : ANYBORDER          (procedure in GENSCRN.PRG)
  5091. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  5092. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5093. *!               : ANYICON            (procedure in GENSCRN.PRG)
  5094. *!
  5095. *!*****************************************************************************
  5096. PROCEDURE gendesktop
  5097. *)
  5098. *) GENDESKTOP - Generate statements to change the desktop font
  5099. *)
  5100. *) Description:
  5101. *) Generate code to change the desktop font if this screen is on
  5102. *) the desktop.  This is done only if the user chose the define window
  5103. *) option in the generate dialog.
  5104. *)
  5105. PARAMETER m.g_screen
  5106. PRIVATE m.center_flag, m.arrange_flag, m.row, m.col, m.j, m.entries
  5107.  
  5108. IF (g_screens[m.g_screen, 7] != 'WINDOWS' AND g_screens[m.g_screen, 7] != 'MAC')
  5109.    RETURN
  5110. ENDIF
  5111.  
  5112. m.center_flag = .F.
  5113. m.arrange_flag = .F.
  5114.  
  5115. IF NOT m.g_defwin
  5116.    RETURN
  5117. ENDIF
  5118.  
  5119. m.g_moddesktop = .T.
  5120.  
  5121. \MODIFY WINDOW SCREEN ;
  5122.  
  5123. IF g_screens[m.g_screen,6]
  5124.    DO windowfromto
  5125.    IF m.g_genvers = "WINDOWS" OR m.g_genvers = "MAC"
  5126.       \\ ;
  5127.       \    FONT "FoxFont", 9
  5128.    ENDIF
  5129. ELSE
  5130.    SELECT (m.g_projalias)
  5131.    GOTO RECORD g_screens[m.g_screen,3]
  5132.  
  5133.    DO getarrange WITH m.dbalias, m.arrange_flag, m.center_flag
  5134.  
  5135.    DO anytitleorfooter
  5136.    DO anyfont
  5137.    DO anystyle
  5138.    DO anywindowchars
  5139.    DO anyborder
  5140.  
  5141.    IF  !EMPTY(PICTURE)
  5142.       DO anywallpaper
  5143.    ELSE
  5144.       DO anyscheme
  5145.    ENDIF
  5146.    DO anyicon
  5147.  
  5148.    IF (CENTER OR m.center_flag) AND !m.arrange_flag
  5149.       \MOVE WINDOW SCREEN CENTER
  5150.    ENDIF
  5151. ENDIF
  5152. \CLEAR
  5153. RETURN
  5154.  
  5155. *!*****************************************************************************
  5156. *!
  5157. *!      Procedure: GENWINDEFI
  5158. *!
  5159. *!      Called by: DEFWINDOWS         (procedure in GENSCRN.PRG)
  5160. *!
  5161. *!          Calls: UNIQUEWIN()        (function  in GENSCRN.PRG)
  5162. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  5163. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  5164. *!               : ANYTITLEORFOOTER   (procedure in GENSCRN.PRG)
  5165. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5166. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5167. *!               : ANYWINDOWCHARS     (procedure in GENSCRN.PRG)
  5168. *!               : ANYBORDER          (procedure in GENSCRN.PRG)
  5169. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  5170. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5171. *!               : ANYICON            (procedure in GENSCRN.PRG)
  5172. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  5173. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  5174. *!
  5175. *!*****************************************************************************
  5176. PROCEDURE genwindefi
  5177. *)
  5178. *) GENWINDEFI - Generate window definition
  5179. *)
  5180. *) Description:
  5181. *) Check to see if window name is unique, if not provide a unique name
  5182. *) with the use of SYS(2015) and display a warning message if
  5183. *) appropriate.  The window definition is generated only if the
  5184. *) user selected that option in the generator dialog.
  5185. *)
  5186. PARAMETER m.g_screen
  5187. PRIVATE m.name, m.pos, m.dupname, m.arrange_flag, m.center_flag, m.in_parms, m.j
  5188. m.arrange_flag = .F.
  5189. m.center_flag = .F.
  5190. m.dupname = .F.
  5191. m.name = IIF(!EMPTY(g_screens[m.g_screen,2]), g_screens[m.g_screen,2], LOWER(SYS(2015)))
  5192. m.pos = uniquewin(LOWER(m.name), m.g_nwindows, @g_wndows)
  5193. IF m.pos = 0
  5194.    m.dupname = .T.
  5195.    m.name = LOWER(SYS(2015))
  5196.    g_screens[m.g_screen,2] = m.name
  5197.    m.pos = uniquewin(m.name, m.g_nwindows, @g_wndows)
  5198. ENDIF
  5199.  
  5200. * Insert one row (two elements)
  5201. = AINS(g_wndows, m.pos)
  5202. g_wndows[m.pos,1] = m.name
  5203. g_wndows[m.pos,2] = .F.  && it will get a sequence number in AnyWindows
  5204. m.g_nwindows = m.g_nwindows + 1
  5205.  
  5206. m.g_windows = .T.
  5207. IF NOT m.g_defwin
  5208.    RETURN
  5209. ENDIF
  5210.  
  5211. IF NOT m.g_redefi
  5212.    \IF NOT WEXIST("<<m.name>>")
  5213.    * We can safely omit this extra code if the name was a randomly generated one
  5214.    IF  UPPER(LEFT(m.name,2)) <> UPPER(LEFT(SYS(2015),2))
  5215.       \\ ;
  5216.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'PJX'))>>" ;
  5217.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'SCX'))>>" ;
  5218.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'MNX'))>>" ;
  5219.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'PRG'))>>" ;
  5220.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'FRX'))>>" ;
  5221.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'QPR'))>>"
  5222.    ENDIF
  5223.    DO pushindent
  5224. ENDIF
  5225. \DEFINE WINDOW <<m.name>> ;
  5226.  
  5227. SELECT (m.g_projalias)
  5228. GOTO RECORD g_screens[m.g_screen,3]
  5229.  
  5230. DO getarrange WITH m.dbalias, m.arrange_flag, m.center_flag
  5231.  
  5232. DO anytitleorfooter
  5233. DO anyfont
  5234. DO anystyle
  5235. DO anywindowchars
  5236. DO anyborder
  5237.  
  5238. IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC')
  5239.    IF TAB
  5240.       \\ ;
  5241.       \    HALFHEIGHT
  5242.    ENDIF
  5243.    IF  !EMPTY(PICTURE)
  5244.       DO anywallpaper
  5245.    ELSE
  5246.       DO anyscheme
  5247.    ENDIF
  5248.    DO anyicon
  5249. ELSE
  5250.    DO anyscheme
  5251. ENDIF
  5252.  
  5253. * If the user defined additional window clauses, put them here
  5254. IF ATC("#WCLA",setupcode) > 0
  5255.    DO gendirective WITH ;
  5256.       MLINE(setupcode,ATCLINE('#WCLA',setupcode)),'#WCLA'
  5257. ENDIF
  5258.  
  5259. * Emit the MOVE WINDOW ... CENTER after all the window clauses have been emitted
  5260. IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC')
  5261.    IF (CENTER OR m.center_flag) AND !m.arrange_flag
  5262.       \MOVE WINDOW <<m.name>> CENTER
  5263.    ENDIF
  5264. ENDIF
  5265.  
  5266. IF !m.g_redefi
  5267.    DO popindent
  5268.    \ENDIF
  5269. ENDIF
  5270. \
  5271. RETURN
  5272.  
  5273. *!*****************************************************************************
  5274. *!
  5275. *!      Procedure: GETARRANGE
  5276. *!
  5277. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  5278. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  5279. *!
  5280. *!          Calls: WINDOWFROMTO       (procedure in GENSCRN.PRG)
  5281. *!
  5282. *!*****************************************************************************
  5283. PROCEDURE getarrange
  5284. PARAMETER m.dbalias, m.arrange_flag, m.center_flag
  5285. PRIVATE m.j, m.pname, m.entries, m.row, m.col
  5286. IF !EMPTY(arranged)
  5287.    m.entries = INT(LEN(arranged)/26)
  5288.    m.j = 1
  5289.    DO WHILE m.j <= m.entries
  5290.       m.pname = ALLTRIM(UPPER(SUBSTR(arranged,(m.j-1)*26+1,8)))
  5291.       m.pname = ALLTRIM(CHRTRAN(m.pname,CHR(0)," "))
  5292.       IF m.pname == m.g_genvers    && found the right one
  5293.          IF INLIST(UPPER(SUBSTR(arranged,(m.j-1)*26 + 9,1)),'Y','T')    && is it arranged?
  5294.             IF INLIST(UPPER(SUBSTR(arranged,(m.j-1)*26 +10,1)),'Y','T') && is it centered?
  5295.                m.center_flag = .T.
  5296.             ELSE
  5297.                m.arrange_flag = .T.
  5298.                m.row = VAL(SUBSTR(arranged,(m.j-1)*26 + 11,8))
  5299.                m.col = VAL(SUBSTR(arranged,(m.j-1)*26 + 19,8))
  5300.             ENDIF
  5301.          ENDIF
  5302.          EXIT
  5303.       ENDIF
  5304.       m.j = m.j + 1
  5305.    ENDDO
  5306. ENDIF
  5307. SELECT (m.dbalias)
  5308. IF m.arrange_flag
  5309.    DO windowfromto WITH m.row, m.col
  5310. ELSE
  5311.    DO windowfromto
  5312. ENDIF
  5313. RETURN
  5314.  
  5315. *!*****************************************************************************
  5316. *!
  5317. *!      Procedure: GENBOXES
  5318. *!
  5319. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5320. *!
  5321. *!          Calls: ANYPATTERN         (procedure in GENSCRN.PRG)
  5322. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5323. *!               : ANYPEN             (procedure in GENSCRN.PRG)
  5324. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5325. *!
  5326. *!*****************************************************************************
  5327. PROCEDURE genboxes
  5328. *)
  5329. *) GENBOXES - Generate code for boxes.
  5330. *)
  5331. *) Description:
  5332. *) Generate code to display all boxes as they appear on the painted
  5333. *) screen(s).  Note since there is no FILL clause on @...TO command
  5334. *) we use the command @...BOX whenever the fill option has been chosen.
  5335. *) If Fill option is not chosen, then we use the simpler form for
  5336. *) generating boxes, @...TO command which supplies us with clauses
  5337. *) DOUBLE and PANEL for the box borders.
  5338. *)
  5339. PRIVATE m.bottom, m.right, m.thisbox
  5340. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5341.    SET DECIMALS TO 3
  5342.    m.bottom = HEIGHT+vpos
  5343.    m.right = WIDTH+hpos
  5344. ELSE
  5345.    m.bottom = HEIGHT+vpos-1
  5346.    m.right = WIDTH+hpos-1
  5347. ENDIF
  5348. IF (m.g_genvers = 'WINDOWS' OR m.g_genvers = 'MAC')
  5349.    IF fillchar <> c_null AND fillchar <> " "
  5350.       \@ <<Vpos>>,<<Hpos>>,<<m.bottom>>,<<m.right>>
  5351.       DO CASE
  5352.       CASE objcode = c_sgbox
  5353.          m.thisbox = c_single
  5354.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5355.       CASE objcode = c_sgboxd
  5356.          m.thisbox = c_double
  5357.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5358.       CASE objcode = c_sgboxp
  5359.          m.thisbox = c_panel
  5360.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5361.       CASE objcode = c_sgboxc
  5362.          IF boxchar = '"'
  5363.             \\ BOX REPLICATE('<<Boxchar>>',8)
  5364.          ELSE
  5365.             \\ BOX REPLICATE("<<Boxchar>>",8)
  5366.          ENDIF
  5367.          IF fillchar = '"'
  5368.             \\+'<<Fillchar>>'
  5369.          ELSE
  5370.             \\+"<<Fillchar>>"
  5371.          ENDIF
  5372.       ENDCASE
  5373.       SET DECIMALS TO 0
  5374.       RETURN
  5375.    ELSE
  5376.       \@ <<Vpos>>,<<Hpos>> TO <<m.bottom>>,<<m.right>>
  5377.    ENDIF
  5378. ELSE
  5379.    IF fillchar <> c_null
  5380.       \@ <<Vpos>>,<<Hpos>>,<<m.bottom>>,<<m.right>>
  5381.       DO CASE
  5382.       CASE objcode = c_sgbox
  5383.          m.thisbox = c_single
  5384.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5385.       CASE objcode = c_sgboxd
  5386.          m.thisbox = c_double
  5387.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5388.       CASE objcode = c_sgboxp
  5389.          m.thisbox = c_panel
  5390.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5391.       CASE objcode = c_sgboxc
  5392.          IF boxchar = '"'
  5393.             \\ BOX REPLICATE('<<Boxchar>>',8)
  5394.          ELSE
  5395.             \\ BOX REPLICATE("<<Boxchar>>",8)
  5396.          ENDIF
  5397.          IF fillchar = '"'
  5398.             \\+'<<Fillchar>>'
  5399.          ELSE
  5400.             \\+"<<Fillchar>>"
  5401.          ENDIF
  5402.       ENDCASE
  5403.  
  5404.       IF (!EMPTY(colorpair) OR SCHEME <> 0)
  5405.          * Color the inside of the box if it is filled with something.
  5406.          \@ <<Vpos>>,<<Hpos>> FILL TO <<m.bottom>>,<<m.right>>
  5407.          DO anypattern
  5408.          DO anyscheme
  5409.       ENDIF
  5410.       SET DECIMALS TO 0
  5411.       RETURN
  5412.    ELSE
  5413.       \@ <<Vpos>>,<<Hpos>> TO <<m.bottom>>,<<m.right>>
  5414.    ENDIF
  5415. ENDIF
  5416.  
  5417. SET DECIMALS TO 0
  5418. DO CASE
  5419. CASE objcode = c_sgboxd
  5420.    \\ DOUBLE
  5421. CASE objcode = c_sgboxp
  5422.    \\ PANEL
  5423. CASE objcode = c_sgboxc
  5424.    IF boxchar = '"'
  5425.       \\ '<<Boxchar>>'
  5426.    ELSE
  5427.       \\ "<<Boxchar>>"
  5428.    ENDIF
  5429. ENDCASE
  5430. DO anypattern
  5431. DO anypen
  5432. DO anystyle
  5433. DO anyscheme
  5434. RETURN
  5435.  
  5436. *!*****************************************************************************
  5437. *!
  5438. *!      Procedure: GENLINES
  5439. *!
  5440. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5441. *!
  5442. *!          Calls: ANYPEN             (procedure in GENSCRN.PRG)
  5443. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5444. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5445. *!
  5446. *!*****************************************************************************
  5447. PROCEDURE genlines
  5448. *)
  5449. *) GENLINES - Generate code for lines.
  5450. *)
  5451. *) Description:
  5452. *) Generate code to display all lines as they appear on the painted
  5453. *) screen(s).
  5454. *)
  5455. PRIVATE m.x, m.y
  5456. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5457.    SET DECIMALS TO 3
  5458.    IF STYLE = 0
  5459.       m.x = HEIGHT+vpos
  5460.       m.y = hpos
  5461.    ELSE
  5462.       m.x = vpos
  5463.       m.y = WIDTH+hpos
  5464.    ENDIF
  5465. ELSE
  5466.    m.x = HEIGHT+vpos-1
  5467.    m.y = WIDTH+hpos-1
  5468. ENDIF
  5469.  
  5470. \@ <<Vpos>>,<<Hpos>> TO <<m.x>>,<<m.y>>
  5471. SET DECIMALS TO 0
  5472. IF BORDER = 1
  5473.    \\ DOUBLE
  5474. ENDIF
  5475. DO anypen
  5476. DO anystyle
  5477. DO anyscheme
  5478. RETURN
  5479.  
  5480.  
  5481. *!*****************************************************************************
  5482. *!
  5483. *!      Procedure: GENTEXT
  5484. *!
  5485. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5486. *!
  5487. *!          Calls: ANYPICTURE         (procedure in GENSCRN.PRG)
  5488. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5489. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5490. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5491. *!
  5492. *!*****************************************************************************
  5493. PROCEDURE gentext
  5494. *)
  5495. *) GENTEXT - Generate code for text.
  5496. *)
  5497. *) Description:
  5498. *) Generate code that will display the text exactly as it appears
  5499. *) in the painted screen(s).
  5500. *)
  5501. PRIVATE m.theexpr, m.occur, m.pos
  5502. m.theexpr = expr
  5503. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5504.    SET DECIMALS TO 3
  5505.    m.occur = 1
  5506.    m.pos = AT(CHR(13), m.theexpr, m.occur)
  5507.    * Sometimes the screen builder surrounds text with single quotes and other
  5508.    * times with double quotes.
  5509.    q1 = LEFT(LTRIM(m.theexpr),1)
  5510.  
  5511.    DO WHILE m.pos > 0
  5512.       DO CASE
  5513.       CASE q1 = "'"
  5514.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5515.             "' + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "'" ;
  5516.             + SUBSTR(m.theexpr, m.pos + 1)
  5517.       CASE q1 = '['
  5518.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5519.             "] + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "[" ;
  5520.             + SUBSTR(m.theexpr, m.pos + 1)
  5521.       OTHERWISE
  5522.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5523.             '" + CHR(13) + ;' + CHR(13)  + CHR(9) + CHR(9) + '"' ;
  5524.             + SUBSTR(m.theexpr, m.pos + 1)
  5525.       ENDCASE
  5526.       m.occur = m.occur + 1
  5527.       m.pos = AT(CHR(13), m.theexpr, m.occur)
  5528.    ENDDO
  5529.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>>
  5530.    IF height > 1
  5531.       \\ ;
  5532.       \    SIZE <<Height>>,<<Width>>, <<Spacing>>
  5533.    ENDIF
  5534. ELSE
  5535.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  5536.    \    SIZE <<Height>>,<<Width>>, <<Spacing>>
  5537. ENDIF
  5538.  
  5539. SET DECIMALS TO 0
  5540. DO anypicture
  5541. DO anyfont
  5542. DO anystyle
  5543. DO anyscheme
  5544. RETURN
  5545.  
  5546. *!*****************************************************************************
  5547. *!
  5548. *!      Procedure: GENFIELDS
  5549. *!
  5550. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5551. *!
  5552. *!          Calls: ANYFONT            (procedure in GENSCRN.PRG)
  5553. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5554. *!               : ANYPICTURE         (procedure in GENSCRN.PRG)
  5555. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5556. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5557. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  5558. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5559. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5560. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5561. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5562. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5563. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5564. *!
  5565. *!*****************************************************************************
  5566. PROCEDURE genfields
  5567. *)
  5568. *) GENFIELDS - Generate fields.
  5569. *)
  5570. *) Description:
  5571. *) Generate code to display SAY, GET, and EDIT statements exactly as they
  5572. *) appear in the painted screen(s).
  5573. *)
  5574. PRIVATE m.theexpr
  5575. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5576.    SET DECIMALS TO 3
  5577. ENDIF
  5578. DO CASE
  5579. CASE objcode = c_sgsay
  5580.    m.theexpr = expr
  5581.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  5582.    \    SIZE <<Height>>,<<Width>>
  5583.    SET DECIMALS TO 0
  5584.    DO anyfont
  5585.    DO anystyle
  5586.    DO anypicture
  5587.    DO anyscheme
  5588.    RETURN
  5589. CASE objcode = c_sgget
  5590.    \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5591.    \    SIZE <<Height>>,<<Width>>
  5592.    DO elemrange
  5593. CASE objcode = c_sgedit
  5594.    DO gentxtrgn
  5595.    RETURN
  5596. ENDCASE
  5597. SET DECIMALS TO 0
  5598.  
  5599. DO gendefault
  5600. DO anyfont
  5601. DO anystyle
  5602. DO anypicture
  5603. DO anywhen
  5604. DO anyvalid
  5605. DO anymessage
  5606. DO anyerror
  5607. DO anydisabled
  5608. DO anyscheme
  5609. RETURN
  5610.  
  5611. *!*****************************************************************************
  5612. *!
  5613. *!      Procedure: GENINVBUT
  5614. *!
  5615. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5616. *!
  5617. *!          Calls: ANYFONT            (procedure in GENSCRN.PRG)
  5618. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5619. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5620. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5621. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5622. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5623. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5624. *!
  5625. *!*****************************************************************************
  5626. PROCEDURE geninvbut
  5627. *)
  5628. *) GENINVBUT - Generate Invisible buttons.
  5629. *)
  5630. *) Description:
  5631. *) Generate code to display invisible buttons exactly as they appear
  5632. *) in the painted screen(s).
  5633. *)
  5634.  
  5635. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5636.    SET DECIMALS TO 3
  5637. ENDIF
  5638. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5639. \    PICTURE <<Picture>> ;
  5640. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5641. \    DEFAULT 0
  5642. SET DECIMALS TO 0
  5643.  
  5644. DO anyfont
  5645. DO anystyle
  5646. DO anywhen
  5647. DO anyvalid
  5648. DO anydisabled
  5649. DO anymessage
  5650. DO anyscheme
  5651. RETURN
  5652.  
  5653. *!*****************************************************************************
  5654. *!
  5655. *!      Procedure: GENTXTRGN
  5656. *!
  5657. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  5658. *!
  5659. *!          Calls: ANYPICTURE         (procedure in GENSCRN.PRG)
  5660. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5661. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5662. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5663. *!               : ANYTAB             (procedure in GENSCRN.PRG)
  5664. *!               : ANYSCROLL          (procedure in GENSCRN.PRG)
  5665. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5666. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5667. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5668. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5669. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5670. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5671. *!
  5672. *!*****************************************************************************
  5673. PROCEDURE gentxtrgn
  5674. *)
  5675. *) GENTXTRGN - Generate some statements for text edit region.
  5676. *)
  5677. *) Description:
  5678. *) Generate code to display text edit regions exactly as they
  5679. *) appear on the painted screen(s).
  5680. *)
  5681. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5682.    SET DECIMALS TO 3
  5683. ENDIF
  5684. \@ <<Vpos>>,<<Hpos>> EDIT <<Name>> ;
  5685. \    SIZE <<IIF(Height < 1, 1, Height)>>,<<Width>>,<<Initialnum>>
  5686. SET DECIMALS TO 0
  5687.  
  5688. IF NOT EMPTY(PICTURE)
  5689.    DO anypicture
  5690. ENDIF
  5691. DO gendefault
  5692. DO anyfont
  5693. DO anystyle
  5694. DO anytab
  5695. DO anyscroll
  5696. DO anywhen
  5697. DO anyvalid
  5698. DO anymessage
  5699. DO anyerror
  5700. DO anydisabled
  5701. DO anyscheme
  5702. RETURN
  5703.  
  5704. *!*****************************************************************************
  5705. *!
  5706. *!      Procedure: GENPUSH
  5707. *!
  5708. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5709. *!
  5710. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5711. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5712. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5713. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5714. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5715. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5716. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5717. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5718. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5719. *!
  5720. *!*****************************************************************************
  5721. PROCEDURE genpush
  5722. *)
  5723. *) GENPUSH - Generate Push buttons.
  5724. *)
  5725. *) Description:
  5726. *) Generate code to display push buttons exactly as they appear
  5727. *) in the painted screen(s).
  5728. *)
  5729. PRIVATE m.thepicture
  5730.  
  5731. m.thepicture = PICTURE
  5732. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5733.    SET DECIMALS TO 3
  5734. ENDIF
  5735. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5736. DO anybitmapctrl WITH m.thepicture
  5737. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5738. SET DECIMALS TO 0
  5739. \    DEFAULT <<Initialnum>>
  5740. DO anyfont
  5741. DO anystyle
  5742. DO anywhen
  5743. DO anyvalid
  5744. DO anydisabled
  5745. DO anymessage
  5746. DO anyerror
  5747. DO anyscheme
  5748. RETURN
  5749.  
  5750. *!*****************************************************************************
  5751. *!
  5752. *!      Procedure: GENRADBUT
  5753. *!
  5754. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5755. *!
  5756. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5757. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5758. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5759. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5760. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5761. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5762. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5763. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5764. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5765. *!
  5766. *!*****************************************************************************
  5767. PROCEDURE genradbut
  5768. *)
  5769. *) GENRADBUT - Generate Radio Buttons.
  5770. *)
  5771. *) Description:
  5772. *) Generate code to display radio buttons exactly as they appear
  5773. *) in the painted screen(s).
  5774. *)
  5775. PRIVATE m.thepicture
  5776.  
  5777. m.thepicture = PICTURE
  5778. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5779.    SET DECIMALS TO 3
  5780. ENDIF
  5781. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5782. DO anybitmapctrl WITH m.thepicture
  5783. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5784. SET DECIMALS TO 0
  5785. \    DEFAULT <<Initialnum>>
  5786. DO anyfont
  5787. DO anystyle
  5788. DO anywhen
  5789. DO anyvalid
  5790. DO anydisabled
  5791. DO anymessage
  5792. DO anyerror
  5793. DO anyscheme
  5794. RETURN
  5795.  
  5796. *!*****************************************************************************
  5797. *!
  5798. *!      Procedure: GENCHKBOX
  5799. *!
  5800. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5801. *!
  5802. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5803. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5804. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5805. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5806. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5807. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5808. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5809. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5810. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5811. *!
  5812. *!*****************************************************************************
  5813. PROCEDURE genchkbox
  5814. *)
  5815. *) GENCHKBOX - Generate Check Boxes
  5816. *)
  5817. *) Description:
  5818. *) Generate code to display check boxes exactly as they appear
  5819. *) in the painted screen(s).
  5820. *)
  5821. PRIVATE m.thepicture
  5822.  
  5823. m.thepicture = PICTURE
  5824. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5825.    SET DECIMALS TO 3
  5826. ENDIF
  5827.  
  5828. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5829. DO anybitmapctrl WITH m.thepicture
  5830. \    SIZE <<Height>>,<<Width>> ;
  5831. SET DECIMALS TO 0
  5832. \    DEFAULT <<Initialnum>>
  5833. DO anyfont
  5834. DO anystyle
  5835. DO anywhen
  5836. DO anyvalid
  5837. DO anydisabled
  5838. DO anymessage
  5839. DO anyerror
  5840. DO anyscheme
  5841. RETURN
  5842.  
  5843. *!*****************************************************************************
  5844. *!
  5845. *!      Procedure: GENLIST
  5846. *!
  5847. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5848. *!
  5849. *!          Calls: CHOPPICTURE        (procedure in GENSCRN.PRG)
  5850. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5851. *!               : FROMPOPUP          (procedure in GENSCRN.PRG)
  5852. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5853. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5854. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5855. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5856. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5857. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5858. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5859. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5860. *!
  5861. *!*****************************************************************************
  5862. PROCEDURE genlist
  5863. *)
  5864. *) GENLIST - Generate Scrollable Lists.
  5865. *)
  5866. *) Description:
  5867. *) Generate code to display scrollable lists exactly as they appear
  5868. *) in the painted screen(s).
  5869. *)
  5870. PRIVATE m.pos, m.start
  5871. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5872.    SET DECIMALS TO 3
  5873. ENDIF
  5874. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5875. SET DECIMALS TO 0
  5876. IF NOT EMPTY(PICTURE)
  5877.    \     PICTURE
  5878.    DO choppicture WITH PICTURE
  5879.    \\ ;
  5880. ENDIF
  5881. IF STYLE = 0
  5882.    \    FROM <<Expr>>
  5883.    DO elemrange
  5884.    \\ ;
  5885.    IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5886.       SET DECIMALS TO 3
  5887.    ENDIF
  5888.    \    SIZE <<Height>>,<<Width>> ;
  5889.    SET DECIMALS TO 0
  5890.    \    DEFAULT 1
  5891. ELSE
  5892.    DO frompopup
  5893. ENDIF
  5894.  
  5895. DO anyfont
  5896. DO anystyle
  5897. DO anywhen
  5898. DO anyvalid
  5899. DO anydisabled
  5900. DO anymessage
  5901. DO anyerror
  5902. DO anyscheme
  5903. RETURN
  5904.  
  5905. *!*****************************************************************************
  5906. *!
  5907. *!      Procedure: GENPICTURE
  5908. *!
  5909. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  5910. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  5911. *!
  5912. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  5913. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5914. *!
  5915. *!*****************************************************************************
  5916. PROCEDURE genpicture
  5917. *)
  5918. *) GENPICTURE - Generate code for pictures.
  5919. *)
  5920. *) Description:
  5921. *) Generate code to display pictures (bitmaps or bitmaps in general fields).
  5922. *)
  5923. PRIVATE m.relpath
  5924. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5925.    SET DECIMALS TO 3
  5926.    \@ <<Vpos>>,<<Hpos>> SAY
  5927.    IF STYLE = 0
  5928.       m.relpath = LOWER(findrelpath(SUBSTR(PICTURE,2,LEN(PICTURE)-2)))
  5929.         IF EMPTY(justext(m.relpath))
  5930.            m.relpath = m.relpath + "."
  5931.         ENDIF
  5932.       \\ (LOCFILE("<<m.relpath>>",<<bitmapstr(c_all)>>, "Where is <<basename(m.relpath)>>?"
  5933.         IF _MAC
  5934.             * Use the "type" parameter to get all PICT files on the Mac,
  5935.             * regardless of extension.
  5936.             \\, "PICT"
  5937.         ENDIF
  5938.         \\ )) BITMAP ;
  5939.    ELSE
  5940.       \\ <<Name>> ;
  5941.    ENDIF
  5942.    \    SIZE <<Height>>,<<Width>>
  5943.  
  5944.    IF CENTER
  5945.       \\ ;
  5946.       \    CENTER
  5947.    ENDIF
  5948.  
  5949.    DO CASE
  5950.    CASE BORDER = 1
  5951.       \\ ;
  5952.       \    ISOMETRIC
  5953.    CASE BORDER = 2
  5954.       \\ ;
  5955.       \    STRETCH
  5956.    ENDCASE
  5957.  
  5958.    SET DECIMALS TO 0
  5959.    DO anystyle
  5960. ENDIF
  5961. RETURN
  5962.  
  5963. *!*****************************************************************************
  5964. *!
  5965. *!      Procedure: GENSPINNER
  5966. *!
  5967. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5968. *!
  5969. *!          Calls: CHOPPICTURE        (procedure in GENSCRN.PRG)
  5970. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5971. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5972. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5973. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5974. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5975. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5976. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5977. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5978. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5979. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5980. *!
  5981. *!*****************************************************************************
  5982. PROCEDURE genspinner
  5983. *)
  5984. *) GENSPINNER - Generate Spinners
  5985. *)
  5986. *) Description:
  5987. *) Generate code to display spinners exactly as they appear
  5988. *) in the painted screen(s).
  5989. *)
  5990. PRIVATE m.thepicture
  5991.  
  5992. m.thepicture = PICTURE
  5993. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5994.    SET DECIMALS TO 3
  5995. ENDIF
  5996.  
  5997. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5998. \    SPINNER
  5999.  
  6000. ** Generate the increment value
  6001. IF !EMPTY(initialval)
  6002.    IF INT(VAL(initialval)) <> VAL(initialval)
  6003.       SET DECIMALS TO LEN(initialval) - AT('.',initialval)
  6004.    ENDIF
  6005.    \\ <<VAL(Initialval)>>
  6006.    SET DECIMALS TO 3
  6007. ELSE
  6008.    \\ 1.000
  6009. ENDIF
  6010.  
  6011. ** Generate the minimum value.
  6012. IF !EMPTY(TAG)
  6013.    \\, <<Tag>>
  6014. ELSE
  6015.    IF !EMPTY(tag2)
  6016.       \\,
  6017.    ENDIF
  6018. ENDIF
  6019.  
  6020. ** Generate the maximum value.
  6021. IF !EMPTY(tag2)
  6022.    \\, <<Tag2>>
  6023. ENDIF
  6024. \\ ;
  6025.  
  6026. IF !EMPTY(m.thepicture)
  6027.    \    PICTURE
  6028.    DO choppicture WITH m.thepicture
  6029.    \\ ;
  6030. ENDIF
  6031. \    SIZE <<Height>>, <<Width>>
  6032.  
  6033. ** Put out a default which corresponds to the range of valid values.
  6034. DO CASE
  6035. CASE !EMPTY(TAG)
  6036.    \\ ;
  6037.    \    DEFAULT <<VAL(Tag)>>
  6038. CASE !EMPTY(tag2)
  6039.    \\ ;
  6040.    \    DEFAULT <<VAL(Tag2)>>
  6041. CASE EMPTY(TRIM(initialval))
  6042.    \\ ;
  6043.    \    DEFAULT 1
  6044. OTHERWISE
  6045.    DO gendefault
  6046. ENDCASE
  6047.  
  6048. DO elemrange
  6049. DO anywhen
  6050. DO anyvalid
  6051. DO anydisabled
  6052. DO anymessage
  6053. DO anyerror
  6054. SET DECIMALS TO 0
  6055. DO anyfont
  6056. DO anystyle
  6057. DO anyscheme
  6058. RETURN
  6059.  
  6060. *!*****************************************************************************
  6061. *!
  6062. *!      Procedure: FROMPOPUP
  6063. *!
  6064. *!      Called by: GENLIST            (procedure in GENSCRN.PRG)
  6065. *!
  6066. *!*****************************************************************************
  6067. PROCEDURE frompopup
  6068. *)
  6069. *) FROMPOPUP - Generate code for scrollable list defined from a popup.
  6070. *)
  6071. *) Description:
  6072. *) Generate POPUP <popup name> code as part of a scrollable list
  6073. *) definition.  Popup name may either be name explicitly provided by
  6074. *) the user or a unique name generated by SYS(2015) function.
  6075. *)
  6076. PRIVATE m.start, m.pos
  6077. \    POPUP
  6078. IF STYLE < 2
  6079.    IF NOT EMPTY(expr)
  6080.       \\ <<Expr>> ;
  6081.    ENDIF
  6082. ELSE
  6083.    m.start = 1
  6084.    m.pos   = 0
  6085.    DO WHILE .T.
  6086.       m.pos = ASCAN(g_popups, m.dbalias, m.start)
  6087.       IF g_popups[m.pos+1] = RECNO()
  6088.          EXIT
  6089.       ENDIF
  6090.       m.start = m.pos + 3
  6091.    ENDDO
  6092.    \\ <<g_popups[m.pos+2]>> ;
  6093. ENDIF
  6094.  
  6095. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6096.    SET DECIMALS TO 3
  6097. ENDIF
  6098. \    SIZE <<Height>>,<<Width>> ;
  6099. \    DEFAULT " "
  6100. SET DECIMALS TO 0
  6101. RETURN
  6102.  
  6103. *!*****************************************************************************
  6104. *!
  6105. *!      Procedure: GENPOPUP
  6106. *!
  6107. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  6108. *!
  6109. *!          Calls: ELEMRANGE          (procedure in GENSCRN.PRG)
  6110. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  6111. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  6112. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  6113. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  6114. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  6115. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  6116. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  6117. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  6118. *!
  6119. *!*****************************************************************************
  6120. PROCEDURE genpopup
  6121. *)
  6122. *) GENPOPUP - Generate Popups.
  6123. *)
  6124. *) Description:
  6125. *) Generate code to display popups exactly as they appear in the
  6126. *) painted screen(s).
  6127. *)
  6128. PRIVATE m.thepicture, m.theinitval
  6129.  
  6130. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6131.    SET DECIMALS TO 3
  6132. ENDIF
  6133. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  6134. IF objcode = c_sgget
  6135.    m.thepicture = PICTURE
  6136.    m.theinitval = initialval
  6137.    \    PICTURE <<m.thepicture>> ;
  6138.    \    SIZE <<Height>>,<<Width>> ;
  6139.    \    DEFAULT <<IIF(EMPTY(m.theinitval), '" "', m.theinitval)>>
  6140. ELSE
  6141.     * e.g., popup from array
  6142.    \    PICTURE "<<ctrlclause(picture)>>" ;
  6143.    \    FROM <<Expr>> ;
  6144.    \    SIZE <<Height>>,<<Width>>
  6145.    DO elemrange
  6146.    \\ ;
  6147.    \    DEFAULT 1
  6148. ENDIF
  6149. SET DECIMALS TO 0
  6150.  
  6151. DO anyfont
  6152. DO anystyle
  6153. DO anywhen
  6154. DO anyvalid
  6155. DO anydisabled
  6156. DO anymessage
  6157. DO anyerror
  6158. DO anyscheme
  6159. RETURN
  6160.  
  6161. *!*****************************************************************************
  6162. *!
  6163. *!      Procedure: ELEMRANGE
  6164. *!
  6165. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6166. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6167. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6168. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6169. *!
  6170. *!          Calls: ADDTOCTRL          (procedure in GENSCRN.PRG)
  6171. *!
  6172. *!*****************************************************************************
  6173. PROCEDURE elemrange
  6174. *)
  6175. *) ELEMRANGE - Element range clause for popup and scrollable list
  6176. *)                defined form an array.
  6177. *)
  6178. PRIVATE m.firstelem, m.genericname
  6179. m.firstelem = .F.
  6180. IF NOT EMPTY(rangelo)
  6181.    m.firstelem = .T.
  6182.    \\ ;
  6183.    \    RANGE
  6184.    IF lotype = 0
  6185.       \\ <<ALLTRIM(CHRTRAN(Rangelo,CHR(13)+CHR(10),""))>>
  6186.    ELSE
  6187.       m.genericname = LOWER(SYS(2015))
  6188.       \\ <<m.genericname>>()
  6189.       DO CASE
  6190.       CASE objtype = c_otfield
  6191.          DO addtoctrl WITH m.genericname, "GET Low RANGE", rangelo, name
  6192.       CASE objtype = c_otspinner
  6193.          DO addtoctrl WITH m.genericname, "SPINNER Low RANGE", rangelo, name
  6194.       OTHERWISE
  6195.          DO addtoctrl WITH m.genericname, "Popup From", rangelo, name
  6196.       ENDCASE
  6197.    ENDIF
  6198. ENDIF
  6199. IF NOT EMPTY(rangehi)
  6200.    IF NOT m.firstelem
  6201.       \\ ;
  6202.       \    RANGE ,
  6203.    ELSE
  6204.       \\,
  6205.    ENDIF
  6206.    IF hitype = 0
  6207.       \\ <<CHRTRAN(ALLTRIM(Rangehi),CHR(13)+CHR(10),"")>>
  6208.    ELSE
  6209.       m.genericname = LOWER(SYS(2015))
  6210.       \\ <<m.genericname>>()
  6211.       DO CASE
  6212.       CASE objtype = c_otfield
  6213.          DO addtoctrl WITH m.genericname, "GET High RANGE", rangehi, name
  6214.       CASE objtype = c_otspinner
  6215.          DO addtoctrl WITH m.genericname, "SPINNER High RANGE", rangehi, name
  6216.       OTHERWISE
  6217.          DO addtoctrl WITH m.genericname, "Popup From", rangehi, name
  6218.       ENDCASE
  6219.    ENDIF
  6220. ENDIF
  6221. RETURN
  6222.  
  6223. *!*****************************************************************************
  6224. *!
  6225. *!      Procedure: GENACTWINDOW
  6226. *!
  6227. *!      Called by: ANYWINDOWS         (procedure in GENSCRN.PRG)
  6228. *!
  6229. *!*****************************************************************************
  6230. PROCEDURE genactwindow
  6231. *)
  6232. *) GENACTWINDOW - Generate Activate Window Command.
  6233. *)
  6234. *) Description:
  6235. *) Generate the ACTIVATE WINDOW... command.
  6236. *)
  6237. PARAMETER m.cnt
  6238. IF !m.g_noreadplain
  6239.    IF m.g_lastwindow == g_screens[m.cnt,2]
  6240.       \@ 0,0 CLEAR
  6241.    ENDIF
  6242.    IF m.g_multreads
  6243.       \ACTIVATE WINDOW <<g_screens[m.cnt,2]>>
  6244.       RETURN
  6245.    ENDIF
  6246.  
  6247.    \IF WVISIBLE("<<g_screens[m.cnt,2]>>")
  6248.    \    ACTIVATE WINDOW <<g_screens[m.cnt,2]>> SAME
  6249.    \ELSE
  6250.    \    ACTIVATE WINDOW <<g_screens[m.cnt,2]>> NOSHOW
  6251.    \ENDIF
  6252. ENDIF
  6253. RETURN
  6254.  
  6255. *!*****************************************************************************
  6256. *!
  6257. *!      Procedure: GENDEFAULT
  6258. *!
  6259. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6260. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6261. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6262. *!
  6263. *!*****************************************************************************
  6264. PROCEDURE gendefault
  6265. *)
  6266. *) GENDEFAULT - Generate Default Clause.
  6267. *)
  6268. PRIVATE m.theinitval
  6269. IF EMPTY(TRIM(initialval)) AND EMPTY(fillchar)
  6270.    RETURN
  6271. ENDIF
  6272. \\ ;
  6273. \    DEFAULT
  6274. IF EMPTY(TRIM(initialval))
  6275.    DO CASE
  6276.    CASE fillchar = "D"
  6277.       \\ {  /  /  }
  6278.    CASE fillchar = "C" OR fillchar = "M" OR fillchar = "G"
  6279.       \\ " "
  6280.    CASE fillchar = "L"
  6281.       \\ .F.
  6282.    CASE fillchar = "N"
  6283.       \\ 0
  6284.    CASE fillchar = "F"
  6285.       \\ 0.0
  6286.    ENDCASE
  6287. ELSE
  6288.    m.theinitval = initialval
  6289.    \\ <<ALLTRIM(m.theinitval)>>
  6290. ENDIF
  6291. RETURN
  6292.  
  6293. **
  6294. **  Procedures Generating Various Clauses for Screen Objects
  6295. **
  6296.  
  6297. *!*****************************************************************************
  6298. *!
  6299. *!      Procedure: ANYBITMAPCTRL
  6300. *!
  6301. *!      Called by: GENPUSH            (procedure in GENSCRN.PRG)
  6302. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6303. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6304. *!
  6305. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6306. *!               : CHOPPICTURE        (procedure in GENSCRN.PRG)
  6307. *!
  6308. *!*****************************************************************************
  6309. PROCEDURE anybitmapctrl
  6310. *)
  6311. *) ANYBITMAPCTRL - Parse the picture clause for a bitmap control (Push button, radio button, checkbox) and return it
  6312. *)        with LOCAFILE and a relative path in place of each absolute path.
  6313. *)
  6314. PARAMETER m.picture
  6315. PRIVATE m.name, m.relpath, m.count
  6316.  
  6317. IF AT("B", SUBSTR(m.picture,1, AT(" ",m.picture))) <> 0
  6318.    \    PICTURE <<LEFT(m.picture, AT(" ",m.picture))>>"
  6319.  
  6320.    m.picture = SUBSTR(m.picture, AT(" ", m.picture)+1)
  6321.    m.picture = LEFT(m.picture, LEN(m.picture)-1)
  6322.    m.count = 0
  6323.  
  6324.    DO WHILE LEN(m.picture) <> 0
  6325.       m.count = m.count + 1
  6326.       IF AT(";", m.picture) <> 0
  6327.          m.name = LEFT(m.picture, AT(";", m.picture)-1)
  6328.          m.picture = SUBSTR(m.picture, AT(";",m.picture)+1)
  6329.       ELSE
  6330.          m.name = m.picture
  6331.          m.picture = ""
  6332.       ENDIF
  6333.  
  6334.       m.relpath = LOWER(findrelpath(m.name))
  6335.  
  6336.       IF m.count = 1
  6337.          \\ + ;
  6338.       ELSE
  6339.          \\ + ";" + ;
  6340.       ENDIF
  6341.         IF EMPTY(justext(m.relpath))
  6342.            m.relpath = m.relpath + "."
  6343.         ENDIF
  6344.       \        (LOCFILE("<<m.relpath>>",<<bitmapstr(c_all)>>,"Where is <<basename(m.relpath)>>?"
  6345.         IF _MAC
  6346.             \\,"PICT"
  6347.         ENDIF
  6348.         \\))
  6349.    ENDDO
  6350.  
  6351.    \\ ;
  6352. ELSE
  6353.    \    PICTURE
  6354.    DO choppicture WITH m.picture
  6355.    \\ ;
  6356. ENDIF
  6357. RETURN
  6358.  
  6359. *!*****************************************************************************
  6360. *!
  6361. *!      Procedure: CHOPPICTURE
  6362. *!
  6363. *!      Called by: GENLIST            (procedure in GENSCRN.PRG)
  6364. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6365. *!               : ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  6366. *!
  6367. *!*****************************************************************************
  6368. PROCEDURE choppicture
  6369. *)
  6370. *) CHOPPICTURE - Breaks a Picture clause into multiple 250 character segments to avoid
  6371. *)        the maximum string length limit.
  6372. *)
  6373. PARAMETER m.pict
  6374. PRIVATE m.quotechar, m.first
  6375. m.quotechar = LEFT(m.pict,1)
  6376. m.first = .T.
  6377.  
  6378. DO WHILE LEN(m.pict) > 250
  6379.    IF m.first
  6380.       \\ <<LEFT(m.pict,250) + m.quotechar>> + ;
  6381.       m.first = .F.
  6382.    ELSE
  6383.       \        <<LEFT(m.pict,250) + m.quotechar>> + ;
  6384.    ENDIF
  6385.    m.pict = m.quotechar + SUBSTR(m.pict,251)
  6386. ENDDO
  6387.  
  6388. IF m.first
  6389.    \\ <<m.pict>>
  6390. ELSE
  6391.    \    <<m.pict>>
  6392. ENDIF
  6393. RETURN
  6394.  
  6395. *!*****************************************************************************
  6396. *!
  6397. *!      Procedure: ANYDISABLED
  6398. *!
  6399. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6400. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6401. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6402. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6403. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6404. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6405. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6406. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6407. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6408. *!
  6409. *!*****************************************************************************
  6410. PROCEDURE anydisabled
  6411. *)
  6412. *) ANYDISABLED - Place ENABLE/DISABLE clause.
  6413. *)
  6414. IF disabled
  6415.    \\ ;
  6416.    \    DISABLE
  6417. ENDIF
  6418. RETURN
  6419.  
  6420. *!*****************************************************************************
  6421. *!
  6422. *!      Procedure: ANYPICTURE
  6423. *!
  6424. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6425. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6426. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6427. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6428. *!
  6429. *!*****************************************************************************
  6430. PROCEDURE anypicture
  6431. *)
  6432. *) ANYPICTURE
  6433. *)
  6434. PRIVATE m.string, m.expr_pos, m.newstring
  6435. IF NOT EMPTY(PICTURE) AND PICTURE <> '" "'
  6436.    \\ ;
  6437.    m.string = SUBSTR(PICTURE,2)   && drop opening quotation mark
  6438.    DO CASE
  6439.    CASE SUBSTR(m.string,1,1) = m.g_itse
  6440.       \    PICTURE <<SUBSTR(m.string,2,RAT(LEFT(picture,1),m.string)-2)>>
  6441.    CASE hasexpr(m.string) > 0 && an #ITSEXPRESSION character somewhere in the middle
  6442.        m.expr_pos = hasexpr(picture)
  6443.        * Emit the first part of the PICTURE
  6444.        \    PICTURE <<LEFT(picture,expr_pos-1)>>
  6445.        * Emit a closing quotation mark, which will be the same as the opening one
  6446.        \\<<LEFT(picture,1)>>
  6447.        * Now emit the expression portion of the picture clause, not including a closing quote
  6448.        \\ + <<SUBSTR(picture,expr_pos+1,LEN(picture)-expr_pos-1))>>
  6449.    OTHERWISE
  6450.       \    PICTURE <<Picture>>
  6451.    ENDCASE
  6452. ENDIF
  6453.  
  6454.  
  6455. FUNCTION hasexpr
  6456. PARAMETER m.thepicture
  6457. RETURN ATC(m.g_itse,m.thepicture)
  6458.  
  6459. *!*****************************************************************************
  6460. *!
  6461. *!      Procedure: ANYSCROLL
  6462. *!
  6463. *!      Called by: GENTXTRGN          (procedure in GENSCRN.PRG)
  6464. *!
  6465. *!*****************************************************************************
  6466. PROCEDURE anyscroll
  6467. *)
  6468. *) ANYSCROLL - Place Scroll clause if applicable.
  6469. *)
  6470. IF scrollbar
  6471.    \\ ;
  6472.    \    SCROLL
  6473. ENDIF
  6474. RETURN
  6475.  
  6476. *!*****************************************************************************
  6477. *!
  6478. *!      Procedure: ANYTAB
  6479. *!
  6480. *!      Called by: GENTXTRGN          (procedure in GENSCRN.PRG)
  6481. *!
  6482. *!*****************************************************************************
  6483. PROCEDURE anytab
  6484. *)
  6485. *) ANYTAB - Place Tab clause on an @...EDIT command.
  6486. *)
  6487. IF TAB
  6488.    \\ ;
  6489.    \    TAB
  6490. ENDIF
  6491. RETURN
  6492.  
  6493. *!*****************************************************************************
  6494. *!
  6495. *!      Procedure: ANYFONT
  6496. *!
  6497. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6498. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6499. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6500. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6501. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6502. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6503. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6504. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6505. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6506. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6507. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6508. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6509. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6510. *!
  6511. *!*****************************************************************************
  6512. PROCEDURE anyfont
  6513. *)
  6514. *) ANYFONT - Place font clause on an object if in a graphical
  6515. *)        environment
  6516. *)
  6517. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6518.    \\ ;
  6519.    \    FONT "<<Fontface>>", <<Fontsize>>
  6520. ENDIF
  6521. RETURN
  6522.  
  6523. *!*****************************************************************************
  6524. *!
  6525. *!      Procedure: ANYSTYLE
  6526. *!
  6527. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6528. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6529. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6530. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  6531. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6532. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6533. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6534. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6535. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6536. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6537. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6538. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6539. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6540. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  6541. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6542. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6543. *!
  6544. *!*****************************************************************************
  6545. PROCEDURE anystyle
  6546. *)
  6547. *) ANYSTYLE - Place a Style clause in an object.
  6548. *)
  6549. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6550.    IF NOT EMPTY(fontstyle) OR mode != 0 OR ;
  6551.          (NOT EMPTY(STYLE) AND objtype != c_otscreen AND ;
  6552.          objtype != c_ottext )
  6553.       \\ ;
  6554.       \    STYLE "
  6555.         \\<<num2style(fontstyle)>>
  6556.  
  6557.         * Is it transparent?
  6558.       IF mode = 1
  6559.          \\T
  6560.       ENDIF
  6561.  
  6562.       IF NOT EMPTY(STYLE) AND objtype != c_otscreen AND ;
  6563.             objtype != c_otlist AND objtype != c_ottext AND ;
  6564.                         objtype != c_otpicture
  6565.          \\<<Style>>
  6566.       ENDIF
  6567.       \\"
  6568.    ENDIF
  6569. ENDIF
  6570. RETURN
  6571.  
  6572. *!*****************************************************************************
  6573. *!
  6574. *!      Procedure: ANYPATTERN
  6575. *!
  6576. *!      Called by: GENBOXES           (procedure in GENSCRN.PRG)
  6577. *!
  6578. *!*****************************************************************************
  6579. PROCEDURE anypattern
  6580. *)
  6581. *) ANYPATTERN - Place a PATTERN clause for boxes.
  6582. *)
  6583. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6584.    IF fillpat != 0
  6585.       \\ ;
  6586.       \    PATTERN <<Fillpat>>
  6587.    ENDIF
  6588. ENDIF
  6589. RETURN
  6590.  
  6591. *!*****************************************************************************
  6592. *!
  6593. *!      Procedure: ANYSCHEME
  6594. *!
  6595. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6596. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6597. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6598. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  6599. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6600. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6601. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6602. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6603. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6604. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6605. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6606. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6607. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6608. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6609. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6610. *!
  6611. *!*****************************************************************************
  6612. PROCEDURE anyscheme
  6613. *)
  6614. *) ANYSCHEME - Place Color Scheme clause if applicable.
  6615. *)
  6616.  
  6617. IF NOT EMPTY(colorpair)
  6618.    \\ ;
  6619.    \    COLOR <<Colorpair>>
  6620.    RETURN
  6621. ENDIF
  6622. IF SCHEME <> 0
  6623.    \\ ;
  6624.    \    COLOR SCHEME <<Scheme>>
  6625.    IF objtype = c_otpopup AND scheme2<>0
  6626.       \\, <<Scheme2>>
  6627.    ENDIF
  6628. ELSE
  6629.    IF m.g_defasch2 <> 0
  6630.       DO CASE
  6631.       CASE objtype = c_ottext AND HEIGHT > 1
  6632.          \\ ;
  6633.          \    COLOR SCHEME <<m.g_defasch2>>
  6634.       CASE objtype = c_otlist
  6635.          \\ ;
  6636.          \    COLOR SCHEME <<m.g_defasch2>>
  6637.       CASE objtype = c_otpopup
  6638.          \\ ;
  6639.          \    COLOR SCHEME <<m.g_defasch1>>, <<m.g_defasch2>>
  6640.       ENDCASE
  6641.    ELSE
  6642.       IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC' ) ;
  6643.             AND ((ObjTYpe = c_otscreen AND fillred >=0) ;
  6644.              OR (ObjType <> c_otscreen AND (penred >= 0 OR fillred >= 0)) )
  6645.          m.ctrlflag = .F.   && .T. if this is a control-type object (e.g., radio button)
  6646.          \\ ;
  6647.          \    COLOR
  6648.          DO CASE
  6649.          CASE INLIST(objtype,c_otfield,c_otspinner)
  6650.             ** Field or spinner - color pair 2
  6651.             DO CASE
  6652.             CASE objcode = c_sgget OR objcode = c_sgedit
  6653.                \\ ,RGB(
  6654.             CASE objcode = c_sgsay
  6655.                \\ RGB(
  6656.             CASE objcode = c_sgfrom
  6657.                \\ ,,,,,,,,RGB(
  6658.             ENDCASE
  6659.  
  6660.          CASE objtype = c_otlist
  6661.             m.ctrlflag = .T.    && remember that this is a control object
  6662.             \\ RGB(
  6663.  
  6664.  
  6665.          CASE objtype = c_ottext OR objtype = c_otscreen OR ;
  6666.                objtype = c_otbox OR objtype = c_otline
  6667.             ** Text, Box, Line, or Screen - color pair 1
  6668.             \\ RGB(
  6669.  
  6670.          OTHERWISE
  6671.             m.ctrlflag = .T.    && remember that this is a control object
  6672.             \\ ,,,,,,,,RGB(
  6673.          ENDCASE
  6674.  
  6675.          IF penred >= 0
  6676.             \\<<Penred>>,<<Pengreen>>,<<Penblue>>,
  6677.          ELSE
  6678.             \\,,,
  6679.          ENDIF
  6680.          IF fillred >= 0
  6681.             \\<<Fillred>>,<<Fillgreen>>,<<Fillblue>>)
  6682.          ELSE
  6683.             \\,,,)
  6684.          ENDIF
  6685.  
  6686.          IF m.ctrlflag AND INLIST(objtype, c_otradbut, c_otchkbox, c_otpopup,c_otlist)
  6687.             * Add one more RGB clause to control the disabled colors for control
  6688.             * objects such as radio buttons, check boxes, popups, etc.
  6689.             \\,RGB(
  6690.             IF penred >= 0
  6691.                \\<<Penred>>,<<Pengreen>>,<<Penblue>>,
  6692.             ELSE
  6693.                \\,,,
  6694.             ENDIF
  6695.             IF fillred >= 0
  6696.                \\<<Fillred>>,<<Fillgreen>>,<<Fillblue>>)
  6697.             ELSE
  6698.                \\,,,)
  6699.             ENDIF
  6700.          ENDIF
  6701.       ENDIF
  6702.    ENDIF
  6703. ENDIF
  6704. RETURN
  6705.  
  6706. *!*****************************************************************************
  6707. *!
  6708. *!      Procedure: ANYPEN
  6709. *!
  6710. *!      Called by: GENBOXES           (procedure in GENSCRN.PRG)
  6711. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6712. *!
  6713. *!*****************************************************************************
  6714. PROCEDURE anypen
  6715. *)
  6716. *) ANYPEN - Place Color Scheme clause if applicable.
  6717. *)
  6718. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6719.    \\ ;
  6720.    \    PEN <<Pensize>>, <<Penpat>>
  6721. ENDIF
  6722. RETURN
  6723.  
  6724. *!*****************************************************************************
  6725. *!
  6726. *!      Procedure: ANYVALID
  6727. *!
  6728. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6729. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6730. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6731. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6732. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6733. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6734. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6735. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6736. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6737. *!
  6738. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6739. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6740. *!
  6741. *!*****************************************************************************
  6742. PROCEDURE anyvalid
  6743. *)
  6744. *) ANYVALID - Place Valid clause if applicable.
  6745. *)
  6746. PRIVATE m.genericname, m.valid
  6747. IF NOT EMPTY(VALID)
  6748.    \\ ;
  6749.    IF validtype = 0
  6750.       m.valid = VALID
  6751.       \    VALID <<stripcr(m.valid)>>
  6752.    ELSE
  6753.       m.genericname = getcname(VALID)
  6754.       \    VALID <<m.genericname>>()
  6755.       DO addtoctrl WITH m.genericname, "VALID", VALID, name
  6756.    ENDIF
  6757. ENDIF
  6758.  
  6759. *!*****************************************************************************
  6760. *!
  6761. *!      Procedure: ANYTITLEORFOOTER
  6762. *!
  6763. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6764. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6765. *!
  6766. *!*****************************************************************************
  6767. PROCEDURE anytitleorfooter
  6768. *)
  6769. *) ANYTITLEORFOOTER - Place Window Title/Footer clause.
  6770. *)
  6771. PRIVATE m.string, m.thetag
  6772. IF NOT EMPTY(TAG)
  6773.    \\ ;
  6774.    m.string = SUBSTR(TAG,2)
  6775.    IF SUBSTR(m.string,1,1) = m.g_itse
  6776.       \    TITLE <<SUBSTR(m.string, 2, RAT('"',m.string)-2)>>
  6777.    ELSE
  6778.       m.thetag = TAG
  6779.       \    TITLE <<m.thetag>>
  6780.    ENDIF
  6781. ENDIF
  6782. IF NOT EMPTY(tag2)
  6783.    \\ ;
  6784.    m.string = SUBSTR(tag2,2)
  6785.    IF SUBSTR(m.string,1,1) = m.g_itse
  6786.       \    FOOTER <<SUBSTR(m.string, 2, RAT('"',m.string)-2)>>
  6787.    ELSE
  6788.       m.thetag = tag2
  6789.       \    FOOTER <<m.thetag>>
  6790.    ENDIF
  6791. ENDIF
  6792. RETURN
  6793.  
  6794.  
  6795. *!*****************************************************************************
  6796. *!
  6797. *!      Procedure: ANYWHEN
  6798. *!
  6799. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6800. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6801. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6802. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6803. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6804. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6805. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6806. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6807. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6808. *!
  6809. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6810. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6811. *!
  6812. *!*****************************************************************************
  6813. PROCEDURE anywhen
  6814. *)
  6815. *) ANYWHEN - Place a When clause in a Get field.
  6816. *)
  6817. PRIVATE m.genericname, m.when
  6818. IF EMPTY(WHEN)
  6819.    RETURN
  6820. ENDIF
  6821. \\ ;
  6822. IF whentype = 0
  6823.    m.when = WHEN
  6824.    \    WHEN <<stripcr(m.when)>>
  6825. ELSE
  6826.    m.genericname = getcname(WHEN)
  6827.    \    WHEN <<m.genericname>>()
  6828.    DO addtoctrl WITH m.genericname, "WHEN", WHEN, name
  6829. ENDIF
  6830. RETURN
  6831.  
  6832. *!*****************************************************************************
  6833. *!
  6834. *!      Procedure: ANYMESSAGE
  6835. *!
  6836. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6837. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6838. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6839. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6840. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6841. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6842. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6843. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6844. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6845. *!
  6846. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6847. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6848. *!
  6849. *!*****************************************************************************
  6850. PROCEDURE anymessage
  6851. *)
  6852. *) ANYMESSAGE - Place a message clause whenever appropriate.
  6853. *)
  6854. PRIVATE m.genericname, m.mess
  6855. IF EMPTY(MESSAGE)
  6856.    RETURN
  6857. ENDIF
  6858. \\ ;
  6859. IF messtype = 0
  6860.    m.mess = MESSAGE
  6861.    \    MESSAGE
  6862.    \\ <<stripcr(m.mess)>>
  6863. ELSE
  6864.    m.genericname = getcname(MESSAGE)
  6865.    \    MESSAGE <<m.genericname>>()
  6866.    DO addtoctrl WITH m.genericname, "MESSAGE", MESSAGE, name
  6867. ENDIF
  6868. RETURN
  6869.  
  6870. *!*****************************************************************************
  6871. *!
  6872. *!      Procedure: ANYERROR
  6873. *!
  6874. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6875. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6876. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6877. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6878. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6879. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6880. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6881. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6882. *!
  6883. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6884. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6885. *!
  6886. *!*****************************************************************************
  6887. PROCEDURE anyerror
  6888. *)
  6889. *) ANYERROR - Place an error clause whenever appropriate.
  6890. *)
  6891. PRIVATE m.genericname, m.err
  6892. IF EMPTY(ERROR)
  6893.    RETURN
  6894. ENDIF
  6895. \\ ;
  6896. IF errortype = 0
  6897.    m.err = ERROR
  6898.    \    ERROR
  6899.    \\ <<stripcr(m.err)>>
  6900. ELSE
  6901.    m.genericname = getcname(ERROR)
  6902.    \    ERROR <<m.genericname>>()
  6903.    DO addtoctrl WITH m.genericname, "ERROR", ERROR, name
  6904. ENDIF
  6905. RETURN
  6906.  
  6907. *!*****************************************************************************
  6908. *!
  6909. *!      Procedure: ANYFILL
  6910. *!
  6911. *!*****************************************************************************
  6912. PROCEDURE anyfill
  6913. *)
  6914. *) ANYFILL - Place the Fill clause whenever appropriate.
  6915. *)
  6916. IF fillchar <> c_null
  6917.    \\ ;
  6918.    \    FILL "<<Fillchar>>"
  6919. ENDIF
  6920. RETURN
  6921.  
  6922. *!*****************************************************************************
  6923. *!
  6924. *!      Procedure: ANYWINDOWCHARS
  6925. *!
  6926. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6927. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6928. *!
  6929. *!*****************************************************************************
  6930. PROCEDURE anywindowchars
  6931. *)
  6932. *) ANYWINDOWCHARS - Place window characteristics options.
  6933. *)
  6934. *) Description:
  6935. *) Place the FLOAT, GROW, CLOSE, ZOOM, SHADOW, and MINIMIZE clauses
  6936. *) for a window painted by the user.
  6937. *)
  6938. \\ ;
  6939. \    <<IIF(Float, "FLOAT ;", "NOFLOAT ;")>>
  6940. \    <<IIF(Close, "CLOSE", "NOCLOSE")>>
  6941. IF SHADOW
  6942.    \\ ;
  6943.    \    SHADOW
  6944. ENDIF
  6945. IF m.g_genvers <> "MAC"
  6946.     IF MINIMIZE
  6947.        \\ ;
  6948.        \    MINIMIZE
  6949.     ELSE
  6950.        \\ ;
  6951.        \    NOMINIMIZE
  6952.     ENDIF
  6953. ENDIF
  6954. RETURN
  6955.  
  6956. *!*****************************************************************************
  6957. *!
  6958. *!      Procedure: ANYBORDER
  6959. *!
  6960. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6961. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6962. *!
  6963. *!*****************************************************************************
  6964. PROCEDURE anyborder
  6965. *)
  6966. *) ANYBORDER - Place Border type clause on a box.
  6967. *)
  6968. *) Description:
  6969. *) Place border type clause on a box depending on the setting of
  6970. *) the field Border.
  6971. *)
  6972. IF BORDER<>1
  6973.    \\ ;
  6974. ENDIF
  6975.  
  6976. DO CASE
  6977. CASE BORDER = 0
  6978.    \    NONE
  6979. CASE BORDER = 2
  6980.    \    DOUBLE
  6981. CASE BORDER = 3
  6982.    \    PANEL
  6983. CASE BORDER = 4
  6984.    \    SYSTEM
  6985. ENDCASE
  6986. RETURN
  6987.  
  6988. *!*****************************************************************************
  6989. *!
  6990. *!      Procedure: ANYWALLPAPER
  6991. *!
  6992. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6993. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6994. *!
  6995. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6996. *!
  6997. *!*****************************************************************************
  6998. PROCEDURE anywallpaper
  6999. *)
  7000. *) ANYWALLPAPER - Place FILL FILE clause on any window.
  7001. *)
  7002. IF !EMPTY(PICTURE)
  7003.    m.relpath = findrelpath(SUBSTR(PICTURE, 2, LEN(PICTURE) - 2))
  7004.     IF !EMPTY(basename(m.relpath))
  7005.       \\ ;
  7006.       \    FILL FILE LOCFILE("<<m.relpath>>",<<bitmapstr(c_all)>>, ;
  7007.       \        "Where is <<LOWER(basename(m.relpath))>>?")
  7008.    ENDIF
  7009. ENDIF
  7010. RETURN
  7011.  
  7012. *!*****************************************************************************
  7013. *!
  7014. *!      Procedure: ANYICON
  7015. *!
  7016. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  7017. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  7018. *!
  7019. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  7020. *!
  7021. *!*****************************************************************************
  7022. PROCEDURE anyicon
  7023. *)
  7024. *) ANYICON - Place ICON FILE clause on any window.
  7025. *)
  7026. IF !EMPTY(ORDER) AND ORDER <> '""'
  7027.    m.relpath = findrelpath(SUBSTR(ORDER, 2, LEN(ORDER) - 2))
  7028.     IF !EMPTY(basename(m.relpath))
  7029.       \\ ;
  7030.       \    ICON FILE LOCFILE("<<m.relpath>>","<<iconstr()>>", ;
  7031.       \        "Where is <<LOWER(basename(m.relpath))>>?")
  7032.    ENDIF
  7033. ENDIF
  7034. RETURN
  7035.  
  7036. *!*****************************************************************************
  7037. *!
  7038. *!      Procedure: WINDOWFROMTO
  7039. *!
  7040. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  7041. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  7042. *!
  7043. *!*****************************************************************************
  7044. PROCEDURE windowfromto
  7045. *)
  7046. *) WINDOWFROMTO - Place FROM...TO clause on any window.
  7047. *)
  7048. *) Description:
  7049. *) Place FROM...TO clause on any window designed in the screen
  7050. *) painter.  If window is to be centered, then adjust the coordinates
  7051. *) accordingly.
  7052. *)
  7053. PARAMETER m.xcoord, m.ycoord
  7054. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  7055.    SET DECIMALS TO 3
  7056. ENDIF
  7057. IF PARAMETERS() = 0
  7058.    IF CENTER
  7059.       IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  7060.          \    AT  <<Vpos>>, <<Hpos>>  ;
  7061.          \    SIZE <<Height>>,<<Width>>
  7062.       ELSE
  7063.          \    FROM INT((SROW()-<<Height>>)/2),
  7064.          \\INT((SCOL()-<<Width>>)/2) ;
  7065.          \    TO INT((SROW()-<<Height>>)/2)+<<Height-1>>,
  7066.          \\INT((SCOL()-<<Width>>)/2)+<<Width-1>>
  7067.       ENDIF
  7068.    ELSE
  7069.       IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  7070.          \    AT <<Vpos>>, <<Hpos>> ;
  7071.          \    SIZE <<Height>>,<<Width>>
  7072.       ELSE
  7073.          \    FROM <<Vpos>>, <<Hpos>> ;
  7074.          \    TO <<Height+Vpos-1>>,<<Width+Hpos-1>>
  7075.       ENDIF
  7076.    ENDIF
  7077. ELSE
  7078.    IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  7079.       \    AT <<m.xcoord>>, <<m.ycoord>> ;
  7080.       \    SIZE <<Height>>,<<Width>>
  7081.    ELSE
  7082.       \    FROM <<m.xcoord>>, <<m.ycoord>> ;
  7083.       \    TO <<Height+m.xcoord-1>>,<<Width+m.ycoord-1>>
  7084.    ENDIF
  7085. ENDIF
  7086. SET DECIMALS TO 0
  7087. RETURN
  7088.  
  7089. **
  7090. ** Code Generating Documentation in Control and Format files.
  7091. **
  7092.  
  7093. *!*****************************************************************************
  7094. *!
  7095. *!      Procedure: HEADER
  7096. *!
  7097. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  7098. *!
  7099. *!*****************************************************************************
  7100. PROCEDURE HEADER
  7101. *)
  7102. *) HEADER - Generate application program's header.
  7103. *)
  7104. *) Description:
  7105. *) As a part of the application's header generate program name, name
  7106. *) of the author of the program, copyright notice, company name and
  7107. *) address, and the word 'Description:' which will be followed with
  7108. *) the application description generated by a separate procedure.
  7109. *)
  7110. IF LEN(_PRETEXT) <> 0
  7111.    \
  7112. ENDIF
  7113. \\*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7114. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7115. \*       <<m.g_verti1>> <<DATE()>>
  7116. \\<<PADC(UPPER(ALLTRIM(strippath(m.g_outfile))),IIF(SET("CENTURY")="ON",35,37))," ")>>
  7117. \\  <<TIME()>> <<m.g_verti2>>
  7118. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7119. \*       <<m.g_corn5>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn6>>
  7120. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7121. \*       <<m.g_verti1>> <<m.g_devauthor>>
  7122. \\<<SAFEREPL(" ",56-LEN(m.g_devauthor))>><<m.g_verti2>>
  7123. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7124. \*       <<m.g_verti1>>
  7125. \\ Copyright (c) <<YEAR(DATE())>>
  7126. IF LEN(ALLTRIM(m.g_devcompany)) <= 36
  7127.    \\ <<ALLTRIM(m.g_devcompany)>>
  7128.    \\<<SAFEREPL(" ",37-LEN(ALLTRIM(m.g_devcompany)))>>
  7129.    \\<<m.g_verti2>>
  7130. ELSE
  7131.    \\ <<SAFEREPL(" ",37)>><<m.g_verti2>>
  7132.    \*       <<m.g_verti1>> <<m.g_devcompany>>
  7133.    \\<<SAFEREPL(" ",56-LEN(m.g_devcompany))>><<m.g_verti2>>
  7134. ENDIF
  7135. \*       <<m.g_verti1>> <<m.g_devaddress>>
  7136. \\<<SAFEREPL(" ",56-LEN(m.g_devaddress))>><<m.g_verti2>>
  7137.  
  7138. \*       <<m.g_verti1>> <<ALLTRIM(m.g_devcity)>>, <<m.g_devstate>>
  7139. \\  <<ALLTRIM(m.g_devzip)>>
  7140. \\<<SAFEREPL(" ",50-(LEN(ALLTRIM(m.g_devcity)+ALLTRIM(m.g_devzip))))>>
  7141. \\<<m.g_verti2>>
  7142.  
  7143. IF !INLIST(ALLTRIM(UPPER(m.g_devctry)),"USA","COUNTRY") AND !EMPTY(m.g_devctry)
  7144.    \*       <<m.g_verti1>> <<ALLTRIM(m.g_devctry)>>
  7145.    \\<<SAFEREPL(" ",50-(LEN(ALLTRIM(m.g_devctry))))>>
  7146.    \\<<m.g_verti2>>
  7147. ENDIF
  7148.  
  7149. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7150. \*       <<m.g_verti1>> Description:
  7151. \\                                            <<m.g_verti2>>
  7152. \*       <<m.g_verti1>>
  7153. \\ This program was automatically generated by GENSCRN.
  7154. \\    <<m.g_verti2>>
  7155. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7156. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7157. \
  7158. RETURN
  7159.  
  7160. *!*****************************************************************************
  7161. *!
  7162. *!      Procedure: GENFUNCHEADER
  7163. *!
  7164. *!      Called by: VALICLAUSE         (procedure in GENSCRN.PRG)
  7165. *!               : WHENCLAUSE         (procedure in GENSCRN.PRG)
  7166. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7167. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7168. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7169. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  7170. *!
  7171. *!*****************************************************************************
  7172. PROCEDURE genfuncheader
  7173. *)
  7174. *) GENFUNCHEADER - Generate Comment for Function/Procedure.
  7175. *)
  7176. PARAMETER m.procname, m.from, m.readlevel, m.varname
  7177. m.g_snippcnt = m.g_snippcnt + 1
  7178. \
  7179. \*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7180. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7181. IF m.readlevel
  7182.    \*       <<m.g_verti1>>
  7183.    \\ <<UPPER(m.procname)>>           <<m.from>>
  7184.    \\<<SAFEREPL(" ",45-LEN(m.procname+m.from))>><<m.g_verti2>>
  7185. ELSE
  7186.    \*       <<m.g_verti1>>
  7187.    \\ <<UPPER(m.procname)>>           <<m.varname>> <<m.from>>
  7188.    \\<<SAFEREPL(" ",44-LEN(m.procname+m.varname+m.from))>><<m.g_verti2>>
  7189. ENDIF
  7190. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7191. \*       <<m.g_verti1>> Function Origin:
  7192. \\<<SAFEREPL(" ",40)>><<m.g_verti2>>
  7193. IF m.readlevel
  7194.    \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7195.    \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7196.    \*       <<m.g_verti1>> From Platform:
  7197.    \\       <<VersionCap(m.g_genvers, .F.)>>
  7198.    \\<<SAFEREPL(" ",35-LEN(VersionCap(m.g_genvers, .F.)))>>
  7199.    \\<<m.g_verti2>>
  7200.    \*       <<m.g_verti1>> From Screen:
  7201.    IF m.g_nscreens > 1 AND NOT m.g_multread
  7202.       \\         Multiple Screens
  7203.       \\<<SAFEREPL(" ",19)>><<m.g_verti2>>
  7204.    ELSE
  7205.       \\         <<basename(SYS(2014,DBF()))>>
  7206.       \\<<SAFEREPL(" ",35-LEN(basename(SYS(2014,DBF()))))>>
  7207.       \\<<m.g_verti2>>
  7208.    ENDIF
  7209.    \*       <<m.g_verti1>> Called By:           READ Statement
  7210.    \\<<SAFEREPL(" ",21)>><<m.g_verti2>>
  7211.    \*       <<m.g_verti1>> Snippet Number:
  7212.    \\      <<ALLTRIM(STR(m.g_snippcnt,2))>>
  7213.    \\<<SAFEREPL(" ",35-LEN(ALLTRIM(STR(m.g_snippcnt,2))))>><<m.g_verti2>>
  7214.    \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7215.    \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7216.    \*
  7217.    RETURN
  7218. ENDIF
  7219. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7220. \*       <<m.g_verti1>> From Platform:
  7221. \\       <<VersionCap(m.g_genvers, .F.)>>
  7222. \\<<SAFEREPL(" ",35-LEN(VersionCap(m.g_genvers, .F.)))>>
  7223. \\<<m.g_verti2>>
  7224. \*       <<m.g_verti1>> From Screen:
  7225. \\         <<basename(SYS(2014,DBF()))>>
  7226. \\,     Record Number:  <<STR(RECNO(),3)>>
  7227. \\<<SAFEREPL(" ",10-LEN(basename(SYS(2014,DBF())+STR(RECNO(),3))))>>
  7228. \\<<m.g_verti2>>
  7229. IF NOT EMPTY(m.varname)
  7230.    \*       <<m.g_verti1>> Variable:            <<m.varname>>
  7231.    \\<<SAFEREPL(" ",35-LEN(m.varname))>><<m.g_verti2>>
  7232. ENDIF
  7233. \*       <<m.g_verti1>> Called By:           <<m.from+" Clause">>
  7234. \\<<SAFEREPL(" ",35-LEN(m.from+" Clause"))>><<m.g_verti2>>
  7235. IF OBJECT(objtype) <> ""
  7236.    \*       <<m.g_verti1>> Object Type:
  7237.    \\         <<Object(Objtype)>>
  7238.    \\<<SAFEREPL(" ",35-LEN(Object(Objtype)))>><<m.g_verti2>>
  7239. ENDIF
  7240. \*       <<m.g_verti1>> Snippet Number:
  7241. \\      <<ALLTRIM(STR(m.g_snippcnt,3))>>
  7242. \\<<SAFEREPL(" ",35-LEN(ALLTRIM(STR(m.g_snippcnt,3))))>><<m.g_verti2>>
  7243. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7244. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7245. \*
  7246. RETURN
  7247.  
  7248. *!*****************************************************************************
  7249. *!
  7250. *!      Procedure: COMMENTBLOCK
  7251. *!
  7252. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  7253. *!               : PUTPROCHEAD        (procedure in GENSCRN.PRG)
  7254. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  7255. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  7256. *!               : GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  7257. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  7258. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  7259. *!               : PLACEREAD          (procedure in GENSCRN.PRG)
  7260. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  7261. *!
  7262. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  7263. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  7264. *!
  7265. *!*****************************************************************************
  7266. PROCEDURE commentblock
  7267. *)
  7268. *) COMMENTBLOCK - Generate a comment block.
  7269. *)
  7270. PARAMETER m.dbalias, m.string
  7271. PRIVATE m.msg
  7272. IF !EMPTY(basename(m.dbalias))
  7273.    m.msg = basename(m.dbalias)+"/"+versioncap(m.g_genvers, .F.)+m.string
  7274. ELSE
  7275.    m.msg = versioncap(m.g_genvers, .F.)+m.string
  7276. ENDIF
  7277. \
  7278. \*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7279. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7280. \*       <<m.g_verti1>>
  7281. \\ <<PADC(m.msg,55," ")>>
  7282. \\ <<m.g_verti2>>
  7283. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7284. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7285. \*
  7286. \
  7287.  
  7288. *!*****************************************************************************
  7289. *!
  7290. *!      Procedure: PROCCOMMENTBLOCK
  7291. *!
  7292. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  7293. *!
  7294. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  7295. *!
  7296. *!*****************************************************************************
  7297. PROCEDURE proccommentblock
  7298. *)
  7299. *) PROCCOMMENTBLOCK - Generate a procedure comment block.
  7300. *)
  7301. PARAMETER m.dbalias, m.string
  7302. PRIVATE m.msg
  7303. m.msg = basename(m.dbalias)+m.string
  7304. \
  7305. \*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7306. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7307. \*       <<m.g_verti1>>
  7308. \\ <<PADC(m.msg,55," ")>>
  7309. \\ <<m.g_verti2>>
  7310. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7311. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7312. \*
  7313. \
  7314. RETURN
  7315.  
  7316. *!*****************************************************************************
  7317. *!
  7318. *!      Procedure: GENCOMMENT
  7319. *!
  7320. *!      Called by: GENVALIDBODY       (procedure in GENSCRN.PRG)
  7321. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7322. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7323. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7324. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7325. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  7326. *!
  7327. *!*****************************************************************************
  7328. PROCEDURE gencomment
  7329. *)
  7330. *) GENCOMMENT - Generate a comment.
  7331. *)
  7332. PARAMETER m.msg
  7333. \*
  7334. \* <<m.msg>>
  7335. \*
  7336.  
  7337. *!*****************************************************************************
  7338. *!
  7339. *!      Procedure: SAFEREPL
  7340. *!
  7341. *!*****************************************************************************
  7342. FUNCTION saferepl
  7343. * REPLICATE shell
  7344. PARAMETER m.strg, m.num
  7345. RETURN REPLICATE(m.strg, max(m.num, 0))
  7346.  
  7347. **
  7348. ** General Supporting Routines
  7349. **
  7350.  
  7351. *!*****************************************************************************
  7352. *!
  7353. *!       Function: BASENAME
  7354. *!
  7355. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  7356. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  7357. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7358. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7359. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7360. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7361. *!               : GENRELSTMTS        (procedure in GENSCRN.PRG)
  7362. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  7363. *!               : PROCCOMMENTBLOCK   (procedure in GENSCRN.PRG)
  7364. *!
  7365. *!          Calls: STRIPPATH()        (function  in GENSCRN.PRG)
  7366. *!               : STRIPEXT()         (function  in GENSCRN.PRG)
  7367. *!
  7368. *!*****************************************************************************
  7369. FUNCTION basename
  7370. PARAMETER m.filename
  7371. RETURN strippath(stripext(m.filename))
  7372.  
  7373. *!*****************************************************************************
  7374. *!
  7375. *!       Function: STRIPEXT
  7376. *!
  7377. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  7378. *!               : BASENAME()         (function  in GENSCRN.PRG)
  7379. *!
  7380. *!*****************************************************************************
  7381. FUNCTION stripext
  7382. *)
  7383. *) STRIPEXT - Strip the extension from a file name.
  7384. *)
  7385. *) Description:
  7386. *) Use the algorithm employed by FoxPRO itself to strip a
  7387. *) file of an extension (if any): Find the rightmost dot in
  7388. *) the filename.  If this dot occurs to the right of a "\"
  7389. *) or ":", then treat everything from the dot rightward
  7390. *) as an extension.  Of course, if we found no dot,
  7391. *) we just hand back the filename unchanged.
  7392. *)
  7393. *) Parameters:
  7394. *) filename - character string representing a file name
  7395. *)
  7396. *) Return value:
  7397. *) The string "filename" with any extension removed
  7398. *)
  7399. PARAMETER m.filename
  7400. PRIVATE m.dotpos, m.terminator
  7401. m.dotpos = RAT(".", m.filename)
  7402. m.terminator = MAX(RAT("\", m.filename), RAT(":", m.filename))
  7403. IF m.dotpos > m.terminator
  7404.    m.filename = LEFT(m.filename, m.dotpos-1)
  7405. ENDIF
  7406. RETURN m.filename
  7407.  
  7408. *!*****************************************************************************
  7409. *!
  7410. *!       Function: STRIPPATH
  7411. *!
  7412. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  7413. *!               : BASENAME()         (function  in GENSCRN.PRG)
  7414. *!
  7415. *!*****************************************************************************
  7416. FUNCTION strippath
  7417. *)
  7418. *) STRIPPATH - Strip the path from a file name.
  7419. *)
  7420. *) Description:
  7421. *) Find positions of backslash in the name of the file.  If there is one
  7422. *) take everything to the right of its position and make it the new file
  7423. *) name.  If there is no slash look for colon.  Again if found, take
  7424. *) everything to the right of it as the new name.  If neither slash
  7425. *) nor colon are found then return the name unchanged.
  7426. *)
  7427. *) Parameters:
  7428. *) filename - character string representing a file name
  7429. *)
  7430. *) Return value:
  7431. *) The string "filename" with any path removed
  7432. *)
  7433. PARAMETER m.filename
  7434. PRIVATE m.slashpos, m.namelen, m.colonpos
  7435. m.slashpos = RAT("\", m.filename)
  7436. IF m.slashpos > 0
  7437.    m.namelen  = LEN(m.filename) - m.slashpos
  7438.    m.filename = RIGHT(m.filename, m.namelen)
  7439. ELSE
  7440.    m.colonpos = RAT(":", m.filename)
  7441.    IF m.colonpos > 0
  7442.       m.namelen  = LEN(m.filename) - m.colonpos
  7443.       m.filename = RIGHT(m.filename, m.namelen)
  7444.    ENDIF
  7445. ENDIF
  7446. RETURN m.filename
  7447.  
  7448. *!*****************************************************************************
  7449. *!
  7450. *!       Function: STRIPCR
  7451. *!
  7452. *!*****************************************************************************
  7453. FUNCTION stripcr
  7454. *)
  7455. *) STRIPCR - Strip off terminating carriage returns and line feeds
  7456. *)
  7457. PARAMETER m.strg
  7458. * Don't use a CHRTRAN since it's remotely possible that the CR or LF might
  7459. * be in a user's quoted string.
  7460. strg = ALLTRIM(strg)
  7461. i = LEN(strg)
  7462. DO WHILE i >= 0 AND INLIST(SUBSTR(strg,i,1),CHR(13),CHR(10))
  7463.    i = i - 1
  7464. ENDDO
  7465. RETURN LEFT(strg,i)
  7466.  
  7467. *!*****************************************************************************
  7468. *!
  7469. *!       Function: ADDBS
  7470. *!
  7471. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7472. *!
  7473. *!*****************************************************************************
  7474. FUNCTION addbs
  7475. *)
  7476. *) ADDBS - Add a backslash unless there is one already there.
  7477. *)
  7478. PARAMETER m.pathname
  7479. PRIVATE m.separator
  7480. m.separator = IIF(_MAC,":","\")
  7481. m.pathname = ALLTRIM(UPPER(m.pathname))
  7482. IF !(RIGHT(m.pathname,1) $ '\:') AND !EMPTY(m.pathname)
  7483.    m.pathname = m.pathname + m.separator
  7484. ENDIF
  7485. RETURN m.pathname
  7486.  
  7487. *!*****************************************************************************
  7488. *!
  7489. *!       Function: JUSTFNAME
  7490. *!
  7491. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7492. *!
  7493. *!*****************************************************************************
  7494. FUNCTION justfname
  7495. *)
  7496. *) JUSTFNAME - Return just the filename (i.e., no path) from "filname"
  7497. *)
  7498. PARAMETERS m.filname
  7499. IF RAT('\',m.filname) > 0
  7500.    m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
  7501. ENDIF
  7502. IF AT(':',m.filname) > 0
  7503.    m.filname = SUBSTR(m.filname,AT(':',m.filname)+1,255)
  7504. ENDIF
  7505. RETURN ALLTRIM(UPPER(m.filname))
  7506.  
  7507. *!*****************************************************************************
  7508. *!
  7509. *!       Function: JUSTSTEM
  7510. *!
  7511. *!*****************************************************************************
  7512. FUNCTION juststem
  7513. * Return just the stem name from "filname"
  7514. PARAMETERS m.filname
  7515. IF RAT('\',m.filname) > 0
  7516.    m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
  7517. ENDIF
  7518. IF RAT(':',m.filname) > 0
  7519.    m.filname = SUBSTR(m.filname,RAT(':',m.filname)+1,255)
  7520. ENDIF
  7521. IF AT('.',m.filname) > 0
  7522.    m.filname = SUBSTR(m.filname,1,AT('.',m.filname)-1)
  7523. ENDIF
  7524. RETURN ALLTRIM(UPPER(m.filname))
  7525.  
  7526. *!*****************************************************************************
  7527. *!
  7528. *!       Function: JUSTPATH
  7529. *!
  7530. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7531. *!
  7532. *!*****************************************************************************
  7533. FUNCTION justpath
  7534. *)
  7535. *) JUSTPATH - Returns just the pathname.
  7536. *)
  7537. PARAMETERS m.filname
  7538. m.filname = ALLTRIM(UPPER(m.filname))
  7539. IF '\' $ m.filname
  7540.    m.filname = SUBSTR(m.filname,1,RAT('\',m.filname))
  7541.    IF RIGHT(m.filname,1) = '\' AND LEN(m.filname) > 1 ;
  7542.             AND SUBSTR(m.filname,LEN(m.filname)-1,1) <> ':'
  7543.          filname = SUBSTR(m.filname,1,LEN(m.filname)-1)
  7544.    ENDIF
  7545.    RETURN m.filname
  7546. ELSE
  7547.    RETURN ''
  7548. ENDIF
  7549.  
  7550.  
  7551. *!*****************************************************************************
  7552. *!
  7553. *!       Function: JUSTEXT
  7554. *!
  7555. *!*****************************************************************************
  7556. FUNCTION justext
  7557. * Return just the extension from "filname"
  7558. PARAMETERS m.filname
  7559. PRIVATE m.ext
  7560. filname = justfname(m.filname)   && prevents problems with ..\ paths
  7561. m.ext = ""
  7562. IF AT('.',m.filname) > 0
  7563.    m.ext = SUBSTR(m.filname,AT('.',m.filname)+1,3)
  7564. ENDIF
  7565. RETURN UPPER(m.ext)
  7566.  
  7567. *!*****************************************************************************
  7568. *!
  7569. *!       Function: FORCEEXT
  7570. *!
  7571. *!          Calls: JUSTPATH()         (function  in GENSCRN.PRG)
  7572. *!               : JUSTFNAME()        (function  in GENSCRN.PRG)
  7573. *!               : ADDBS()            (function  in GENSCRN.PRG)
  7574. *!
  7575. *!*****************************************************************************
  7576. FUNCTION forceext
  7577. *)
  7578. *) FORCEEXT - Force filename to have a particular extension.
  7579. *)
  7580. PARAMETERS m.filname,m.ext
  7581. PRIVATE m.ext
  7582. IF SUBSTR(m.ext,1,1) = "."
  7583.    m.ext = SUBSTR(m.ext,2,3)
  7584. ENDIF
  7585.  
  7586. m.pname = justpath(m.filname)
  7587. m.filname = justfname(UPPER(ALLTRIM(m.filname)))
  7588. IF AT('.',m.filname) > 0
  7589.    m.filname = SUBSTR(m.filname,1,AT('.',m.filname)-1) + '.' + m.ext
  7590. ELSE
  7591.    m.filname = m.filname + '.' + m.ext
  7592. ENDIF
  7593. RETURN addbs(m.pname) + m.filname
  7594.  
  7595. *!*****************************************************************************
  7596. *!
  7597. *!       Function: UNIQUEWIN
  7598. *!
  7599. *!      Called by: GENWINDEFI         (procedure in GENSCRN.PRG)
  7600. *!
  7601. *!*****************************************************************************
  7602. FUNCTION uniquewin
  7603. *)
  7604. *) UNIQUEWIN - Check if a window name is unique.
  7605. *)
  7606. PARAMETER m.windowname, m.windcnt, m.arry
  7607. EXTERNAL ARRAY arry
  7608. PRIVATE m.found, m.i, m.first, m.middle
  7609. m.found  = .F.
  7610. m.first  = 1
  7611. m.last   = m.windcnt
  7612. m.middle = 0
  7613.  
  7614. IF EMPTY(arry[1,1])
  7615.    RETURN 1
  7616. ENDIF
  7617. DO WHILE (m.last >= m.first) AND NOT m.found
  7618.    m.middle = INT((m.first+m.last) / 2)
  7619.    DO CASE
  7620.    CASE m.windowname < arry[m.middle,1]
  7621.       m.last = m.middle - 1
  7622.    CASE m.windowname > arry[m.middle,1]
  7623.       m.first = m.middle + 1
  7624.    OTHERWISE
  7625.       m.found = .T.
  7626.    ENDCASE
  7627. ENDDO
  7628. IF m.found
  7629.    RETURN 0
  7630. ELSE
  7631.    RETURN m.first
  7632. ENDIF
  7633. RETURN
  7634.  
  7635. *!*****************************************************************************
  7636. *!
  7637. *!      Procedure: ADDTOCTRL
  7638. *!
  7639. *!      Called by: ELEMRANGE          (procedure in GENSCRN.PRG)
  7640. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  7641. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  7642. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  7643. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  7644. *!
  7645. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  7646. *!               : GENFUNCHEADER      (procedure in GENSCRN.PRG)
  7647. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  7648. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  7649. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  7650. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  7651. *!
  7652. *!*****************************************************************************
  7653. PROCEDURE addtoctrl
  7654. *)
  7655. *) ADDTOCTRL - Generate clause code for object level cluses.
  7656. *)
  7657. PARAMETER m.procname, m.from, m.memo, m.varname
  7658. PRIVATE m.linecnt, m.count, m.textline, m.genfunction, m.notcomnt, m.at, ;
  7659.    m.thispretext, m.in_dec, m.platnum, m.wnamelen, m.upline, m.thisplat
  7660.  
  7661. m.thisplat = IIF(TYPE("platform") <> "U",platform,"DOS")
  7662. m.platnum = getplatnum(m.thisplat)
  7663.  
  7664. * Write this clause to the temporary file
  7665. _TEXT = m.g_tmphandle
  7666. m.thispretext = _PRETEXT
  7667. _PRETEXT = ""
  7668.  
  7669. m.genfunction = .F.
  7670. m.notcomnt = 0
  7671. m.linecnt = MEMLINES(m.memo)
  7672. _MLINE = 0
  7673. DO genfuncheader WITH m.procname, m.from, .F., ALLTRIM(m.varname)
  7674. FOR m.count = 1 TO m.linecnt
  7675.    m.textline = MLINE(m.memo, 1, _MLINE)
  7676.    DO killcr WITH m.textline
  7677.    m.upline = UPPER(LTRIM(CHRTRAN(m.textline,chr(9),' ')))
  7678.    IF oktogenerate(@upline, @notcomnt)
  7679.       IF m.notcomnt > 0 AND NOT m.genfunction
  7680.          \FUNCTION <<m.procname>>     &&  <<m.varname>> <<m.from>>
  7681.          in_dec = SET("DECIMALS")
  7682.          SET DECIMALS TO 0
  7683.          \#REGION <<INT(m.g_screen)>>
  7684.          SET DECIMALS TO in_dec
  7685.          m.genfunction = .T.
  7686.       ENDIF
  7687.  
  7688.       IF NOT EMPTY(g_wnames[m.g_screen, m.platnum])
  7689.          m.at = atwname(g_wnames[m.g_screen, m.platnum], m.textline)
  7690.          IF m.at <> 0 AND !iscomment(@textline)
  7691.             m.wnamelen = LEN(g_wnames[m.g_screen, m.platnum])
  7692.             \<<STUFF(m.textline, m.at, m.wnamelen,g_screens[m.g_screen,2])>>
  7693.          ELSE
  7694.             IF !geninsertcode(@upline,m.g_screen, .F., m.thisplat)
  7695.                \<<m.textline>>
  7696.             ENDIF
  7697.          ENDIF
  7698.       ELSE
  7699.          IF !geninsertcode(@upline,m.g_screen, .F., m.thisplat)
  7700.             \<<m.textline>>
  7701.          ENDIF
  7702.       ENDIF
  7703.    ENDIF
  7704. ENDFOR
  7705. IF m.notcomnt = 0
  7706.    \FUNCTION <<m.procname>>     &&  <<m.varname>> <<m.from>>
  7707. ENDIF
  7708. _TEXT = m.g_orghandle
  7709. _PRETEXT = m.thispretext
  7710. RETURN
  7711.  
  7712. *!*****************************************************************************
  7713. *!
  7714. *!       Function: OKTOGENERATE
  7715. *!
  7716. *!      Called by: ADDTOCTRL          (procedure in GENSCRN.PRG)
  7717. *!
  7718. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  7719. *!               : MATCH()            (function  in GENSCRN.PRG)
  7720. *!
  7721. *!*****************************************************************************
  7722. FUNCTION oktogenerate
  7723. *)
  7724. *) OKTOGENERATE - Ok to generate this line?
  7725. *)
  7726. *) Description:
  7727. *) Check if the code segment provided by the user for the object level
  7728. *) VALID, MESSAGE, and WHEN clauses does not contain 'FUNCTION',
  7729. *) 'PROCEDURE' or 'PARAMETER' statements as its first non-comment
  7730. *) statements.  Further, do not output #NAME directives. This is done on line by
  7731. *) line basis.
  7732. *)
  7733. *) "notcomnt" needs to be passed by reference, and is changed in this module
  7734. *) m.statement must already be in upper case and trimmed.  It may be passed by reference.
  7735. PARAMETER m.statement, m.notcomnt
  7736.  
  7737. PRIVATE m.asterisk, m.ampersand, m.isnote, m.name, m.word1
  7738. IF EMPTY(m.statement)
  7739.    RETURN .T.
  7740. ENDIF
  7741.  
  7742. DO CASE
  7743. CASE AT("*", m.statement) = 1 ;
  7744.       OR AT(m.g_dblampersand, m.statement) = 1 ;
  7745.       OR AT("NOTE", m.statement) = 1
  7746.    RETURN .T.
  7747. OTHERWISE
  7748.    * OK, it's not a comment
  7749.    m.notcomnt = m.notcomnt + 1
  7750.    * Make a quick test to see if we may exclude this line
  7751.    IF AT(LEFT(statement,1),"PF#") > 0
  7752.       * Postpone the expensive wordnum and match functions as long as possible
  7753.       word1 = CHRTRAN(wordnum(statement,1),';','')
  7754.       DO CASE
  7755.       CASE match(word1,"PROCEDURE") OR match(word1,"FUNCTION") OR match(word1,"PARAMETERS")
  7756.          *
  7757.          * If the first non-comment line is a FUNCTION, PROCEDURE, or
  7758.          * a PARAMETER statement then do not generate it.
  7759.          *
  7760.          IF m.notcomnt = 1
  7761.             RETURN .F.
  7762.          ENDIF
  7763.       CASE LEFT(statement,5) == "#NAME"   && Don't ever emit a #NAME directive
  7764.          RETURN .F.
  7765.       ENDCASE
  7766.    ENDIF
  7767. ENDCASE
  7768. RETURN .T.
  7769.  
  7770. *!*****************************************************************************
  7771. *!
  7772. *!       Function: OBJECT
  7773. *!
  7774. *!*****************************************************************************
  7775. FUNCTION OBJECT
  7776. *)
  7777. *) OBJECT - Return name of an object.
  7778. *)
  7779. PARAMETER m.objecttype
  7780. PRIVATE m.objname
  7781. DO CASE
  7782. CASE m.objecttype = 11
  7783.    m.objname = "List"
  7784. CASE m.objecttype = 12
  7785.    m.objname = "Push Button"
  7786. CASE m.objecttype = 13
  7787.    m.objname = "Radio Button"
  7788. CASE m.objecttype = 14
  7789.    m.objname = "Check Box"
  7790. CASE m.objecttype = 15
  7791.    m.objname = "Field"
  7792. CASE m.objecttype = 16
  7793.    m.objname = "Popup"
  7794. OTHERWISE
  7795.    m.objname = ""
  7796. ENDCASE
  7797. RETURN m.objname
  7798.  
  7799. *!*****************************************************************************
  7800. *!
  7801. *!      Procedure: COMBINE
  7802. *!
  7803. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7804. *!
  7805. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  7806. *!
  7807. *!*****************************************************************************
  7808. PROCEDURE combine
  7809. *)
  7810. *) COMBINE - Combine the original and the temp files.
  7811. *)
  7812. PRIVATE m.size, m.top, m.end, m.status, m.chunk
  7813.  
  7814. IF m.g_graphic
  7815.    SET MESSAGE TO 'Merging Files'
  7816. ENDIF
  7817. m.size = FSEEK(m.g_tmphandle,0,2)
  7818. m.top  = FSEEK(m.g_tmphandle,0)
  7819.  
  7820. DO WHILE .T.
  7821.    m.chunk = IIF(m.size>65000, 65000, m.size)
  7822.    m.end   = FSEEK(m.g_orghandle,0,2)
  7823.    m.status = FWRITE(m.g_orghandle,FREAD(m.g_tmphandle,m.chunk))
  7824.    IF m.status = 0 AND m.size > 0
  7825.       DO errorhandler WITH "Unsuccessful file merge...",;
  7826.          LINENO(), c_error_2
  7827.    ENDIF
  7828.    m.size = m.size - 65000
  7829.    IF m.size < 0
  7830.       EXIT
  7831.    ENDIF
  7832. ENDDO
  7833. IF m.g_graphic
  7834.    SET MESSAGE TO 'Generation Complete'
  7835. ELSE
  7836.    WAIT CLEAR
  7837. ENDIF
  7838. RETURN
  7839.  
  7840. **
  7841. ** Code Associated With Displaying of the Thermometer
  7842. **
  7843.  
  7844. *!*****************************************************************************
  7845. *!
  7846. *!      Procedure: ACTTHERM
  7847. *!
  7848. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7849. *!
  7850. *!*****************************************************************************
  7851. PROCEDURE acttherm
  7852. *)
  7853. *) ACTTHERM(<text>) - Activate thermometer.
  7854. *)
  7855. *) Activates thermometer.  Update the thermometer with UPDTHERM().
  7856. *) Thermometer window is named "thermometer."  Be sure to RELEASE
  7857. *) this window when done with thermometer.  Creates the global
  7858. *) m.g_thermwidth.
  7859. *)
  7860. PARAMETER m.text
  7861. PRIVATE m.prompt
  7862.  
  7863. IF m.g_graphic
  7864.    m.prompt = LOWER(m.g_outfile)
  7865.     m.prompt = thermfname(m.prompt)
  7866.  
  7867.    DO CASE
  7868.    CASE _WINDOWS
  7869.       DEFINE WINDOW thermomete ;
  7870.          AT  INT((SROW() - (( 5.615 * ;
  7871.          FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7872.          FONTMETRIC(1, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2), ;
  7873.          INT((SCOL() - (( 63.833 * ;
  7874.          FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7875.          FONTMETRIC(6, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2) ;
  7876.          SIZE 5.615,63.833 ;
  7877.          FONT m.g_dlgface, m.g_dlgsize ;
  7878.          STYLE m.g_dlgstyle ;
  7879.          NOFLOAT ;
  7880.          NOCLOSE ;
  7881.          NONE ;
  7882.          COLOR RGB(0, 0, 0, 192, 192, 192)
  7883.       MOVE WINDOW thermomete CENTER
  7884.       ACTIVATE WINDOW thermomete NOSHOW
  7885.  
  7886.       @ 0.5,3 SAY m.text FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle
  7887.       @ 1.5,3 SAY m.prompt FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle
  7888.       @ 0.000,0.000 TO 0.000,63.833 ;
  7889.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7890.       @ 0.000,0.000 TO 5.615,0.000 ;
  7891.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7892.       @ 0.385,0.667 TO 5.231,0.667 ;
  7893.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7894.       @ 0.308,0.667 TO 0.308,63.167 ;
  7895.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7896.       @ 0.385,63.000 TO 5.308,63.000 ;
  7897.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7898.       @ 5.231,0.667 TO 5.231,63.167 ;
  7899.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7900.       @ 5.538,0.000 TO 5.538,63.833 ;
  7901.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7902.       @ 0.000,63.667 TO 5.615,63.667 ;
  7903.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7904.       @ 3.000,3.333 TO 4.231,3.333 ;
  7905.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7906.       @ 3.000,60.333 TO 4.308,60.333 ;
  7907.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7908.       @ 3.000,3.333 TO 3.000,60.333 ;
  7909.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7910.       @ 4.231,3.333 TO 4.231,60.333 ;
  7911.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7912.       m.g_thermwidth = 56.269
  7913.    CASE _MAC
  7914.       DEFINE WINDOW thermomete ;
  7915.          AT  INT((SROW() - (( 5.62 * ;
  7916.          FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7917.          FONTMETRIC(1, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2), ;
  7918.          INT((SCOL() - (( 63.83 * ;
  7919.          FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7920.          FONTMETRIC(6, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2) ;
  7921.          SIZE 5.62,63.83 ;
  7922.          FONT m.g_dlgface, m.g_dlgsize ;
  7923.          STYLE m.g_dlgstyle ;
  7924.          NOFLOAT ;
  7925.          NOCLOSE ;
  7926.             NONE ;
  7927.          COLOR RGB(0, 0, 0, 192, 192, 192)
  7928.       MOVE WINDOW thermomete CENTER
  7929.       ACTIVATE WINDOW thermomete NOSHOW
  7930.  
  7931.       IF ISCOLOR()
  7932.          @ 0.000,0.000 TO 5.62,63.83 PATTERN 1;
  7933.              COLOR RGB(192, 192, 192, 192, 192, 192)
  7934.           @ 0.000,0.000 TO 0.000,63.83 ;
  7935.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7936.           @ 0.000,0.000 TO 5.62,0.000 ;
  7937.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7938.           @ 0.385,0.67 TO 5.23,0.67 ;
  7939.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7940.           @ 0.31,0.67 TO 0.31,63.17 ;
  7941.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7942.           @ 0.385,63.000 TO 5.31,63.000 ;
  7943.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7944.           @ 5.23,0.67 TO 5.23,63.17 ;
  7945.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7946.           @ 5.54,0.000 TO 5.54,63.83 ;
  7947.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7948.           @ 0.000,63.67 TO 5.62,63.67 ;
  7949.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7950.           @ 3.000,3.33 TO 4.23,3.33 ;
  7951.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7952.           @ 3.000,60.33 TO 4.31,60.33 ;
  7953.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7954.           @ 3.000,3.33 TO 3.000,60.33 ;
  7955.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7956.           @ 4.23,3.33 TO 4.23,60.33 ;
  7957.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7958.       ELSE
  7959.          @ 0.000, 0.000 TO 5.62, 63.830  PEN 2
  7960.           @ 0.230, 0.500 TO 5.39, 63.333  PEN 1
  7961.        ENDIF
  7962.       @ 0.5,3 SAY m.text FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle+"T" ;
  7963.          COLOR RGB(0,0,0,192,192,192)
  7964.       @ 1.5,3 SAY m.prompt FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle+"T" ;
  7965.          COLOR RGB(0,0,0,192,192,192)
  7966.  
  7967.       m.g_thermwidth = 56.27
  7968.         IF !ISCOLOR()
  7969.             @ 3.000,3.33 TO 4.23,m.g_thermwidth + 3.33
  7970.         ENDIF
  7971.    ENDCASE
  7972.    SHOW WINDOW thermomete TOP
  7973. ELSE
  7974.    m.prompt = SUBSTR(SYS(2014,m.g_outfile),1,48)+;
  7975.       IIF(LEN(m.g_outfile)>48,"...","")
  7976.  
  7977.    DEFINE WINDOW thermomete;
  7978.       FROM INT((SROW()-6)/2), INT((SCOL()-57)/2) ;
  7979.       TO INT((SROW()-6)/2) + 6, INT((SCOL()-57)/2) + 57;
  7980.       DOUBLE COLOR SCHEME 5
  7981.    ACTIVATE WINDOW thermomete NOSHOW
  7982.  
  7983.    m.g_thermwidth = 50
  7984.    @ 0,3 SAY m.text
  7985.    @ 1,3 SAY UPPER(m.prompt)
  7986.    @ 2,1 TO 4,m.g_thermwidth+4 &g_boxstrg
  7987.  
  7988.    SHOW WINDOW thermomete TOP
  7989. ENDIF
  7990. RETURN
  7991.  
  7992. *!*****************************************************************************
  7993. *!
  7994. *!      Procedure: UPDTHERM
  7995. *!
  7996. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7997. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  7998. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  7999. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8000. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8001. *!
  8002. *!*****************************************************************************
  8003. PROCEDURE updtherm
  8004. *)
  8005. *) UPDTHERM(<percent>) - Update thermometer.
  8006. *)
  8007. PARAMETER m.percent
  8008. PRIVATE m.nblocks, m.percent
  8009.  
  8010. ACTIVATE WINDOW thermomete
  8011.  
  8012. * Map to the number of platforms we are generating for
  8013. m.percent = MIN(INT(m.percent / m.g_numplatforms) ,100)
  8014.  
  8015. m.nblocks = (m.percent/100) * (m.g_thermwidth)
  8016. DO CASE
  8017. CASE _WINDOWS
  8018.    @ 3.000,3.333 TO 4.231,m.nblocks + 3.333 ;
  8019.       PATTERN 1 COLOR RGB(128, 128, 128, 128, 128, 128)
  8020. CASE _MAC
  8021.    *@ 3.000,3.33 TO 4.23,m.nblocks + 3.33 ;
  8022.    *   PATTERN 1 COLOR RGB(0, 0, 0, 220, 140, 120)
  8023.    @ 3.000,3.33 TO 4.23,m.nblocks + 3.33 ;
  8024.       PATTERN 1 COLOR RGB(0, 0, 128, 0, 0, 128)
  8025. OTHERWISE
  8026.    @ 3,3 SAY REPLICATE("█",m.nblocks)
  8027. ENDCASE
  8028. RETURN
  8029.  
  8030. *!*****************************************************************************
  8031. *!
  8032. *!      Procedure: DEACTTHERMO
  8033. *!
  8034. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  8035. *!
  8036. *!*****************************************************************************
  8037. PROCEDURE deactthermo
  8038. *)
  8039. *) DEACTTHERMO - Deactivate and Release thermometer window.
  8040. *)
  8041. IF WEXIST("thermomete")
  8042.    RELEASE WINDOW thermomete
  8043. ENDIF
  8044. RETURN
  8045.  
  8046. *!*****************************************************************************
  8047. *!
  8048. *!      Procedure: THERMADJ
  8049. *!
  8050. *!*****************************************************************************
  8051. FUNCTION thermadj
  8052. * Map the local thermometer from local (this platform) to global (all platforms)
  8053. * When all platforms have been accounted for, we want to show m.finish percent.
  8054. PARAMETERS m.pnum, m.current, m.finish
  8055. =assert(m.current <= m.finish,"Thermometer error!  Current > finish.")
  8056. =assert(BETWEEN(m.finish,0,100),"Thermometer error! Finish out of range.")
  8057. RETURN (m.finish * (m.pnum - 1)) + m.current
  8058.  
  8059.  
  8060. *!*****************************************************************************
  8061. *!
  8062. *!      Procedure: THERMFNAME
  8063. *!
  8064. *!*****************************************************************************
  8065. FUNCTION thermfname
  8066. PARAMETER m.fname
  8067. PRIVATE m.addelipse, m.g_pathsep, m.g_thermfface, m.g_thermfsize, m.g_thermfstyle
  8068.  
  8069. #define c_space 50
  8070. IF _MAC
  8071.     m.g_thermfface = "Geneva"
  8072.     m.g_thermfsize = 10
  8073.     m.g_thermfstyle = "B"
  8074. ELSE
  8075.     m.g_thermfface = "MS Sans Serif"
  8076.     m.g_thermfsize = 8
  8077.     m.g_thermfstyle = "B"
  8078. ENDIF
  8079.  
  8080. * Translate the filename into Mac native format
  8081. IF _MAC
  8082.     m.g_pathsep = ":"
  8083.     m.fname = SYS(2027, m.fname)
  8084. ELSE
  8085.     m.g_pathsep = "\"
  8086. ENDIF
  8087.  
  8088. IF TXTWIDTH(m.fname,m.g_thermfface,m.g_thermfsize,m.g_thermfstyle) > c_space
  8089.     * Make it fit in c_space
  8090.     m.fname = partialfname(m.fname, c_space - 1)
  8091.     m.addelipse = .F.
  8092.     DO WHILE TXTWIDTH(m.fname+'...',m.g_thermfface,m.g_thermfsize,m.g_thermfstyle) > c_space
  8093.         m.fname = LEFT(m.fname, LEN(m.fname) - 1)
  8094.         m.addelipse = .T.
  8095.     ENDDO
  8096.     IF m.addelipse
  8097.         m.fname = m.fname + "..."
  8098.    ENDIF
  8099. ENDIF
  8100. RETURN m.fname
  8101.  
  8102.  
  8103.  
  8104. *!*****************************************************************************
  8105. *!
  8106. *!      Procedure: PARTIALFNAME
  8107. *!
  8108. *!*****************************************************************************
  8109. FUNCTION partialfname
  8110. PARAMETER m.filname, m.fillen
  8111. * Return a filname no longer than m.fillen characters.  Take some chars
  8112. * out of the middle if necessary.  No matter what m.fillen is, this function
  8113. * always returns at least the file stem and extension.
  8114. PRIVATE m.bname, m.elipse, m.remain
  8115. m.elipse = "..." + m.g_pathsep
  8116. IF _MAC
  8117.     m.bname = SUBSTR(m.filname, RAT(":",m.filname)+1)
  8118. ELSE
  8119.     m.bname = justfname(m.filname)
  8120. ENDIF
  8121. DO CASE
  8122. CASE LEN(m.filname) <= m.fillen
  8123.    m.retstr = m.filname
  8124. CASE LEN(m.bname) + LEN(m.elipse) >= m.fillen
  8125.    m.retstr = m.bname
  8126. OTHERWISE
  8127.    m.remain = MAX(m.fillen - LEN(m.bname) - LEN(m.elipse), 0)
  8128.    IF _MAC
  8129.        m.retstr = LEFT(SUBSTR(m.filname,1,RAT(":",m.filname)-1),m.remain) ;
  8130.             +m.elipse+m.bname
  8131.    ELSE
  8132.          m.retstr = LEFT(justpath(m.filname),m.remain)+m.elipse+m.bname
  8133.    ENDIF
  8134. ENDCASE
  8135. RETURN m.retstr
  8136.  
  8137. **
  8138. ** Error Handling Code
  8139. **
  8140.  
  8141. *!*****************************************************************************
  8142. *!
  8143. *!      Procedure: ERRORHANDLER
  8144. *!
  8145. *!      Called by: GENSCRN.PRG
  8146. *!               : OPENPROJDBF()      (function  in GENSCRN.PRG)
  8147. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  8148. *!               : CHECKPARAM()       (function  in GENSCRN.PRG)
  8149. *!               : PREPFILE           (procedure in GENSCRN.PRG)
  8150. *!               : CLOSEFILE          (procedure in GENSCRN.PRG)
  8151. *!               : GETPLATFORM()      (function  in GENSCRN.PRG)
  8152. *!               : REFRESHPREFS       (procedure in GENSCRN.PRG)
  8153. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8154. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8155. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  8156. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  8157. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  8158. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  8159. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  8160. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  8161. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  8162. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  8163. *!               : COMBINE            (procedure in GENSCRN.PRG)
  8164. *!
  8165. *!          Calls: CLEANUP            (procedure in GENSCRN.PRG)
  8166. *!               : ERRLOG             (procedure in GENSCRN.PRG)
  8167. *!               : ERRSHOW            (procedure in GENSCRN.PRG)
  8168. *!               : CLOSEFILE          (procedure in GENSCRN.PRG)
  8169. *!
  8170. *!*****************************************************************************
  8171. PROCEDURE errorhandler
  8172. *)
  8173. *) ERRORHANDLER - Error Processing Center.
  8174. *)
  8175. PARAMETERS m.msg, m.linenum, m.errcode
  8176. IF ERROR() = 22   && too many memory variables--just bomb out as fast as we can
  8177.    ON ERROR
  8178.    DO cleanup
  8179.    CANCEL
  8180. ENDIF
  8181.  
  8182. DO CASE
  8183. CASE errcode == "Minor"
  8184.    DO errlog WITH m.msg, m.linenum
  8185.    m.g_status = 1
  8186. CASE errcode == "Serious"
  8187.    DO errlog  WITH m.msg, m.linenum
  8188.    DO errshow WITH m.msg, m.linenum
  8189.    m.g_status = 2
  8190.    ON ERROR
  8191. CASE errcode == "Fatal"
  8192.    ON ERROR
  8193.    IF m.g_havehand = .T.
  8194.       DO errlog WITH m.msg, m.linenum
  8195.       DO closefile WITH m.g_orghandle
  8196.       DO closefile WITH m.g_tmphandle
  8197.    ENDIF
  8198.    DO errshow WITH m.msg, m.linenum
  8199.    IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  8200.       RELEASE WINDOW thermometer
  8201.    ENDIF
  8202.    DO cleanup
  8203.    CANCEL
  8204. ENDCASE
  8205. RETURN
  8206.  
  8207. *!*****************************************************************************
  8208. *!
  8209. *!      Procedure: ESCHANDLER
  8210. *!
  8211. *!      Called by: BUILDENABLE        (procedure in GENSCRN.PRG)
  8212. *!
  8213. *!          Calls: BUILDDISABLE       (procedure in GENSCRN.PRG)
  8214. *!               : CLEANUP            (procedure in GENSCRN.PRG)
  8215. *!
  8216. *!*****************************************************************************
  8217. PROCEDURE eschandler
  8218. *)
  8219. *) ESCHANDLER - Escape handler.
  8220. *)
  8221. ON ERROR
  8222. WAIT WINDOW "Generation process stopped." NOWAIT
  8223. DO builddisable
  8224. IF m.g_havehand
  8225.    ERASE (m.g_outfile)
  8226.    ERASE (m.g_tmpfile)
  8227. ENDIF
  8228. IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  8229.    RELEASE WINDOW thermometer
  8230. ENDIF
  8231. DO cleanup
  8232. CANCEL
  8233.  
  8234. *!*****************************************************************************
  8235. *!
  8236. *!      Procedure: ERRLOG
  8237. *!
  8238. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  8239. *!
  8240. *!          Calls: OPENERRFILE        (procedure in GENSCRN.PRG)
  8241. *!
  8242. *!*****************************************************************************
  8243. PROCEDURE errlog
  8244. *)
  8245. *) ERRLOG - Save an error message in the error log file.
  8246. *)
  8247. PARAMETER m.msg, m.linenum
  8248. DO openerrfile
  8249.  
  8250. SET CONSOLE OFF
  8251. \\GENERATOR: <<ALLTRIM(m.msg)>>
  8252. IF NOT EMPTY(m.linenum)
  8253.    \\ LINE NUMBER: <<m.linenum>>
  8254. ENDIF
  8255. \
  8256. = FCLOSE(_TEXT)
  8257. _TEXT = m.g_orghandle
  8258. RETURN
  8259.  
  8260. *!*****************************************************************************
  8261. *!
  8262. *!      Procedure: ERRSHOW
  8263. *!
  8264. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  8265. *!               : OPENERRFILE        (procedure in GENSCRN.PRG)
  8266. *!
  8267. *!*****************************************************************************
  8268. PROCEDURE errshow
  8269. *)
  8270. *) ERRSHOW - Show error in an alert box on the screen.
  8271. *)
  8272. PARAMETER m.msg, m.lineno
  8273. PRIVATE m.curcursor
  8274.  
  8275. IF m.g_graphic
  8276.     IF _MAC
  8277.        DEFINE WINDOW ALERT ;
  8278.           AT  INT((SROW() - (( 6.615 * ;
  8279.           FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8280.           FONTMETRIC(1, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2), ;
  8281.           INT((SCOL() - (( 63.833 * ;
  8282.           FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8283.           FONTMETRIC(6, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2) ;
  8284.           SIZE 6.615,63.833 ;
  8285.           FONT m.g_dlgface, m.g_dlgsize ;
  8286.           STYLE m.g_dlgstyle ;
  8287.           NOCLOSE ;
  8288.           DOUBLE ;
  8289.           TITLE "Genscrn Error" ;
  8290.           COLOR RGB(0, 0, 0, 255, 255, 255)
  8291.     ELSE
  8292.        DEFINE WINDOW ALERT ;
  8293.           AT  INT((SROW() - (( 6.615 * ;
  8294.           FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8295.           FONTMETRIC(1, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2), ;
  8296.           INT((SCOL() - (( 63.833 * ;
  8297.           FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8298.           FONTMETRIC(6, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2) ;
  8299.           SIZE 6.615,63.833 ;
  8300.           FONT m.g_dlgface, m.g_dlgsize ;
  8301.           STYLE m.g_dlgstyle ;
  8302.           NOCLOSE ;
  8303.           DOUBLE ;
  8304.           TITLE "Genscrn Error" ;
  8305.           COLOR RGB(0, 0, 0, 255, 255, 255)
  8306.    ENDIF
  8307.    MOVE WINDOW ALERT CENTER
  8308.    ACTIVATE WINDOW ALERT NOSHOW
  8309.  
  8310.    m.dispmsg = m.msg
  8311.    IF TXTWIDTH(m.dispmsg) > WCOLS()
  8312.       * Make sure it isn't too long.
  8313.       DO WHILE TXTWIDTH(m.dispmsg+'...') > WCOLS()
  8314.          m.dispmsg = LEFT(m.dispmsg,LEN(m.dispmsg)-1)
  8315.       ENDDO
  8316.       IF m.msg <> m.dispmsg    && Has display message been shortened?
  8317.          m.dispmsg = m.dispmsg + '...'
  8318.       ENDIF
  8319.    ENDIF
  8320.  
  8321.    @ 1,MAX((WCOLS()-TXTWIDTH( m.dispmsg ))/2,1) SAY m.dispmsg
  8322.  
  8323.    m.msg = "Genscrn Line Number: "+STR(m.lineno, 4)
  8324.    @ 2,(WCOLS()-TXTWIDTH( m.msg ))/2 SAY m.msg
  8325.  
  8326.    IF TYPE("m.g_screen") <> "U" AND m.g_screen <> 0
  8327.       m.msg = "Generating from: "+LOWER(g_screens[m.g_screen,1])
  8328.       @ 3,MAX((WCOLS()-TXTWIDTH( m.msg ))/2,1) SAY m.msg
  8329.    ENDIF
  8330.  
  8331.    m.msg = "Press any key to cleanup and exit..."
  8332.    @ 4,(WCOLS()-TXTWIDTH( m.msg ))/2 SAY m.msg
  8333.  
  8334.    SHOW WINDOW ALERT
  8335. ELSE
  8336.    DEFINE WINDOW ALERT;
  8337.       FROM INT((SROW()-7)/2), INT((SCOL()-50)/2) TO INT((SROW()-7)/2) + 6, INT((SCOL()-50)/2) + 50 ;
  8338.       FLOAT NOGROW NOCLOSE NOZOOM SHADOW DOUBLE;
  8339.       COLOR SCHEME 7
  8340.  
  8341.    ACTIVATE WINDOW ALERT
  8342.  
  8343.    @ 0,0 CLEAR
  8344.    @ 1,0 SAY PADC(SUBSTR(m.msg,1,44)+;
  8345.       IIF(LEN(m.msg)>44,"...",""), WCOLS())
  8346.    @ 2,0 SAY PADC("Line Number: "+STR(m.lineno, 4), WCOLS())
  8347.  
  8348.    IF TYPE("m.g_screen") <> "U" AND m.g_screen <> 0
  8349.       m.msg = "Working on screen: "+LOWER(g_screens[m.g_screen])
  8350.       @ 3,0 SAY PADC(m.msg,WCOLS())
  8351.    ENDIF
  8352.  
  8353.    @ 4,0 SAY PADC("Press any key to cleanup and exit...", WCOLS())
  8354. ENDIF
  8355.  
  8356. m.curcursor = SET( "CURSOR" )
  8357. SET CURSOR OFF
  8358.  
  8359. WAIT ""
  8360.  
  8361. RELEASE WINDOW ALERT
  8362. SET CURSOR &curcursor
  8363.  
  8364. RELEASE WINDOW ALERT
  8365. RETURN
  8366.  
  8367. *!*****************************************************************************
  8368. *!
  8369. *!      Procedure: OPENERRFILE
  8370. *!
  8371. *!      Called by: ERRLOG             (procedure in GENSCRN.PRG)
  8372. *!
  8373. *!          Calls: ERRSHOW            (procedure in GENSCRN.PRG)
  8374. *!
  8375. *!*****************************************************************************
  8376. PROCEDURE openerrfile
  8377. *)
  8378. *) OPENERRFILE - Open error file.
  8379. *)
  8380. PRIVATE m.errfile, m.errhandle
  8381. m.errfile   = m.g_errlog+".ERR"
  8382. m.errhandle = FOPEN(m.errfile,2)
  8383. IF m.errhandle < 0
  8384.    m.errhandle = FCREATE(m.errfile)
  8385.    IF m.errhandle < 0
  8386.       DO errshow WITH ".ERR could not be opened...", LINENO()
  8387.       m.g_status = 2
  8388.       IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  8389.          RELEASE WINDOW thermometer
  8390.       ENDIF
  8391.       ON ERROR
  8392.       RETURN TO MASTER
  8393.    ENDIF
  8394. ELSE
  8395.    = FSEEK(m.errhandle,0,2)
  8396. ENDIF
  8397. IF SET("TEXTMERGE") = "OFF"
  8398.    SET TEXTMERGE ON
  8399. ENDIF
  8400. _TEXT = m.errhandle
  8401.  
  8402. *!*****************************************************************************
  8403. *!
  8404. *!      Procedure: PUSHINDENT
  8405. *!
  8406. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8407. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  8408. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  8409. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  8410. *!
  8411. *!*****************************************************************************
  8412. PROCEDURE pushindent
  8413. *)
  8414. *) PUSHINDENT - Add another indentation level
  8415. *)
  8416. _PRETEXT = CHR(9) + _PRETEXT
  8417. RETURN
  8418.  
  8419. *!*****************************************************************************
  8420. *!
  8421. *!      Procedure: POPINDENT
  8422. *!
  8423. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8424. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  8425. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  8426. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  8427. *!
  8428. *!*****************************************************************************
  8429. PROCEDURE popindent
  8430. *)
  8431. *) POPINDENT - Remove one indentation level
  8432. *)
  8433. IF LEFT(_PRETEXT,1) = CHR(9)
  8434.    _PRETEXT = SUBSTR(_PRETEXT,2)
  8435. ENDIF
  8436. RETURN
  8437.  
  8438. *!*****************************************************************************
  8439. *!
  8440. *!      Procedure: COUNTPLATFORMS
  8441. *!
  8442. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8443. *!
  8444. *!*****************************************************************************
  8445. FUNCTION countplatforms
  8446. *)
  8447. *) COUNTPLATFORMS - Count the number of platforms in this SCX that are in common across
  8448. *)                    all the SCXs in this screen set.
  8449. *)
  8450. PRIVATE m.cnt, m.i
  8451. IF TYPE("g_platforms") <> "U"
  8452.    m.cnt = 0
  8453.    FOR m.i = 1 TO ALEN(g_platforms)
  8454.       IF !EMPTY(g_platforms[m.i])
  8455.          m.cnt = m.cnt + 1
  8456.       ENDIF
  8457.    ENDFOR
  8458.    RETURN m.cnt
  8459. ENDIF
  8460. RETURN 0
  8461.  
  8462. *!*****************************************************************************
  8463. *!
  8464. *!      Function: LOOKUPPLATFORM
  8465. *!
  8466. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8467. *!
  8468. *!*****************************************************************************
  8469. FUNCTION lookupplatform
  8470. *)
  8471. *) LOOKUPPLATFORM - Return the n-th platform name
  8472. *)
  8473. PARAMETER m.n
  8474. IF TYPE("g_platforms") <> "U" AND ALEN(g_platforms) >= m.n ;
  8475.       AND m.n > 0 AND TYPE("g_platforms[m.n]") = "C"
  8476.    RETURN UPPER(g_platforms[m.n])
  8477. ENDIF
  8478. RETURN ""
  8479.  
  8480. *!*****************************************************************************
  8481. *!
  8482. *!      Function: HASRECORDS
  8483. *!
  8484. *!*****************************************************************************
  8485. FUNCTION hasrecords
  8486. *)
  8487. *) HASRECORDS - Return .T. if plat records are in the screen.
  8488. *)
  8489. PARAMETER m.plat
  8490. IF TYPE("g_platforms") = "U"
  8491.    RETURN IIF(m.plat = "DOS",.T.,.F.)
  8492. ELSE
  8493.    RETURN IIF(ASCAN(g_platforms,m.plat) > 0,.T.,.F.)
  8494. ENDIF
  8495. RETURN
  8496.  
  8497. *!*****************************************************************************
  8498. *!
  8499. *!       Function: GETPARAM
  8500. *!
  8501. *!      Called by: CHECKPARAM()       (function  in GENSCRN.PRG)
  8502. *!
  8503. *!          Calls: ISCOMMENT()        (function  in GENSCRN.PRG)
  8504. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  8505. *!               : MATCH()            (function  in GENSCRN.PRG)
  8506. *!
  8507. *!*****************************************************************************
  8508. FUNCTION getparam
  8509. *)
  8510. *) GETPARAM - Return the PARAMETER statement from a setup snippet, if one is there
  8511. *)
  8512. PARAMETER m.snipname
  8513. PRIVATE m.i, m.thisparam, m.numlines, m.thisline, m.word1, m.contin
  8514.  
  8515. * Do a quick check to see if we need to search further.
  8516. IF ATC("PARA",&snipname) = 0
  8517.    RETURN ""
  8518. ENDIF
  8519.  
  8520. m.numlines = MEMLINES(&snipname)
  8521. _MLINE = 0
  8522. m.i = 1
  8523. DO WHILE m.i <= m.numlines
  8524.    m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  8525.    DO killcr WITH m.thisline
  8526.  
  8527.    * Drop any double-ampersand comment
  8528.    IF AT(m.g_dblampersand,m.thisline) > 0
  8529.       m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  8530.    ENDIF
  8531.  
  8532.    IF !EMPTY(m.thisline) AND !iscomment(@thisline)
  8533.       * See if the first non-blank, non-comment, non-directive, non-EXTERNAL
  8534.       * line is a #SECTION 1
  8535.       DO CASE
  8536.       CASE LEFT(m.thisline,5) = "#SECT" AND AT('1',m.thisline) <> 0
  8537.          * Read until we find a #SECTION 2, the end of the snippet or a
  8538.          * PARAMETER statement.
  8539.          DO WHILE m.i <= m.numlines
  8540.             m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  8541.             DO killcr WITH m.thisline
  8542.  
  8543.             * Drop any double-ampersand comment
  8544.             IF AT(m.g_dblampersand,m.thisline) > 0
  8545.                m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  8546.             ENDIF
  8547.  
  8548.             m.word1 = wordnum(CHRTRAN(m.thisline,CHR(9)+';',' '),1)
  8549.             DO CASE
  8550.             CASE match(m.word1,"PARAMETERS")
  8551.  
  8552.                * Replace tabs with spaces
  8553.                m.thisline = LTRIM(CHRTRAN(m.thisline,CHR(9)," "))
  8554.  
  8555.                * Process continuation lines.  Replace tabs in incoming lines with spaces.
  8556.                DO WHILE RIGHT(RTRIM(m.thisline),1) = ';'
  8557.                   m.thisline = m.thisline + ' '+ CHR(13)+CHR(10)+CHR(9)
  8558.                   m.contin = MLINE(&snipname, 1, _MLINE)
  8559.                   DO killcr WITH m.contin
  8560.                   m.contin = CHRTRAN(LTRIM(m.contin),CHR(9)," ")
  8561.                   m.thisline = m.thisline + UPPER(m.contin)
  8562.                ENDDO
  8563.  
  8564.                * Clean up the parameters so that minor differences in
  8565.                * spacing don't cause the comparisons to fail.
  8566.  
  8567.                * Take the parameters but not the PARAMETER keyword itself
  8568.                m.thisparam = SUBSTR(m.thisline,AT(' ',m.thisline)+1)
  8569.                DO WHILE INLIST(LEFT(m.thisparam,1),CHR(10),CHR(13),CHR(9),' ')
  8570.                   m.thisparam = SUBSTR(m.thisparam,2)
  8571.                ENDDO
  8572.  
  8573.                * Force single spacing in the param string
  8574.                DO WHILE AT('  ',m.thisparam) > 0
  8575.                   m.thisparam = STRTRAN(m.thisparam,'  ',' ')
  8576.                ENDDO
  8577.  
  8578.                * Drop "m." designations so that they don't make the variables look different
  8579.                m.thisparam = STRTRAN(m.thisparam,'m.','')
  8580.                m.thisparam = STRTRAN(m.thisparam,'m->','')
  8581.  
  8582.                RETURN LOWER(m.thisparam)
  8583.             CASE LEFT(m.thisline,5) = "#SECT" AND AT('2',m.thisline) <> 0
  8584.                * No parameter statement, since we found #SECTION 2 first
  8585.                RETURN ""
  8586.             ENDCASE
  8587.             m.i = m.i + 1
  8588.          ENDDO
  8589.       CASE LEFT(m.thisline,1) = "#"   && some other directive
  8590.          * Do nothing.  Get next line.
  8591.       CASE match(wordnum(m.thisline,1),"EXTERNAL")
  8592.          * Ignore it.  This doesn't disqualify a later statement from being a PARAMETER
  8593.          * statement.
  8594.       OTHERWISE
  8595.          * no #SECTION 1, so no parameters
  8596.          RETURN ""
  8597.       ENDCASE
  8598.    ENDIF
  8599.    m.i = m.i + 1
  8600. ENDDO
  8601. RETURN ""
  8602.  
  8603.  
  8604. *!*****************************************************************************
  8605. *!
  8606. *!       Function: MATCH
  8607. *!
  8608. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8609. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  8610. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  8611. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  8612. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8613. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  8614. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  8615. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  8616. *!
  8617. *!*****************************************************************************
  8618. FUNCTION match
  8619. *)
  8620. *) MATCH - Returns TRUE is candidate is a valid 4-or-more-character abbreviation of keyword
  8621. *)
  8622. PARAMETER m.candidate, m.keyword
  8623. PRIVATE m.in_exact, m.retlog
  8624.  
  8625. m.in_exact = SET("EXACT")
  8626. SET EXACT OFF
  8627. DO CASE
  8628. CASE EMPTY(m.candidate)
  8629.    m.retlog = EMPTY(m.keyword)
  8630. CASE LEN(m.candidate) < 4
  8631.    m.retlog = IIF(m.candidate == m.keyword,.T.,.F.)
  8632. OTHERWISE
  8633.    m.retlog = IIF(m.keyword = m.candidate,.T.,.F.)
  8634. ENDCASE
  8635. IF m.in_exact != "OFF"
  8636.    SET EXACT ON
  8637. ENDIF
  8638.  
  8639. RETURN m.retlog
  8640.  
  8641. *!*****************************************************************************
  8642. *!
  8643. *!       Function: WORDNUM
  8644. *!
  8645. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8646. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  8647. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  8648. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  8649. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8650. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  8651. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  8652. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  8653. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  8654. *!
  8655. *!*****************************************************************************
  8656. FUNCTION wordnum
  8657. *)
  8658. *) WORDNUM - Returns w_num-th word from string strg
  8659. *)
  8660. PARAMETERS m.strg,m.w_num
  8661. PRIVATE strg,s1,w_num,ret_str
  8662.  
  8663. m.s1 = ALLTRIM(m.strg)
  8664.  
  8665. * Replace tabs with spaces
  8666. m.s1 = CHRTRAN(m.s1,CHR(9)," ")
  8667.  
  8668. * Reduce multiple spaces to a single space
  8669. DO WHILE AT('  ',m.s1) > 0
  8670.    m.s1 = STRTRAN(m.s1,'  ',' ')
  8671. ENDDO
  8672.  
  8673. ret_str = ""
  8674. DO CASE
  8675. CASE m.w_num > 1
  8676.    DO CASE
  8677.    CASE AT(" ",m.s1,m.w_num-1) = 0   && No word w_num.  Past end of string.
  8678.       m.ret_str = ""
  8679.    CASE AT(" ",m.s1,m.w_num) = 0     && Word w_num is last word in string.
  8680.       m.ret_str = SUBSTR(m.s1,AT(" ",m.s1,m.w_num-1)+1,255)
  8681.    OTHERWISE                         && Word w_num is in the middle.
  8682.       m.strt_pos = AT(" ",m.s1,m.w_num-1)
  8683.       m.ret_str  = SUBSTR(m.s1,strt_pos,AT(" ",m.s1,m.w_num)+1 - strt_pos)
  8684.    ENDCASE
  8685. CASE m.w_num = 1
  8686.    IF AT(" ",m.s1) > 0               && Get first word.
  8687.       m.ret_str = SUBSTR(m.s1,1,AT(" ",m.s1)-1)
  8688.    ELSE                              && There is only one word.  Get it.
  8689.       m.ret_str = m.s1
  8690.    ENDIF
  8691. ENDCASE
  8692. RETURN ALLTRIM(m.ret_str)
  8693.  
  8694.  
  8695. *!*****************************************************************************
  8696. *!
  8697. *!       Function: GETCNAME
  8698. *!
  8699. *!      Called by: SETCLAUSEFLAGS     (procedure in GENSCRN.PRG)
  8700. *!               : ORCLAUSEFLAGS      (procedure in GENSCRN.PRG)
  8701. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  8702. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  8703. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  8704. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  8705. *!
  8706. *!*****************************************************************************
  8707. FUNCTION getcname
  8708. *) GETCNAME - Generates a name for a clause.  Will take name from a
  8709. *)              generator directive stored in a snippet if present,
  8710. *)              or generates a generic name otherwise.  The name is
  8711. *)              designated by a #NAME name directive
  8712. *)
  8713. PARAMETERS m.snippet
  8714. PRIVATE dirname
  8715. IF ATC("#NAME",m.snippet) > 0
  8716.    m.dirname = MLINE(m.snippet, ATCLINE('#NAME',m.snippet))
  8717.    DO killcr WITH m.dirname
  8718.    m.dirname = UPPER(ALLTRIM(SUBSTR(m.dirname,AT(' ',m.dirname)+1)))
  8719.    IF !EMPTY(m.dirname)
  8720.       RETURN m.dirname
  8721.    ENDIF
  8722. ENDIF
  8723. RETURN LOWER(SYS(2015))
  8724.  
  8725. *!*****************************************************************************
  8726. *!
  8727. *!      Procedure: NOTEAREA
  8728. *!
  8729. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  8730. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  8731. *!
  8732. *!*****************************************************************************
  8733. PROCEDURE notearea
  8734. *)
  8735. *) NOTEAREA - Note that we are using this area so that we can clean up at exit
  8736. *)
  8737. g_areas[m.g_areacount] = SELECT()
  8738. m.g_areacount = m.g_areacount + 1
  8739. RETURN
  8740.  
  8741. *!*****************************************************************************
  8742. *!
  8743. *!      Procedure: CLEARAREAS
  8744. *!
  8745. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  8746. *!
  8747. *!*****************************************************************************
  8748. PROCEDURE clearareas
  8749. *)
  8750. *) CLEARAREAS - Clear the ones we opened.
  8751. *)
  8752. FOR i = 1 TO m.g_areacount
  8753.    SELECT g_areas[m.i]
  8754.    USE
  8755. ENDFOR
  8756. RETURN
  8757.  
  8758. *!*****************************************************************************
  8759. *!
  8760. *!      Procedure: INITTICK
  8761. *!
  8762. *!      Called by: GENSCRN.PRG
  8763. *!
  8764. *!*****************************************************************************
  8765. PROCEDURE inittick
  8766. *)
  8767. *) INITTICK, TICK, and TOCK - Profiling functions
  8768. *)
  8769. IF TYPE("ticktock") = "U"
  8770.    PUBLIC ticktock[10]
  8771. ENDIF
  8772. ticktock = 0
  8773. RETURN
  8774.  
  8775. *!*****************************************************************************
  8776. *!
  8777. *!       Function: TICK
  8778. *!
  8779. *!      Called by: GENSCRN.PRG
  8780. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8781. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8782. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  8783. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  8784. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8785. *!
  8786. *!*****************************************************************************
  8787. FUNCTION tick
  8788. *)
  8789. *) INITTICK, TICK, and TOCK - Profiling functions
  8790. *)
  8791. PARAMETER m.bucket
  8792. ticktock[bucket] = ticktock[bucket] - SECONDS()
  8793. RETURN
  8794.  
  8795. *!*****************************************************************************
  8796. *!
  8797. *!       Function: TOCK
  8798. *!
  8799. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  8800. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8801. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8802. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  8803. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  8804. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8805. *!
  8806. *!*****************************************************************************
  8807. FUNCTION tock
  8808. *)
  8809. *) INITTICK, TICK, and TOCK - Profiling functions
  8810. *)
  8811. PARAMETER m.bucket
  8812. ticktock[bucket] = ticktock[bucket] + SECONDS()
  8813. RETURN
  8814.  
  8815. *!*****************************************************************************
  8816. *!
  8817. *!      Procedure: PUTMSG
  8818. *!
  8819. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8820. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8821. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8822. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8823. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8824. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8825. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8826. *!
  8827. *!*****************************************************************************
  8828. PROCEDURE putmsg
  8829. *)
  8830. *) Display a status message on the status bar at the bottom of the screen
  8831. *)
  8832. PARAMETER m.msg
  8833. IF m.g_graphic
  8834.    SET MESSAGE TO msg
  8835. ENDIF
  8836.  
  8837. *!*****************************************************************************
  8838. *!
  8839. *!       Function: VERSIONCAP
  8840. *!
  8841. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8842. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8843. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8844. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8845. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8846. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  8847. *!
  8848. *!*****************************************************************************
  8849. FUNCTION versioncap
  8850. *)
  8851. *) VERSIONCAP - Return platform name suitable for display
  8852. *)
  8853. PARAMETER m.strg, m.dual
  8854. DO CASE
  8855. CASE m.strg = "DOS"
  8856.    m.retstrg = "MS-DOS"
  8857.     IF m.dual
  8858.        m.retstrg = m.retstrg + " and UNIX"
  8859.     ENDIF
  8860. CASE m.strg = "WINDOWS"
  8861.    m.retstrg = "Windows"
  8862.     IF m.dual
  8863.        m.retstrg = m.retstrg + " and Macintosh"
  8864.     ENDIF
  8865. CASE m.strg = "MAC"
  8866.    m.retstrg = "Macintosh"
  8867.     IF m.dual
  8868.        m.retstrg = m.retstrg + " and Windows"
  8869.     ENDIF
  8870. CASE m.strg = "UNIX"
  8871.    m.retstrg = "UNIX"
  8872.     IF m.dual
  8873.        m.retstrg = m.retstrg + " and MS-DOS"
  8874.     ENDIF
  8875. OTHERWISE
  8876.    m.retstrg = m.strg
  8877. ENDCASE
  8878. RETURN m.retstrg
  8879.  
  8880. *!*****************************************************************************
  8881. *!
  8882. *!       Function: MULTIPLAT
  8883. *!
  8884. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8885. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8886. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8887. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8888. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8889. *!
  8890. *!*****************************************************************************
  8891. FUNCTION multiplat
  8892. *)
  8893. *) MULTIPLAT - Returns TRUE if we are generating for multiple platforms
  8894. *)
  8895. RETURN IIF(m.g_allplatforms AND m.g_numplatforms > 1, .T. , .F.)
  8896.  
  8897. *!*****************************************************************************
  8898. *!
  8899. *!      Procedure: SEEKHEADER
  8900. *!
  8901. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  8902. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8903. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8904. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8905. *!               : GENRELATIONS       (procedure in GENSCRN.PRG)
  8906. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8907. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  8908. *!
  8909. *!*****************************************************************************
  8910. PROCEDURE seekheader
  8911. *)
  8912. *) SEEKHEADER - Find the header for this screen/platform
  8913. *)
  8914. PARAMETER m.i
  8915. IF g_screens[m.i,6]
  8916.    GO TOP
  8917. ELSE
  8918.    LOCATE FOR platform = g_screens[m.i,7] AND objtype = c_otscreen
  8919. ENDIF
  8920. RETURN
  8921.  
  8922. *!*****************************************************************************
  8923. *!
  8924. *!       Function: GETPLATNAME
  8925. *!
  8926. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  8927. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8928. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8929. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8930. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  8931. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  8932. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  8933. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  8934. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  8935. *!
  8936. *!*****************************************************************************
  8937. FUNCTION getplatname
  8938. *)
  8939. *) GETPLATNAME - Return the platform for a screen
  8940. *)
  8941. PARAMETER m.plnum
  8942. IF g_screens[m.plnum,6]
  8943.    RETURN "DOS"
  8944. ELSE
  8945.    RETURN platform
  8946. ENDIF
  8947. RETURN
  8948.  
  8949.  
  8950. *!*****************************************************************************
  8951. *!
  8952. *!      Procedure: INSERTFILE
  8953. *!
  8954. *!      Called by: GENINSERTCODE      (procedure in GENSCRN.PRG)
  8955. *!
  8956. *!          Calls: WRITECODE          (procedure in GENSCRN.PRG)
  8957. *!
  8958. *!*****************************************************************************
  8959. PROCEDURE insertfile
  8960. PARAMETER m.incfn, m.scrnno, m.insetup, m.platname
  8961. PRIVATE m.oldals, m.insdbfname, m.oldmline, m.fptname
  8962.  
  8963. * Search for the file in the current directory, along the FoxPro path, and along
  8964. * the DOS path.
  8965. IF !FILE(m.incfn)
  8966.    DO CASE
  8967.    CASE FILE(FULLPATH(m.incfn))
  8968.       m.incfn = FULLPATH(m.incfn)
  8969.    CASE FILE(FULLPATH(m.incfn,1))
  8970.       m.incfn = FULLPATH(m.incfn,1)
  8971.    ENDCASE
  8972. ENDIF
  8973.  
  8974. IF FILE((m.incfn))
  8975.    m.oldals = ALIAS()
  8976.    m.insdbfname = SYS(3)+".DBF"
  8977.    m.oldmline = _MLINE
  8978.  
  8979.    * The following lines create a temporary file with a single memo field
  8980.    * and appends the inserted file into the memo field. Effectively creating
  8981.    * a code snippet. This allows the standard procedure for generating code
  8982.    * snippets to be call to process the inserted file. This in turn allows
  8983.    * the include file to contain generator directives.
  8984.    CREATE TABLE (m.insdbfname) (inscode m)
  8985.    APPEND BLANK
  8986.    APPEND MEMO inscode FROM (m.incfn)
  8987.  
  8988.    \** Start of inserted file <<m.incfn>> <<REPLICATE(m.g_horiz,32)+"start">>
  8989.  
  8990.    * Make a recursive call to the standard snippet generation procedure
  8991.    DO writecode WITH inscode, m.platname, 1, 0, m.scrnno, m.insetup
  8992.  
  8993.    \** End of inserted file <<m.incfn>> <<REPLICATE(m.g_horiz,36)+"end">>
  8994.    \
  8995.  
  8996.    USE
  8997.    DELETE FILE (m.insdbfname)
  8998.    m.fptname = forceext(m.insdbfname,"FPT")
  8999.    IF FILE(m.fptname)
  9000.       DELETE FILE (m.fptname)
  9001.    ENDIF
  9002.  
  9003.    SELECT (m.oldals)
  9004.    _MLINE=oldmline
  9005. ELSE
  9006.    \*
  9007.    \* Inserted file <<m.incfn>> not found!
  9008.    \*
  9009. ENDIF
  9010. RETURN
  9011.  
  9012. *!*****************************************************************************
  9013. *!
  9014. *!      Function: VERSNUM
  9015. *!
  9016. *!*****************************************************************************
  9017. FUNCTION versnum
  9018. * Return string corresponding to FoxPro version number
  9019. RETURN wordnum(vers(),2)
  9020.  
  9021.  
  9022. *!*****************************************************************************
  9023. *!
  9024. *!      Function: SHOWSTAT
  9025. *!
  9026. *!*****************************************************************************
  9027. PROCEDURE showstat
  9028. PARAMETER m.strg
  9029. WAIT WINDOW m.strg NOWAIT
  9030. RETURN
  9031.  
  9032. *!*****************************************************************************
  9033. *!
  9034. *!      Function: KILLCR
  9035. *!
  9036. *!*****************************************************************************
  9037. PROCEDURE killcr
  9038. PARAMETER m.strg
  9039. IF _MAC
  9040.    m.strg = CHRTRAN(m.strg,CHR(13)+CHR(10),"")
  9041. ENDIF
  9042. RETURN
  9043.  
  9044. *!*****************************************************************************
  9045. *!
  9046. *!      Function: ASSERT
  9047. *!
  9048. *!*****************************************************************************
  9049. FUNCTION assert
  9050. PARAMETER m.bool, m.strg
  9051. IF !m.bool
  9052.    WAIT WINDOW m.strg
  9053. ENDIF
  9054.  
  9055. *!*****************************************************************************
  9056. *!
  9057. *!      Function: BITMAPSTR
  9058. *!
  9059. *!*****************************************************************************
  9060. FUNCTION bitmapstr
  9061. * Return a string of bitmap file extensions, suitable for LOCFILE, etc.
  9062. PARAMETER whichone
  9063. DO CASE
  9064. CASE whichone = c_all AND _MAC
  9065.    RETURN '"'+m.g_picext+"|"+m.g_bmpext+"|"+m.g_icnext+"|"+m.g_icoext+'"'
  9066. CASE whichone = c_all AND !_MAC
  9067.    RETURN '"'+m.g_bmpext+"|"+m.g_icoext+"|"+m.g_picext+"|"+m.g_icnext+'"'
  9068. OTHERWISE
  9069.    RETURN '"'+IIF(_MAC,m.g_picext,m.g_bmpext)+'"'
  9070. ENDCASE
  9071.  
  9072. *!*****************************************************************************
  9073. *!
  9074. *!      Function: ICONSTR
  9075. *!
  9076. *!*****************************************************************************
  9077. FUNCTION iconstr
  9078. DO CASE
  9079. CASE _MAC
  9080.     RETURN m.g_icnext
  9081. OTHERWISE
  9082.     RETURN m.g_icoext
  9083. ENDCASE
  9084.  
  9085. *!*****************************************************************************
  9086. *!
  9087. *!      Function: STYLE2NUM
  9088. *!
  9089. *!*****************************************************************************
  9090. FUNCTION style2num
  9091. * Translate a font style string to its equivalent numerical representation
  9092. PARAMETER m.strg
  9093. PRIVATE m.i, m.num
  9094. m.num = 0
  9095. m.strg= UPPER(ALLTRIM(m.strg))
  9096. FOR m.i = 1 TO LEN(m.strg)
  9097.    DO CASE
  9098.    CASE SUBSTR(m.strg,i,1) = "B"      && bold
  9099.       m.num = m.num + 1
  9100.    CASE SUBSTR(m.strg,i,1) = "I"         && italic
  9101.       m.num = m.num + 2
  9102.    CASE SUBSTR(m.strg,i,1) = "U"      && underlined
  9103.       m.num = m.num + 4
  9104.    CASE SUBSTR(m.strg,i,1) = "O"      && outline
  9105.       m.num = m.num + 8
  9106.    CASE SUBSTR(m.strg,i,1) = "S"      && shadow
  9107.       m.num = m.num + 16
  9108.    CASE SUBSTR(m.strg,i,1) = "C"         && condensed
  9109.       m.num = m.num + 32
  9110.    CASE SUBSTR(m.strg,i,1) = "E"      && extended
  9111.       m.num = m.num + 64
  9112.    CASE SUBSTR(m.strg,i,1) = "-"      && strikeout
  9113.       m.num = m.num + 128
  9114.    ENDCASE
  9115. ENDFOR
  9116. RETURN m.num
  9117.  
  9118. *!*****************************************************************************
  9119. *!
  9120. *!      Function: NUM2STYLE
  9121. *!
  9122. *!*****************************************************************************
  9123. FUNCTION num2style
  9124. * Translate a font style number to its equivalent string representation
  9125. PARAMETER m.num
  9126. PRIVATE m.i, m.strg, m.pow, m.stylechars, m.outstrg
  9127. m.strg = ""
  9128. * These are the style characters.  Their position in the string matches the bit
  9129. * position in the num byte.
  9130. m.stylechars = "BIUOSCE-"
  9131.  
  9132. * Look at each of the bits in the num byte
  9133. FOR m.i = 8 TO 1 STEP -1
  9134.    m.pow = ROUND(2^(i-1),0)
  9135.     IF m.num >= m.pow
  9136.        m.strg = m.strg + SUBSTR(stylechars,m.i,1)
  9137.     ENDIF
  9138.     m.num = m.num % m.pow
  9139. ENDFOR
  9140.  
  9141. * Now reverse the string so that style codes appear in the traditional order
  9142. m.outstrg = ""
  9143. FOR m.i = 1 TO LEN(m.strg)
  9144.    m.outstrg = m.outstrg + SUBSTR(m.strg,LEN(m.strg)+1-m.i,1)
  9145. ENDFOR
  9146. RETURN m.outstrg
  9147.  
  9148.  
  9149. FUNCTION ctrlclause
  9150. PARAMETER m.pictstrg
  9151. * Return the control portion of a picture string
  9152. m.pictstrg = LTRIM(m.pictstrg)
  9153. m.spos = AT(' ',m.pictstrg)
  9154. IF m.spos > 1
  9155.     IF INLIST(LEFT(m.pictstrg,1),'"',"'")
  9156.        m.pictstrg = STRTRAN(m.pictstrg,LEFT(m.pictstrg,1),"")
  9157.     ENDIF
  9158.    RETURN ALLTRIM(LEFT(m.pictstrg,m.spos - 1))
  9159. ELSE
  9160.    RETURN m.pictstrg
  9161. ENDIF
  9162.  
  9163.  
  9164. *: EOF: GENSCRN.PRG
  9165.