home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a087 / 7.ddi / GENSCRN.PR_ / GENSCRN.bin
Encoding:
Text File  |  1994-02-02  |  286.0 KB  |  9,170 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. m.memowidth = SET("MEMOWIDTH")
  397. SET MEMOWIDTH TO 256
  398. m.cursor = SET("CURSOR")
  399. SET CURSOR OFF
  400. m.consol = SET("CONSOLE")
  401. SET CONSOLE OFF
  402. m.bell = SET("BELL")
  403. SET BELL OFF
  404. m.exact = SET("EXACT")
  405. SET EXACT ON
  406. m.safety = SET("SAFETY")
  407. m.deci = SET("DECIMALS")
  408. SET DECIMALS TO 0
  409. m.mdecpoint = SET("POINT")
  410. SET POINT TO "."
  411. m.fixed = SET("FIXED")
  412. SET FIXED ON
  413. m.print = SET("PRINT")
  414. SET PRINT OFF
  415. m.unique = SET("UNIQUE")
  416. SET UNIQUE OFF
  417. m.mcollate = SET("COLLATE")
  418. SET COLLATE TO "machine"
  419. #if "MAC" $ UPPER(VERSION(1))
  420.    IF _MAC
  421.       m.mmacdesk = SET("MACDESKTOP")
  422.       SET MACDESKTOP ON
  423.     ENDIF
  424. #endif
  425. m.origpretext = _PRETEXT
  426. _PRETEXT = ""
  427. RETURN
  428.  
  429. *!*****************************************************************************
  430. *!
  431. *!      Procedure: CLEANUP
  432. *!
  433. *!      Called by: GENSCRN.PRG
  434. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  435. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  436. *!
  437. *!          Calls: CLEANSCRN          (procedure in GENSCRN.PRG)
  438. *!               : CLEARAREAS         (procedure in GENSCRN.PRG)
  439. *!
  440. *!*****************************************************************************
  441. PROCEDURE cleanup
  442. *)
  443. *) CLEANUP - Restore environment to pre-execution state.
  444. *)
  445. *) Description:
  446. *) Put SET command settings back the way we found them.
  447. *)
  448. PRIVATE m.i, m.delilen, m.ldelimi, m.rdelimi
  449. IF EMPTY(m.g_projalias)
  450.    RETURN
  451. ENDIF
  452. SELECT (m.g_projalias)
  453. USE
  454. DO cleanscrn
  455. DO clearareas  && clear the workareas we opened during this run
  456. SELECT (m.g_workarea)
  457.  
  458. DELETE FILE (m.g_tmpfile)
  459. DELETE FILE (m.g_idxfile)
  460.  
  461. m.delilen = LEN(m.delimiters)
  462. m.ldelimi = SUBSTR(m.delimiters,1,;
  463.    IIF(MOD(m.delilen,2)=0,m.delilen/2,CEILING(m.delilen/2)))
  464. m.rdelimi = SUBSTR(m.delimiters,;
  465.    IIF(MOD(m.delilen,2)=0,m.delilen/2+1,CEILING(m.delilen/2)+1))
  466. SET TEXTMERGE DELIMITERS TO m.ldelimi, m.rdelimi
  467.  
  468. SET FIELDS TO &mfieldsto
  469. IF m.fields = "ON"
  470.    SET FIELDS ON
  471. ELSE
  472.    SET FIELDS OFF
  473. ENDIF
  474. IF m.cursor = "ON"
  475.    SET CURSOR ON
  476. ELSE
  477.    SET CURSOR OFF
  478. ENDIF
  479. IF m.consol = "ON"
  480.    SET CONSOLE ON
  481. ELSE
  482.    SET CONSOLE OFF
  483. ENDIF
  484. IF m.escape = "ON"
  485.    SET ESCAPE ON
  486. ELSE
  487.    SET ESCAPE OFF
  488. ENDIF
  489. IF m.bell = "ON"
  490.    SET BELL ON
  491. ELSE
  492.    SET BELL OFF
  493. ENDIF
  494. IF m.exact = "ON"
  495.    SET EXACT ON
  496. ELSE
  497.    SET EXACT OFF
  498. ENDIF
  499. IF m.safety = "ON"
  500.    SET SAFETY ON
  501. ELSE
  502.    SET SAFETY OFF
  503. ENDIF
  504. IF m.comp = "ON"
  505.    SET COMPATIBLE ON
  506. ENDIF
  507. IF m.print = "ON"
  508.    SET PRINT ON
  509. ENDIF
  510. SET DECIMALS TO m.deci
  511. SET MEMOWIDTH TO m.memowidth
  512. SET DEVICE TO &mdevice
  513. SET UDFPARMS TO &mudfparms
  514. SET POINT TO "&mdecpoint"
  515. SET COLLATE TO "&mcollate"
  516. #if "MAC" $ UPPER(VERSION(1))
  517.    IF _MAC
  518.       SET MACDESKTOP &mmacdesk
  519.     ENDIF
  520. #endif
  521. IF m.fixed = "OFF"
  522.    SET FIXED OFF
  523. ENDIF
  524. IF m.trbetween = "ON"
  525.    SET TRBET ON
  526. ENDIF
  527. IF m.talkset = "ON"
  528.    SET TALK ON
  529. ENDIF
  530. IF m.unique = "ON"
  531.    SET UNIQUE ON
  532. ENDIF
  533. SET MESSAGE TO
  534. _PRETEXT = m.origpretext
  535. * Leave this array if dbglevel is defined.  Used for profiling.
  536. * IF TYPE("dbglevel") = "U"
  537. *   RELEASE ticktock
  538. * ENDIF
  539.  
  540. ON ERROR &onerror
  541. RETURN
  542.  
  543. *!*****************************************************************************
  544. *!
  545. *!      Procedure: CLEANSCRN
  546. *!
  547. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  548. *!
  549. *!*****************************************************************************
  550. PROCEDURE cleanscrn
  551. *)
  552. *) CLEANSCRN - Clean up after each screen set generation, once per platform
  553. *)
  554. PRIVATE m.i
  555. FOR m.i = 1 TO m.g_nscreens
  556.    m.g_screen = i
  557.    IF NOT EMPTY(g_screens[m.i,4])
  558.       LOOP
  559.    ENDIF
  560.    IF USED(g_screens[m.i,5])
  561.       SELECT (g_screens[m.i,5])
  562.       USE
  563.    ENDIF
  564. ENDFOR
  565. m.g_screen = 0
  566. RETURN
  567.  
  568. *!*****************************************************************************
  569. *!
  570. *!      Procedure: BUILDENABLE
  571. *!
  572. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  573. *!
  574. *!          Calls: PREPFILE           (procedure in GENSCRN.PRG)
  575. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  576. *!
  577. *!*****************************************************************************
  578. PROCEDURE buildenable
  579. *)
  580. *> BUILDENABLE - Enable code generation.
  581. *)
  582. *) Description:
  583. *) Call prepfile to open output file(s).
  584. *) If error(s) encountered in prepfile then exit, otherwise
  585. *) SET TEXTMERGE ON
  586. *)
  587. *) Returns: .T. on success; .F. on failure
  588. *)
  589. DO prepfile WITH m.g_outfile, m.g_orghandle
  590. DO prepfile WITH m.g_tmpfile, m.g_tmphandle
  591.  
  592. SET TEXTMERGE ON
  593. ON ESCAPE DO eschandler
  594. SET ESCAPE ON
  595. RETURN
  596.  
  597. *!*****************************************************************************
  598. *!
  599. *!      Procedure: BUILDDISABLE
  600. *!
  601. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  602. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  603. *!
  604. *!          Calls: CLOSEFILE          (procedure in GENSCRN.PRG)
  605. *!
  606. *!*****************************************************************************
  607. PROCEDURE builddisable
  608. *)
  609. *) BUILDDISABLE - Disable code generation.
  610. *)
  611. *) Description:
  612. *) Issue the command SET TEXTMERGE OFF.
  613. *) Close the generated output file.
  614. *) Close the temporary file.
  615. *) If anything goes wrong display appropriate message to the user.
  616. *)
  617. SET ESCAPE OFF
  618. ON ESCAPE
  619. SET TEXTMERGE OFF
  620. IF m.g_havehand
  621.    DO closefile WITH m.g_orghandle
  622.    DO closefile WITH m.g_tmphandle
  623. ENDIF
  624. RETURN
  625.  
  626. *!*****************************************************************************
  627. *!
  628. *!      Procedure: PREPPARAMS
  629. *!
  630. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  631. *!
  632. *!          Calls: CHECKPARAM()       (function  in GENSCRN.PRG)
  633. *!
  634. *!*****************************************************************************
  635. PROCEDURE prepparams
  636. *)
  637. *) PREPPARAMS - Read through each of the platforms on screen 1
  638. *)              and ensure that any parameter statements in #SECTION 1
  639. *)              are identical.
  640. *)
  641. PRIVATE m.i, m.j, m.dbalias, m.thisparam
  642. m.g_screen = 1
  643. m.dbalias = g_screens[m.g_screen,5]
  644. SELECT (m.dbalias)
  645. DO CASE
  646. CASE g_screens[m.g_screen,6] OR !multiplat()
  647.    * DOS 2.0 screen or just one 2.5 platform being generated
  648.    GO TOP
  649.    RETURN checkparam(m.g_screen)
  650.  
  651. OTHERWISE
  652.    FOR m.j = 1 TO c_maxplatforms
  653.       LOCATE FOR ALLTRIM(UPPER(platform)) = g_platlist[m.j] AND objtype = c_otscreen
  654.       DO CASE
  655.       CASE !FOUND() OR EMPTY(setupcode)
  656.          LOOP
  657.       CASE !checkparam(m.g_screen)
  658.          RETURN .F.
  659.       ENDCASE
  660.    ENDFOR
  661. ENDCASE
  662. m.g_screen = 0
  663. RETURN .T.
  664.  
  665. *!*****************************************************************************
  666. *!
  667. *!       Function: CLEANPARAM
  668. *!
  669. *!      Called by: CHECKPARAM()       (function  in GENSCRN.PRG)
  670. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  671. *!
  672. *!*****************************************************************************
  673. FUNCTION cleanparam
  674. *)
  675. *) CLEANPARAM - Clean up a parameter string so that it may be compared with another one.
  676. *)              This function replaces tabs with spaces, capitalizes the string, merges
  677. *)              forces single spacing, and strips out CR/LF characters.
  678. *)
  679. PARAMETER m.p, m.cp
  680. m.cp = UPPER(ALLTRIM(CHRTRAN(m.p,";"+CHR(13)+CHR(10),"")))   && drop CR/LF and continuation chars
  681. m.cp = CHRTRAN(m.cp,CHR(9),' ')   && tabs to spaces
  682. DO WHILE AT('  ',m.cp) > 0         && reduce multiple spaces to a single space
  683.    m.cp = STRTRAN(m.cp,'  ',' ')
  684. ENDDO
  685. DO WHILE AT(', ',m.cp) > 0         && drop spaces after commas
  686.    m.cp = STRTRAN(m.cp,', ',',')
  687. ENDDO
  688. RETURN m.cp
  689.  
  690. *!*****************************************************************************
  691. *!
  692. *!       Function: CHECKPARAM
  693. *!
  694. *!      Called by: PREPPARAMS         (procedure in GENSCRN.PRG)
  695. *!
  696. *!          Calls: GETPARAM()         (function  in GENSCRN.PRG)
  697. *!               : CLEANPARAM()       (function  in GENSCRN.PRG)
  698. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  699. *!
  700. *!*****************************************************************************
  701. FUNCTION checkparam
  702. *)
  703. *) CHECKPARAM - See if this parameter statement matches others we have found. Generate
  704. *)               an error message if it doesn't.  g_parameter is empty if we haven't
  705. *)               seen any parameter statements yet, or it contains the variables in the
  706. *)               parameter statement (but not the PARAMETERS keyword) if we have seen one
  707. *)               before.
  708. *)
  709. PARAMETER m.i
  710. PRIVATE m.thisparam
  711. m.thisparam = getparam("setupcode")  && get parameter from setup snippet at current record position
  712.  
  713. IF !EMPTY(m.thisparam)
  714.    IF !EMPTY(m.g_parameter) AND !(cleanparam(m.thisparam) == cleanparam(m.g_parameter))
  715.       DO errorhandler WITH "DOS and Windows setup code has different parameters", ;
  716.          LINENO(), c_error_3
  717.       RETURN .F.
  718.    ELSE
  719.       g_parameter = m.thisparam
  720.    ENDIF
  721. ENDIF
  722. RETURN .T.
  723.  
  724. *!*****************************************************************************
  725. *!
  726. *!      Procedure: ISVALIDPLAT
  727. *!
  728. *!      Called by: PREPPLATFORM
  729. *!
  730. *!*****************************************************************************
  731. FUNCTION isvalidplat
  732. PARAMETER platname
  733. RETURN IIF(INLIST(UPPER(platname), c_dos, c_windows, c_mac, c_unix), .T., .F.)
  734.  
  735. *!*****************************************************************************
  736. *!
  737. *!      Procedure: PREPPLATFORM
  738. *!
  739. *!      Called by: GENSCRN.PRG
  740. *!
  741. *!*****************************************************************************
  742. PROCEDURE prepplatform
  743. *)
  744. *) PREPPLATFORM - Create an array of platform names in the screen set.  Make sure that
  745. *)                there is at least one common platform across all SCXs in the screen set.
  746. *)                g_platforms comes out of this procedure containing the intersection of
  747. *)                the set of platforms in each screen.  If there are no common platforms
  748. *)                across all screens, it will be empty.
  749. *)
  750. PRIVATE m.i, m.j, m.firstscrn, m.p_cur, m.tempplat, m.numtodel, m.in_area, ;
  751.    m.rcount
  752. IF m.g_nscreens <= 0
  753.    RETURN .F.
  754. ENDIF
  755.  
  756. DIMENSION t_platforms[ALEN(g_platforms)]
  757. m.in_area = SELECT()
  758. IF g_screens[1,6]         && First screen is a DOS 2.0 screen
  759.    g_platforms = ""
  760.    g_platforms[1] = "DOS"
  761. ELSE
  762.    IF _DOS
  763.       * Avoid selecting into an array to conserve memory
  764.       SELECT DISTINCT platform FROM (g_screens[1,1]) ;
  765.           WHERE isvalidplat(platform) ; 
  766.           INTO CURSOR curstemp ;
  767.          ORDER BY platform
  768.       m.rcount = _TALLY
  769.       SELECT curstemp
  770.       DIMENSION g_platforms[m.rcount]
  771.       GOTO TOP
  772.       FOR m.i = 1 TO m.rcount
  773.          g_platforms[m.i] = curstemp->platform
  774.          SKIP
  775.       ENDFOR
  776.       USE                                             && get rid of the cursor
  777.    ELSE
  778.       SELECT DISTINCT platform FROM (g_screens[1,1]) ;
  779.           WHERE isvalidplat(platform) ;
  780.           INTO ARRAY g_platforms ;
  781.          ORDER BY platform
  782.    ENDIF
  783. ENDIF
  784.  
  785. m.numtodel = 0   && number of array elements to delete
  786. FOR m.i = 2 TO m.g_nscreens
  787.    m.g_screen = m.i
  788.    IF g_screens[m.i,6]   && DOS 2.0 screen
  789.       DIMENSION t_platforms[1]
  790.       t_platforms = ""
  791.       t_platforms[1] = "DOS"
  792.    ELSE
  793.       IF _DOS
  794.          * Avoid selecting into an array to conserve memory
  795.          SELECT DISTINCT platform FROM (g_screens[m.i,1]) ;
  796.                 WHERE isvalidplat(platform) ;
  797.                 INTO CURSOR curstemp ;
  798.             ORDER BY platform
  799.          m.rcount = _TALLY
  800.          SELECT curstemp
  801.          DIMENSION t_platforms[m.rcount]
  802.          GOTO TOP
  803.          FOR m.k = 1 TO m.rcount
  804.             t_platforms[m.k] = curstemp->platform
  805.             SKIP
  806.          ENDFOR
  807.          USE                                             && get rid of the cursor
  808.       ELSE
  809.          SELECT DISTINCT platform FROM (g_screens[m.i,1]) ;
  810.                 WHERE isvalidplat(platform) ;
  811.              INTO ARRAY t_platforms ;
  812.             ORDER BY platform
  813.       ENDIF
  814.    ENDIF
  815.  
  816.    * Update g_platforms with the intersection of g_platforms
  817.    *  and t_platforms
  818.    m.j = 1
  819.    DO WHILE m.j < ALEN(g_platforms) -  m.numtodel
  820.       IF !INLIST(TYPE("g_platforms[m.j]"),"L","U") ;
  821.             AND ASCAN(t_platforms,g_platforms[m.j]) = 0
  822.          =ADEL(g_platforms,m.j)
  823.          m.numtodel = m.numtodel + 1
  824.       ELSE
  825.          m.j = m.j + 1
  826.       ENDIF
  827.    ENDDO
  828.  
  829. ENDFOR
  830. SELECT (m.in_area)
  831.  
  832. m.g_screen = 0
  833. * Shrink the unique platform array if necessary
  834. DIMENSION g_platforms[ALEN(g_platforms)-m.numtodel]
  835.  
  836. IF ALEN(g_platforms) <= 0 OR EMPTY(g_platforms[1])
  837.    WAIT WINDOW  "No common platforms in these screens.  Press any key."
  838.    CANCEL
  839. ELSE
  840.    FOR m.j = 1 TO ALEN(g_platforms)
  841.       g_platforms[m.j] = UPPER(ALLTRIM(g_platforms[m.j]))
  842.    ENDFOR
  843.  
  844.    * If the current platform is in the list of common platforms, put it at the top
  845.    m.p_cur = ASCAN(g_platforms, m.g_thisvers)
  846.    IF m.p_cur > 1
  847.       m.tempplat = g_platforms[1]
  848.       g_platforms[1] = g_platforms[m.p_cur]
  849.       g_platforms[m.p_cur] = m.tempplat
  850.    ENDIF
  851. ENDIF
  852. RETURN .T.
  853.  
  854. *!*****************************************************************************
  855. *!
  856. *!      Procedure: PREPFILE
  857. *!
  858. *!      Called by: BUILDENABLE        (procedure in GENSCRN.PRG)
  859. *!
  860. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  861. *!
  862. *!*****************************************************************************
  863. PROCEDURE prepfile
  864. *)
  865. *) PREPFILE - Create and open the application output file.
  866. *)
  867. *) Description:
  868. *) Create or open a file that will hold the generated application.
  869. *) If error(s) encountered at any time issue an error message
  870. *) and return .F.
  871. *)
  872. PARAMETER m.filename, m.ifp
  873. PRIVATE m.msg
  874. m.ifp = FCREATE(m.filename)
  875.  
  876. IF (m.ifp = -1)
  877.    m.msg = "Cannot open "+LOWER(m.filename)
  878.    m.g_havehand = .F.
  879.    DO errorhandler WITH m.msg, LINENO(), c_error_3
  880. ELSE
  881.    m.g_havehand = .T.
  882. ENDIF
  883. RETURN
  884.  
  885. *!*****************************************************************************
  886. *!
  887. *!      Procedure: CLOSEFILE
  888. *!
  889. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  890. *!               : BUILDDISABLE       (procedure in GENSCRN.PRG)
  891. *!
  892. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  893. *!
  894. *!*****************************************************************************
  895. PROCEDURE closefile
  896. *)
  897. *) CLOSEFILE - Close a low level file opened with FCREATE.
  898. *)
  899. PARAMETER m.ifp
  900. IF (m.ifp > 0) AND !FCLOSE(m.ifp)
  901.    DO errorhandler WITH "Unable to close the generated file",;
  902.       LINENO(), c_error_2
  903. ENDIF
  904. RETURN
  905.  
  906. *!*****************************************************************************
  907. *!
  908. *!       Function: PREPSCREENS
  909. *!
  910. *!      Called by: GENSCRN.PRG
  911. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  912. *!
  913. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  914. *!               : SCREENUSED()       (function  in GENSCRN.PRG)
  915. *!               : NOTEAREA           (procedure in GENSCRN.PRG)
  916. *!               : GETPLATFORM()      (function  in GENSCRN.PRG)
  917. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  918. *!               : PREPWNAMES         (procedure in GENSCRN.PRG)
  919. *!
  920. *!*****************************************************************************
  921. FUNCTION prepscreens
  922. *)
  923. *) PREPSCREENS - Prepare screen file(s) for processing.
  924. *)
  925. *) Description:
  926. *) Called once per platform.
  927. *)
  928. *) Open PJX database, index it to find all screen files belonging
  929. *) to a screen set if part of a project.
  930. *)
  931. *) Open all screen file(s).  If screen file already opened, then
  932. *) select it.  Assign unique aliases to screen with name conflicts.
  933. *) If error is encountered while opening any of the screen files
  934. *) this program will be aborted.
  935. *)
  936. PARAMETER m.gen_version
  937.  
  938. PRIVATE m.status, m.projdbf, m.saverec, m.dbname, m.dbalias
  939. m.status = .T.
  940.  
  941. SELECT (m.g_projalias)
  942. SET SAFETY OFF
  943. INDEX ON STR(scrnorder) TO (m.g_idxfile) COMPACT
  944. SET SAFETY ON
  945. GO TOP
  946. SCAN FOR NOT DELETED() AND setid = m.g_keyno AND TYPE = 's'
  947.    m.saverec = RECNO()
  948.    m.dbname  = FULLPATH(ALLTRIM(name), m.g_projpath)
  949.    if right(m.dbname,1) = ":"
  950.       m.dbname = m.dbname + justfname(name)
  951.    endif
  952.    m.g_nscreens = m.g_nscreens + 1
  953.  
  954.    IF MOD(m.g_nscreens,5)=0
  955.       DIMENSION g_screens[ALEN(g_screens,1)+5,7]
  956.       DIMENSION g_wnames [ALEN(g_wnames)+5,C_MAXPLATFORMS]
  957.       DIMENSION g_platforms [ALEN(g_platforms)+5]
  958.       DIMENSION g_firstproc [ALEN(g_firstproc)+5]
  959.    ENDIF
  960.  
  961.    m.dbalias = LEFT(basename(m.dbname), c_aliaslen)
  962.    IF screenused(m.dbalias, m.dbname)
  963.       g_screens[m.g_nscreens,4] = .T.
  964.    ELSE
  965.       g_screens[m.g_nscreens,4] = .F.
  966.         IF FILE(m.dbname)
  967.          SELECT 0
  968.          USE (m.dbname) AGAIN ALIAS (g_screens[m.g_nscreens,5])
  969.          DO notearea
  970.         ELSE
  971.            DO errorhandler WITH "Could not find SCX file: "+m.dbname, ;
  972.                LINENO(),c_error_2
  973.             RETURN .F.
  974.        ENDIF
  975.    ENDIF
  976.  
  977.    DO CASE
  978.    CASE FCOUNT() = c_scxflds
  979.       LOCATE FOR platform = m.gen_version
  980.       IF FOUND()
  981.          g_screens[m.g_nscreens,6] = .F.
  982.          g_screens[m.g_nscreens,7] = platform
  983.       ELSE
  984.          g_screens[m.g_nscreens,6] = .F.
  985.          g_screens[m.g_nscreens,7] = getplatform()
  986.       ENDIF
  987.    CASE FCOUNT() = c_20scxflds
  988.       g_screens[m.g_nscreens,6] = .T.
  989.       g_screens[m.g_nscreens,7] = "DOS"
  990.    OTHERWISE
  991.       DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  992.          c_error_2
  993.       RETURN .F.
  994.    ENDCASE
  995.    g_screens[m.g_nscreens,1] = m.dbname
  996.  
  997.    IF NOT EMPTY(STYLE)
  998.       IF EMPTY(name)
  999.          g_screens[m.g_nscreens,2] = LOWER(SYS(2015))
  1000.       ELSE
  1001.          g_screens[m.g_nscreens,2] = ALLTRIM(LOWER(name))
  1002.       ENDIF
  1003.       DO prepwnames WITH m.g_nscreens
  1004.    ENDIF
  1005.  
  1006.    SELECT (m.g_projalias)
  1007.    GOTO RECORD m.saverec
  1008.    g_screens[m.g_nscreens,3] = m.saverec
  1009. ENDSCAN
  1010.  
  1011. RETURN m.status
  1012.  
  1013. *!*****************************************************************************
  1014. *!
  1015. *!       Function: NEWWINDOWS
  1016. *!
  1017. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1018. *!
  1019. *!*****************************************************************************
  1020. FUNCTION newwindows
  1021. * Initialize the windows name array and other window-related
  1022. * variables for each platform.
  1023. g_wndows = ""                  && array of window names
  1024. m.g_nwindows = 0               && number of windows
  1025. m.g_lastwindow = ""            && name of last window generated for this platform
  1026. RETURN
  1027.  
  1028. *!*****************************************************************************
  1029. *!
  1030. *!       Function: NEWSCHEMES
  1031. *!
  1032. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1033. *!
  1034. *!*****************************************************************************
  1035. FUNCTION newschemes
  1036. *)
  1037. *) NEWSCHEMES - Initialize the color schemes for each screen/platform
  1038. *)
  1039. m.g_defasch  = 0
  1040. m.g_defasch2 = 0
  1041. RETURN
  1042.  
  1043. *!*****************************************************************************
  1044. *!
  1045. *!       Function: NEWDBFS
  1046. *!
  1047. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1048. *!
  1049. *!*****************************************************************************
  1050. FUNCTION newdbfs
  1051. *)
  1052. *) NEWDBFS - Initialize the databases name array for each platform
  1053. *)
  1054. m.g_dbfs = ""
  1055. RETURN
  1056.  
  1057. *!*****************************************************************************
  1058. *!
  1059. *!      Procedure: NEWREADCLAUSES
  1060. *!
  1061. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1062. *!
  1063. *!*****************************************************************************
  1064. PROCEDURE newreadclauses
  1065. *)
  1066. *) NEWREADCLAUSES - Initialize the variables that control which READ and WINDOW clauses are
  1067. *)                    emitted.
  1068. *)
  1069. m.g_validtype  = ""
  1070. m.g_validname  = ""
  1071. m.g_whentype   = ""
  1072. m.g_whenname   = ""
  1073. m.g_actitype   = ""
  1074. m.g_actiname   = ""
  1075. m.g_deattype   = ""
  1076. m.g_deatname   = ""
  1077. m.g_showtype   = ""
  1078. m.g_showname   = ""
  1079. m.g_showexpr   = ""
  1080. RETURN
  1081.  
  1082. *!*****************************************************************************
  1083. *!
  1084. *!      Procedure: NEWDIRECTIVES
  1085. *!
  1086. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1087. *!
  1088. *!*****************************************************************************
  1089. PROCEDURE newdirectives
  1090. m.g_windclauses= ""            && #WCLAUSES directive
  1091. m.g_rddir      = .F.           && Is there a #READCLAUSES directive?
  1092. m.g_rddirno    = 0             && Number of 1st screen with #READ directive
  1093. RETURN
  1094.  
  1095. *!*****************************************************************************
  1096. *!
  1097. *!       Function: GETPLATFORM
  1098. *!
  1099. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1100. *!
  1101. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1102. *!
  1103. *!*****************************************************************************
  1104. FUNCTION getplatform
  1105. *)
  1106. *) GETPLATFORM - Find which Platform we are supposed to generate for.  If we are trying to
  1107. *)               generate for Windows, but there are no windows records in the SCX, use
  1108. *)               this function to determine which records to use.
  1109. *)
  1110. IF m.g_genvers = 'WINDOWS' OR m.g_genvers = 'MAC'
  1111.    LOCATE FOR platform = IIF(m.g_genvers = 'WINDOWS', 'MAC', 'WINDOWS')
  1112.    IF FOUND()
  1113.       RETURN platform
  1114.    ELSE
  1115.       LOCATE FOR platform = 'DOS'
  1116.       IF FOUND()
  1117.          RETURN 'DOS'
  1118.       ELSE
  1119.          LOCATE FOR platform = 'UNIX'
  1120.          IF FOUND()
  1121.             RETURN 'UNIX'
  1122.          ELSE
  1123.             DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1124.                c_error_2
  1125.          ENDIF
  1126.       ENDIF
  1127.    ENDIF
  1128. ELSE
  1129.    LOCATE FOR platform = IIF(m.g_genvers = 'DOS', 'UNIX', 'DOS')
  1130.    IF FOUND()
  1131.       RETURN platform
  1132.    ELSE
  1133.       LOCATE FOR platform = 'WINDOWS'
  1134.       IF FOUND()
  1135.          RETURN 'DOS'
  1136.       ELSE
  1137.          LOCATE FOR platform = 'MAC'
  1138.          IF FOUND()
  1139.             RETURN 'UNIX'
  1140.          ELSE
  1141.             DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1142.                c_error_2
  1143.          ENDIF
  1144.       ENDIF
  1145.    ENDIF
  1146. ENDIF
  1147. RETURN ""
  1148.  
  1149.  
  1150. *!*****************************************************************************
  1151. *!
  1152. *!      Procedure: PREPWNAMES
  1153. *!
  1154. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1155. *!
  1156. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  1157. *!               : SKIPWHITESPACE()   (function  in GENSCRN.PRG)
  1158. *!
  1159. *!*****************************************************************************
  1160. PROCEDURE prepwnames
  1161. *)
  1162. *) PREPWNAMES - Store #WNAME directive strings.  They must be in the setup snippet.
  1163. *)
  1164. PARAMETER m.scrnno
  1165. PRIVATE m.lineno, m.textline
  1166. m.lineno = ATCLINE('#WNAM',setupcode)
  1167. IF m.lineno > 0
  1168.    m.textline = MLINE(setupcode,m.lineno)
  1169.    DO killcr WITH m.textline
  1170.    IF g_screens[m.scrnno,6]   && DOS 2.0 screen
  1171.       IF ATC('#WNAM',m.textline) = 1
  1172.          g_wnames[m.scrnno, getplatnum("DOS")] = skipwhitespace(m.textline)
  1173.       ENDIF
  1174.    ELSE
  1175.       IF ATC('#WNAM',m.textline) = 1
  1176.          g_wnames[m.scrnno, getplatnum(platform)] = skipwhitespace(m.textline)
  1177.       ENDIF
  1178.    ENDIF
  1179. ENDIF
  1180. RETURN
  1181.  
  1182. *!*****************************************************************************
  1183. *!
  1184. *!       Function: SCREENUSED
  1185. *!
  1186. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1187. *!
  1188. *!          Calls: ILLEGALNAME()      (function  in GENSCRN.PRG)
  1189. *!
  1190. *!*****************************************************************************
  1191. FUNCTION screenused
  1192. *)
  1193. *) SCREENUSED - Check to see if screen file already opened.
  1194. *)
  1195. PARAMETER m.dbalias, m.fulldbname
  1196. m.dbalias = LEFT(m.dbalias,c_aliaslen)
  1197. IF NOT USED(m.dbalias)
  1198.    IF illegalname(m.dbalias)
  1199.       g_screens[m.g_nscreens,5] = "S"+SUBSTR(LOWER(SYS(3)),2,8)
  1200.    ELSE
  1201.       g_screens[m.g_nscreens,5] = m.dbalias
  1202.    ENDIF
  1203.    RETURN .F.
  1204. ENDIF
  1205. SELECT (m.dbalias)
  1206. IF RAT(".SCX",DBF())<>0 AND m.fulldbname=DBF()
  1207.    g_screens[m.g_nscreens,5] = m.dbalias
  1208.    RETURN .T.
  1209. ELSE
  1210.    g_screens[m.g_nscreens,5] = "S"+SUBSTR(LOWER(SYS(3)),2,8)
  1211. ENDIF
  1212. RETURN .F.
  1213.  
  1214. *!*****************************************************************************
  1215. *!
  1216. *!       Function: ILLEGALNAME
  1217. *!
  1218. *!      Called by: SCREENUSED()       (function  in GENSCRN.PRG)
  1219. *!
  1220. *!*****************************************************************************
  1221. FUNCTION illegalname
  1222. *)
  1223. *) ILLEGALNAME - Check if default alias will be used when this
  1224. *)               database is USEd. (i.e., 1st letter is not A-Z,
  1225. *)                a-z or '_', or any one of ramaining letters is not
  1226. *)                alphanumeric.)
  1227. *)
  1228. PARAMETER m.dname
  1229. PRIVATE m.start, m.aschar, m.length
  1230. m.length = LEN(m.dname)
  1231. m.start  = 0
  1232. IF m.length = 1
  1233.    *
  1234.    * If length 1, then check if default alias can be used,
  1235.    * i.e., name is different than A-J and a-j.
  1236.    *
  1237.    m.aschar = ASC(m.dname)
  1238.    IF (m.aschar >= 65 AND m.aschar <= 74) OR ;
  1239.          (m.aschar >= 97 AND m.aschar <= 106)
  1240.       RETURN .T.
  1241.    ENDIF
  1242. ENDIF
  1243. DO WHILE m.start < m.length
  1244.    m.start  = m.start + 1
  1245.    m.aschar = ASC(SUBSTR(m.dname, m.start, 1))
  1246.    IF m.start<>1 AND (m.aschar >= 48 AND m.aschar <= 57)
  1247.       LOOP
  1248.    ENDIF
  1249.    IF NOT ((m.aschar >= 65 AND m.aschar <= 90) OR ;
  1250.          (m.aschar >= 97 AND m.aschar <= 122) OR m.aschar = 95)
  1251.       RETURN .T.
  1252.    ENDIF
  1253. ENDDO
  1254. RETURN .F.
  1255.  
  1256. *!*****************************************************************************
  1257. *!
  1258. *!       Function: OPENPROJDBF
  1259. *!
  1260. *!      Called by: GENSCRN.PRG
  1261. *!
  1262. *!          Calls: NOTEAREA           (procedure in GENSCRN.PRG)
  1263. *!               : STRIPEXT()         (function  in GENSCRN.PRG)
  1264. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1265. *!               : REFRESHPREFS       (procedure in GENSCRN.PRG)
  1266. *!               : GETWITHLIST        (procedure in GENSCRN.PRG)
  1267. *!
  1268. *!*****************************************************************************
  1269. FUNCTION openprojdbf
  1270. *)
  1271. *) OPENPROJDBF - Prepare Project dbf for processing.
  1272. *)
  1273. *) Description:
  1274. *) Check to see if projdbf has an appropriate number of fields.
  1275. *) Find the screen set record.
  1276. *) Extract information from the SETID record.
  1277. *)
  1278. PARAMETER m.projdbf, m.recno
  1279.  
  1280. SELECT 0
  1281. IF USED("projdbf")
  1282.    m.g_projalias = "P"+SUBSTR(LOWER(SYS(3)),2,8)
  1283. ELSE
  1284.    m.g_projalias = "projdbf"
  1285. ENDIF
  1286. USE (m.projdbf) ALIAS (m.g_projalias)
  1287. DO notearea
  1288. IF versnum() > "2.5"
  1289.    SET NOCPTRANS TO devinfo, arranged, symbols, object
  1290. ENDIF
  1291. m.g_errlog = stripext(m.projdbf)
  1292. m.g_projpath = SUBSTR(m.projdbf,1,RAT("\",m.projdbf))
  1293.  
  1294. IF FCOUNT() <> c_pjxflds
  1295.    IF FCOUNT() = c_pjx20flds
  1296.       DO errorhandler WITH "Invalid 2.0 project file passed to GenScrn.",;
  1297.          LINENO(), c_error_2
  1298.    ELSE
  1299.       DO errorhandler WITH "Generator out of date.",;
  1300.          LINENO(), c_error_2
  1301.    ENDIF
  1302.    RETURN .F.
  1303. ENDIF
  1304.  
  1305. DO refreshprefs
  1306. GOTO m.recno
  1307. m.g_keyno        = setid
  1308. m.g_outfile      = ALLTRIM(SUBSTR(outfile,1,AT(c_null,outfile)-1))
  1309. m.g_outfile      = FULLPATH(m.g_outfile, m.g_projpath)
  1310. IF RIGHT(m.g_outfile,1) = ":"
  1311.    m.g_outfile = m.g_outfile + justfname(outfile)
  1312. ENDIF
  1313. m.g_openfiles    = openfiles
  1314. m.g_closefiles   = closefiles
  1315. m.g_defwin       = defwinds
  1316. m.g_relwin       = relwinds
  1317. m.g_readcycle    = readcycle
  1318. m.g_readlock     = NOLOCK
  1319. m.g_readmodal    = MODAL
  1320. m.g_readborder   = nologo
  1321. m.g_multreads    = multreads
  1322. m.g_allplatforms = !savecode
  1323. DO getwithlist
  1324. RETURN
  1325.  
  1326. *!*****************************************************************************
  1327. *!
  1328. *!      Procedure: GETWITHLIST
  1329. *!
  1330. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  1331. *!
  1332. *!*****************************************************************************
  1333. PROCEDURE getwithlist
  1334. *)
  1335. *) GETWITHLIST - Construct the list for READ level WITH clause.  The
  1336. *) window list is in the project file, stored as CR separated strings
  1337. *) possibly terminated with a NULL.
  1338. *)
  1339.  
  1340. m.g_withlist = assocwinds
  1341. * Drop any nulls
  1342. m.g_withlist = ALLTRIM(CHRTRAN(m.g_withlist, CHR(0), ""))
  1343. * Translate any CRs/LFs into commas
  1344. m.g_withlist = CHRTRAN(m.g_withlist, c_cret+c_lf, ",,")
  1345. * Sanity check for duplicate commas
  1346. m.g_withlist = STRTRAN(m.g_withlist, ",,", ",")   && shouldn't be necessary
  1347. IF RIGHT(m.g_withlist,1) = ","
  1348.    m.g_withlist = LEFT(m.g_withlist, LEN(m.g_withlist) - 1)
  1349. ENDIF
  1350. IF LEFT(m.g_withlist,1) = ","
  1351.    m.g_withlist = RIGHT(m.g_withlist, LEN(m.g_withlist) - 1)
  1352. ENDIF
  1353. RETURN
  1354.  
  1355. *!*****************************************************************************
  1356. *!
  1357. *!      Procedure: REFRESHPREFS
  1358. *!
  1359. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  1360. *!
  1361. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1362. *!               : SUBDEVINFO()       (function  in GENSCRN.PRG)
  1363. *!
  1364. *!*****************************************************************************
  1365. PROCEDURE refreshprefs
  1366. *)
  1367. *) REFRESHPREFS - Refresh Documentation and Developer preferences.
  1368. *)
  1369. *) Description:
  1370. *) Get the newest preferences for documentation style and developer
  1371. *) data from the HEADER record.
  1372. *)
  1373. PRIVATE m.start
  1374. LOCATE FOR TYPE = "H"
  1375. IF NOT FOUND ()
  1376.    DO errorhandler WITH "Missing header record in "+m.projdbf,;
  1377.       LINENO(), c_error_2
  1378.    RETURN
  1379. ENDIF
  1380. IF _MAC
  1381.     * On the Mac, the home directory will be stored in homedir unless
  1382.     * it is in a non-DOS format (e.g., contains spaces), in which case
  1383.     * it is stored in the assocwinds field.  This subterfuge is to 
  1384.     * maintain cross platform compatibility of the projects.
  1385.     IF !EMPTY(assocwinds)
  1386.         m.g_homedir = ALLTRIM(SUBSTR(assocwinds,1,AT(c_null,assocwinds)-1))
  1387.     ELSE
  1388.         m.g_homedir = ALLTRIM(SUBSTR(homedir,1,AT(c_null,homedir)-1))
  1389.         IF RIGHT(m.g_homedir,1) <> "\"
  1390.            m.g_homedir = m.g_homedir + "\"
  1391.         ENDIF
  1392.     ENDIF
  1393.     * There is a potential problem with the setting of the home directory on the
  1394.     * Mac when we generate a screen that isn't inside a true project. The home directory
  1395.     * will be set to the temporary file directory, which is not where we want to look for
  1396.     * relative paths. Adjust it here.
  1397.     IF UPPER(ALLTRIM(justpath(m.g_homedir))) == UPPER(sys(2023)) AND alldigits(juststem(m.g_homedir))
  1398.         SKIP
  1399.         m.g_target = name
  1400.         IF AT(CHR(0), name) > 0
  1401.             m.g_target = ALLTRIM(justpath(SUBSTR(name,1,AT(c_null,name)-1)))
  1402.         ENDIF
  1403.         m.g_homedir = FULLPATH(m.g_target, m.g_homedir)
  1404.            IF RIGHT(m.g_homedir,1) <> "\"
  1405.                m.g_homedir = m.g_homedir + "\"
  1406.         ENDIF
  1407.         SKIP -1
  1408.     ENDIF
  1409. ELSE
  1410.     m.g_homedir = ALLTRIM(SUBSTR(homedir,1,AT(c_null,homedir)-1))
  1411.     IF RIGHT(m.g_homedir,1) <> "\"
  1412.        m.g_homedir = m.g_homedir + "\"
  1413.     ENDIF
  1414. ENDIF
  1415.  
  1416. m.start = 1
  1417. m.g_devauthor = subdevinfo(m.start,c_authorlen,m.g_devauthor)
  1418.  
  1419. m.start = m.start + c_authorlen + 1
  1420. m.g_devcompany = subdevinfo(m.start,c_complen,m.g_devcompany)
  1421.  
  1422. m.start = m.start + c_complen + 1
  1423. m.g_devaddress = subdevinfo(m.start,c_addrlen,m.g_devaddress)
  1424.  
  1425. m.start = m.start + c_addrlen + 1
  1426. m.g_devcity = subdevinfo(m.start,c_citylen,m.g_devcity)
  1427.  
  1428. m.start = m.start + c_citylen + 1
  1429. m.g_devstate = subdevinfo(m.start,c_statlen,m.g_devstate)
  1430.  
  1431. m.start = m.start + c_statlen + 1
  1432. m.g_devzip = subdevinfo(m.start,c_ziplen,m.g_devzip)
  1433.  
  1434. m.start = m.start + c_ziplen + 1
  1435. m.g_devctry = subdevinfo(m.start,c_countrylen,m.g_devctry)
  1436.  
  1437. IF cmntstyle = 0
  1438.    m.g_corn1 = "╓"
  1439.    m.g_corn2 = "╖"
  1440.    m.g_corn3 = "╙"
  1441.    m.g_corn4 = "╜"
  1442.    m.g_corn5 = "╟"
  1443.    m.g_corn6 = "╢"
  1444.    m.g_horiz = "─"
  1445.    m.g_verti1 = "║"
  1446.    m.g_verti2= "║"
  1447. ENDIF
  1448. RETURN
  1449.  
  1450. *!*****************************************************************************
  1451. *!
  1452. *!       Function: ALLDIGITS
  1453. *!
  1454. *!*****************************************************************************
  1455. FUNCTION alldigits
  1456. PARAMETER m.strg
  1457. PRIVATE m.i, m.thechar, m.retval
  1458. m.retval = .T.
  1459. FOR m.i = 1 TO LEN(m.strg)
  1460.    m.thechar = SUBSTR(m.strg, m.i , 1)
  1461.    IF m.thechar < '0' OR m.thechar > '9'
  1462.       m.retval = .F.
  1463.    ENDIF
  1464. ENDFOR
  1465. RETURN m.retval
  1466.  
  1467.  
  1468. *!*****************************************************************************
  1469. *!
  1470. *!       Function: SUBDEVINFO
  1471. *!
  1472. *!      Called by: REFRESHPREFS       (procedure in GENSCRN.PRG)
  1473. *!
  1474. *!*****************************************************************************
  1475. FUNCTION subdevinfo
  1476. *)
  1477. *) SUBDEVINFO - Extract strings from the DEVINFO memo field.
  1478. *)
  1479. PARAMETER m.start, m.stop, m.default
  1480. PRIVATE m.string
  1481. m.string = SUBSTR(devinfo, m.start, m.stop+1)
  1482. m.string = SUBSTR(m.string, 1, AT(c_null,m.string)-1)
  1483. RETURN IIF(EMPTY(m.string), m.default, m.string)
  1484.  
  1485. **
  1486. ** High Level Controlling Structures in Format file generation.
  1487. **
  1488.  
  1489. *!*****************************************************************************
  1490. *!
  1491. *!      Procedure: BUILD
  1492. *!
  1493. *!      Called by: GENSCRN.PRG
  1494. *!
  1495. *!          Calls: BUILDENABLE        (procedure in GENSCRN.PRG)
  1496. *!               : ACTTHERM           (procedure in GENSCRN.PRG)
  1497. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1498. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1499. *!               : COMBINE            (procedure in GENSCRN.PRG)
  1500. *!               : BUILDDISABLE       (procedure in GENSCRN.PRG)
  1501. *!               : DEACTTHERMO        (procedure in GENSCRN.PRG)
  1502. *!
  1503. *!*****************************************************************************
  1504. PROCEDURE BUILD
  1505. *)
  1506. *) BUILD - Controlling procedure for building of a format file.
  1507. *)
  1508. *) Description:
  1509. *) This procedure is a controlling procedure for the process of
  1510. *) generating a screen file.  It enables building, activates the
  1511. *) thermometer, calls BUILDCTRL and combines two output files,
  1512. *) and finally disables building.
  1513. *) This procedure also makes calls to UPDTHERM to
  1514. *) update the thermometer display.
  1515. *)
  1516.  
  1517. DO buildenable
  1518. DO acttherm WITH "Generating Screen Code..."
  1519. DO updtherm WITH c_therm1 * m.g_numplatforms     && 5%
  1520.  
  1521. DO dispatchbuild
  1522.  
  1523. DO updtherm WITH c_therm7 * m.g_numplatforms     && 95%
  1524. DO combine
  1525. DO updtherm WITH 100 * m.g_numplatforms   && force thermometer to complete
  1526. DO builddisable
  1527.  
  1528. DO deactthermo
  1529. RETURN
  1530.  
  1531. *!*****************************************************************************
  1532. *!
  1533. *!      Procedure: DISPATCHBUILD
  1534. *!
  1535. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  1536. *!
  1537. *!          Calls: COUNTPLATFORMS     (procedure in GENSCRN.PRG)
  1538. *!               : PREPPARAMS         (procedure in GENSCRN.PRG)
  1539. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  1540. *!               : SCANPROC           (procedure in GENSCRN.PRG)
  1541. *!               : GENPARAMETER       (procedure in GENSCRN.PRG)
  1542. *!               : LOOKUPPLATFORM     (procedure in GENSCRN.PRG)
  1543. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  1544. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  1545. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  1546. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1547. *!               : NEWWINDOWS()       (function  in GENSCRN.PRG)
  1548. *!               : NEWDBFS()          (function  in GENSCRN.PRG)
  1549. *!               : NEWREADCLAUSES     (procedure in GENSCRN.PRG)
  1550. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  1551. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  1552. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  1553. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1554. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  1555. *!
  1556. *!*****************************************************************************
  1557. PROCEDURE dispatchbuild
  1558. *)
  1559. *) DISPATCHBUILD - Determines which platforms are to be generated and
  1560. *)                  calls BUILDCTRL for each one.
  1561. *)
  1562. PRIVATE m.i, m.thisplat, m.j
  1563. m.g_numplatforms = countplatforms()
  1564.  
  1565. DO prepparams
  1566.  
  1567. _TEXT = m.g_orghandle
  1568. _PRETEXT = ""
  1569.  
  1570. DO CASE
  1571. CASE multiplat()
  1572.    * Emit code for all common platforms in the screen set and put CASE statements
  1573.    * around the code for each one.  The g_platforms array contains the list of
  1574.    * platforms to generate for.
  1575.  
  1576.    * If generating for multiple platforms, scan all cleanup snippets and assemble an
  1577.    * array of unique procedure names.  This process is designed to handle procedure name
  1578.    * collisions across platforms.
  1579.    DO scanproc
  1580.  
  1581.    DO header   && main heading at top of program
  1582.  
  1583.    * Special case when there are multiple platforms being sent to the
  1584.    * same SPR.  Since the SPR can only have a single parameter statement,
  1585.    * and since it has to appear before the CASE _platform code, put it
  1586.    * here.
  1587.    DO genparameter
  1588.  
  1589.    m.thisplat = "X"   && placeholder value
  1590.    m.i = 1
  1591.    DO WHILE !EMPTY(m.thisplat)
  1592.       m.thisplat = lookupplatform(m.i)
  1593.       IF !EMPTY(m.thisplat)
  1594.          DO putmsg WITH "Generating code for "+versioncap(m.thisplat, m.g_dualoutput)
  1595.       
  1596.          IF m.i = 1
  1597.             \DO CASE
  1598.          ELSE
  1599.             \
  1600.          ENDIF
  1601.          DO gencasestmt WITH m.thisplat
  1602.          \
  1603.          
  1604.          * Switch the platform to generate for
  1605.          m.g_genvers = m.thisplat
  1606.  
  1607.          * Update screen array entries for the new platform, unless it's the currently
  1608.          * executing platform, in which case we did this just above.
  1609.          IF !(m.thisplat == m.g_thisvers)
  1610.             * Start with a fresh set of screens.  Prepscreens() fills in the details.
  1611.             g_nscreens = 0
  1612.             IF !prepscreens(m.thisplat)
  1613.                DO errorhandler WITH "Error initializing screens for ";
  1614.                   +PROPER(m.thisplat)+".", LINENO(), c_error_3
  1615.                CANCEL
  1616.             ENDIF
  1617.             DO newwindows      && initialize the window array
  1618.             DO newdbfs         && initialize the DBF name array
  1619.             DO newreadclauses  && initialize the read clause variables
  1620.             DO newdirectives   && initialize the directives that change from platform to platform
  1621.             DO newschemes      && initialize the scheme variables
  1622.          ENDIF
  1623.  
  1624.          DO pushindent
  1625.          DO buildctrl WITH m.thisplat, m.i, .F.
  1626.          DO popindent
  1627.       ENDIF
  1628.       m.i = m.i + 1
  1629.    ENDDO
  1630.    \
  1631.    \ENDCASE
  1632.    \
  1633.    _TEXT = m.g_tmphandle
  1634.    m.thispretext = _PRETEXT
  1635.    _PRETEXT = ""
  1636.    DO updtherm WITH c_therm6 * m.g_numplatforms  && 70%
  1637.    DO genprocedures
  1638.    _TEXT = m.g_orghandle
  1639.    _PRETEXT = m.thispretext
  1640.  
  1641. OTHERWISE                         && just outputing one platform.
  1642.    * If we are generating for a platform other than the one we are running
  1643.    * on, run through prepscreens again to assign the right platform
  1644.    * name to each of these screens.
  1645.    IF (_DOS AND g_platforms[1] <> "DOS") ;
  1646.          OR (_WINDOWS AND g_platforms[1] <> "WINDOWS") ;
  1647.          OR (_MAC AND g_platforms[1] <> "MAC") ;
  1648.          OR (_UNIX AND g_platforms[1] <> "UNIX")
  1649.       g_nscreens = 0
  1650.       IF !prepscreens(g_platforms[1])
  1651.          DO errorhandler WITH "Error initializing screens for ";
  1652.             +PROPER(m.thisplat)+".", LINENO(), c_error_3
  1653.          CANCEL
  1654.       ENDIF
  1655.    ENDIF
  1656.  
  1657.    m.g_allplatforms = .F.
  1658.    m.g_numplatforms = 1
  1659.    m.g_genvers      = g_platforms[1]
  1660.  
  1661.    DO newwindows      && Initialize the array of window names
  1662.    DO newdbfs         && Initialize the array of DBF names
  1663.    DO newreadclauses  && Initialize the read clause variables for each platform
  1664.    DO newdirectives   && Initialize the directives that change from platform to platform
  1665.    DO newschemes      && initialize the scheme variables
  1666.  
  1667.    DO header
  1668.    DO buildctrl WITH g_platforms[1], 1, .T.
  1669.  
  1670.    DO updtherm WITH  c_therm6   && 70%
  1671.    DO genprocedures
  1672. ENDCASE
  1673. RETURN
  1674.  
  1675.  
  1676. **
  1677. ** Code Associated With Building of the Control Program.
  1678. **
  1679. *!*****************************************************************************
  1680. *!
  1681. *!      Procedure: BUILDCTRL
  1682. *!
  1683. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1684. *!
  1685. *!          Calls: HEADER             (procedure in GENSCRN.PRG)
  1686. *!               : GENPARAMETER       (procedure in GENSCRN.PRG)
  1687. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  1688. *!               : GENSETENVIRON      (procedure in GENSCRN.PRG)
  1689. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  1690. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1691. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  1692. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  1693. *!               : DEFPOPUPS          (procedure in GENSCRN.PRG)
  1694. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  1695. *!               : GENCLNENVIRON      (procedure in GENSCRN.PRG)
  1696. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  1697. *!
  1698. *!*****************************************************************************
  1699. PROCEDURE buildctrl
  1700. *)
  1701. *) BUILDCTRL - Generate Format control file.
  1702. *)
  1703. *) Description:
  1704. *) Buildctrl controls the generation process.  It invokes procedures
  1705. *) which build the output program from a set of screens.
  1706. *)
  1707. PARAMETERS m.pltfrm, m.pnum, m.putparam, m.dbalias
  1708. PRIVATE m.i
  1709.  
  1710. IF m.putparam
  1711.    * Bracketed code is handled elsewhere.  We are only emitting the parameter
  1712.    * from this platform.  Go get it again to make sure we have the right one.
  1713.    * At this point, g_parameter could contain the parameter from any platform.
  1714.  
  1715.    * Open the database for the first screen since it's the only one we can generate
  1716.    * a parameter statement for.
  1717.    m.dbalias = g_screens[1,5]
  1718.    SELECT (m.dbalias)
  1719.    DO seekheader WITH 1
  1720.  
  1721.    m.g_parameter = getparam("setupcode")
  1722.  
  1723.    DO genparameter
  1724. ENDIF
  1725. DO gensect1                                && SECTION 1 setup code
  1726. DO gensetenviron                        && environment setup code
  1727. IF m.g_openfiles
  1728.    DO genopendbfs                        && USE ... INDEX ... statements
  1729. ENDIF
  1730. DO updtherm WITH thermadj(m.pnum,c_therm2,c_therm5)    && and SET RELATIONS
  1731.  
  1732. DO defwindows                             && window definitions
  1733. DO gensect2                                && SECTION 2 setup code
  1734. DO defpopups                            && lists
  1735. DO updtherm WITH thermadj(m.pnum,c_therm3,c_therm5)
  1736.  
  1737. DO buildfmt WITH m.pnum            && @ ... SAY/GET statements
  1738.  
  1739. DO updtherm WITH thermadj(m.pnum,c_therm4,c_therm5)
  1740. IF m.g_windows AND m.g_relwin AND !m.g_noread
  1741.    * If the READ is omitted, don't produce the code to release the window.
  1742.    FOR m.i = 1 TO m.g_nwindows
  1743.       \RELEASE WINDOW <<g_wndows[m.i,1]>>
  1744.    ENDFOR
  1745. ENDIF
  1746.  
  1747. IF m.g_moddesktop AND m.g_relwin AND INLIST(m.g_genvers,"WINDOWS","MAC")
  1748.    \MODIFY WINDOW SCREEN
  1749. ENDIF
  1750.  
  1751. DO genclnenviron                        && environment cleanup code
  1752. DO updtherm WITH thermadj(m.pnum,c_therm5,c_therm5)
  1753. DO gencleanup                       && cleanup code, but not procedures/functions
  1754.  
  1755. *!*****************************************************************************
  1756. *!
  1757. *!      Procedure: GENSETENVIRON
  1758. *!
  1759. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1760. *!
  1761. *!*****************************************************************************
  1762. PROCEDURE gensetenviron
  1763. *)
  1764. *) GENSETENVIRON - Generate environment code for the .SPR
  1765. *)
  1766. IF !m.g_noreadplain
  1767.    \
  1768.    \#REGION 0
  1769.    \REGIONAL m.currarea, m.talkstat, m.compstat
  1770.    \
  1771.    \IF SET("TALK") = "ON"
  1772.    \    SET TALK OFF
  1773.    \    m.talkstat = "ON"
  1774.    \ELSE
  1775.    \    m.talkstat = "OFF"
  1776.    \ENDIF
  1777.    \m.compstat = SET("COMPATIBLE")
  1778.    \SET COMPATIBLE FOXPLUS
  1779.    
  1780.    IF INLIST(m.g_genvers,"WINDOWS","MAC")
  1781.       \
  1782.       \m.rborder = SET("READBORDER")
  1783.       \SET READBORDER <<IIF(m.g_readborder, "ON", "OFF")>>
  1784.    ENDIF
  1785. ENDIF   
  1786.  
  1787. IF m.g_closefiles
  1788.    \
  1789.    \m.currarea = SELECT()
  1790.    \
  1791. ENDIF
  1792. RETURN
  1793.  
  1794. *!*****************************************************************************
  1795. *!
  1796. *!      Procedure: GENCLNENVIRON
  1797. *!
  1798. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1799. *!
  1800. *!          Calls: GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  1801. *!               : RELPOPUPS          (procedure in GENSCRN.PRG)
  1802. *!
  1803. *!*****************************************************************************
  1804. PROCEDURE genclnenviron
  1805. *)
  1806. *) GENCLNENVIRON - Generate environment code for the .SPR
  1807. *)
  1808. IF m.g_closefiles
  1809.    DO genclosedbfs
  1810. ENDIF
  1811. IF m.g_somepops
  1812.    DO relpopups
  1813. ENDIF
  1814. IF !m.g_noreadplain
  1815.    \
  1816.    \#REGION 0
  1817.    IF INLIST(m.g_genvers,"WINDOWS","MAC")
  1818.       \
  1819.       \SET READBORDER &rborder
  1820.       \
  1821.    ENDIF
  1822.    \IF m.talkstat = "ON"
  1823.    \    SET TALK ON
  1824.    \ENDIF
  1825.    \IF m.compstat = "ON"
  1826.    \    SET COMPATIBLE ON
  1827.    \ENDIF
  1828.    \
  1829. ENDIF
  1830. RETURN
  1831.  
  1832. *!*****************************************************************************
  1833. *!
  1834. *!      Procedure: GENCLEANUP
  1835. *!
  1836. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1837. *!
  1838. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  1839. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  1840. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  1841. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  1842. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  1843. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  1844. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  1845. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  1846. *!
  1847. *!*****************************************************************************
  1848. PROCEDURE gencleanup
  1849. *)
  1850. *) GENCLEANUP - Generate Cleanup Code.
  1851. *)
  1852. PRIVATE m.i, m.dbalias, m.msg
  1853.  
  1854. IF m.g_graphic
  1855.    m.msg = 'Generating Cleanup Code'
  1856.    IF multiplat()
  1857.       m.msg = m.msg + " for "+versioncap(m.g_genvers, m.g_dualoutput)
  1858.    ENDIF
  1859.    DO putmsg WITH  m.msg
  1860. ENDIF
  1861.  
  1862. * Generate the actual cleanup code--the code that precedes procedures
  1863. * and function declarations.
  1864. FOR m.i = 1 TO m.g_nscreens
  1865.    m.g_screen = m.i
  1866.    m.dbalias = g_screens[m.i,5]
  1867.    SELECT (m.dbalias)
  1868.  
  1869.    DO seekheader WITH m.i
  1870.    IF EMPTY (proccode)
  1871.       g_firstproc[m.i] = 0
  1872.       LOOP
  1873.    ENDIF
  1874.  
  1875.    * Find the line number where the first procedure or function
  1876.    * declaration occurs
  1877.    g_firstproc[m.i] = getfirstproc("PROCCODE")
  1878.  
  1879.    IF g_firstproc[m.i] <> 1
  1880.       * Either there aren't any procedures/functions, or they
  1881.       * are below the actual cleanup code.  Emit the cleanup code.
  1882.       DO commentblock WITH g_screens[m.i,1], " Cleanup Code"
  1883.       \#REGION <<INT(m.i)>>
  1884.       DO writecode WITH proccode, getplatname(m.i), c_fromone, g_firstproc[m.i], m.i
  1885.    ENDIF
  1886. ENDFOR
  1887. m.g_screen = 0
  1888.  
  1889. RETURN
  1890.  
  1891. *!*****************************************************************************
  1892. *!
  1893. *!      Procedure: GENPROCEDURES
  1894. *!
  1895. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1896. *!
  1897. *!          Calls: PUTMSG             (procedure in GENSCRN.PRG)
  1898. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  1899. *!               : PUTPROCHEAD        (procedure in GENSCRN.PRG)
  1900. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  1901. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  1902. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  1903. *!               : ISGENPLAT()        (function  in GENSCRN.PRG)
  1904. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  1905. *!
  1906. *!*****************************************************************************
  1907. PROCEDURE genprocedures
  1908. *)
  1909. *) GENPROCEDURES - Generate Procedures and Functions from cleanup code.
  1910. *)
  1911. PRIVATE m.i, m.dbalias
  1912. m.msg = 'Generating Procedures and Functions'
  1913. DO putmsg WITH m.msg
  1914.  
  1915. * Go back through each of the screens and output any procedures and
  1916. * functions that are in the cleanup snippet.
  1917. FOR m.i = 1 TO m.g_nscreens
  1918.    m.g_screen = m.i
  1919.    m.g_isfirstproc = .T.  && reset this for each screen
  1920.    m.dbalias = g_screens[m.i,5]
  1921.    SELECT (m.dbalias)
  1922.    DO seekheader WITH m.i
  1923.  
  1924.    DO CASE
  1925.    CASE g_screens[m.i,6]    && DOS 2.0 screen
  1926.       IF g_firstproc[m.i] > 0
  1927.          DO putprochead WITH m.i, g_screens[m.i,1]
  1928.          DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1929.       ENDIF
  1930.    CASE multiplat()
  1931.       * Multiple 2.5 platforms
  1932.       IF m.g_procsmatch   && all cleanup snippets in the file are the same
  1933.          * Get all the screen/platform headers from this screen file
  1934.          IF g_firstproc[m.i] > 0
  1935.             DO putprochead WITH m.i, g_screens[m.i,1]
  1936.             DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1937.          ENDIF
  1938.       ELSE
  1939.          * The are some differences.  Look for procedure name collisions among the
  1940.          * cleanup snippets in the platforms we are generating.
  1941.          SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  1942.             IF EMPTY(proccode)
  1943.                LOOP
  1944.             ENDIF
  1945.             DO putprochead WITH m.i, g_screens[m.i,1]
  1946.             DO extractprocs WITH m.i
  1947.          ENDSCAN
  1948.       ENDIF
  1949.    OTHERWISE  && just generating one 2.5 platform
  1950.       IF g_firstproc[m.i] > 0
  1951.          DO putprochead WITH m.i, g_screens[m.i,1]
  1952.          DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1953.       ENDIF
  1954.    ENDCASE
  1955. ENDFOR
  1956. m.g_screen = 0
  1957. RETURN
  1958.  
  1959. *!*****************************************************************************
  1960. *!
  1961. *!       Function: PROCSMATCH
  1962. *!
  1963. *!      Called by: SCANPROC           (procedure in GENSCRN.PRG)
  1964. *!
  1965. *!          Calls: ISGENPLAT()        (function  in GENSCRN.PRG)
  1966. *!
  1967. *!*****************************************************************************
  1968. FUNCTION procsmatch
  1969. *)
  1970. *) PROCSMATCH - Are the CRCs for the cleanup snippets the same for all platforms in the
  1971. *)                current screen that are being generated?
  1972. *)
  1973. PRIVATE m.crccode, m.thiscode, m.in_rec
  1974.  
  1975. m.in_rec = IIF(!EOF(),RECNO(),1)
  1976. m.crccode = "0"
  1977. * Get the headers for all the platforms we are generating
  1978. SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  1979.    m.thiscode = ALLTRIM(SYS(2007,proccode))
  1980.    DO CASE
  1981.    CASE m.crccode = "0"
  1982.       m.crccode = m.thiscode
  1983.    CASE m.thiscode <> m.crccode AND m.crccode <> "0"
  1984.       RETURN .F.
  1985.    ENDCASE
  1986. ENDSCAN
  1987. GOTO m.in_rec
  1988. RETURN .T.
  1989.  
  1990. *!*****************************************************************************
  1991. *!
  1992. *!       Function: ISGENPLAT
  1993. *!
  1994. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  1995. *!               : PROCSMATCH()       (function  in GENSCRN.PRG)
  1996. *!               : SCANPROC           (procedure in GENSCRN.PRG)
  1997. *!
  1998. *!*****************************************************************************
  1999. FUNCTION isgenplat
  2000. *)
  2001. *) ISGENPLAT - Is this platform one of the ones being generated?
  2002. *)
  2003. PARAMETER m.platname
  2004. RETURN IIF(ASCAN(g_platforms,ALLTRIM(UPPER(m.platname))) > 0, .T. , .F. )
  2005.  
  2006. *!*****************************************************************************
  2007. *!
  2008. *!      Procedure: PUTPROCHEAD
  2009. *!
  2010. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  2011. *!
  2012. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2013. *!
  2014. *!*****************************************************************************
  2015. PROCEDURE putprochead
  2016. *)
  2017. *) PUTPROCHEAD - Emit the procedure and function heading if we haven't done
  2018. *)
  2019. PARAMETER m.scrnno, m.filname
  2020. IF m.g_isfirstproc
  2021.    \
  2022.    DO commentblock WITH g_screens[m.scrnno,1], " Supporting Procedures and Functions "
  2023.    \#REGION <<INT(m.scrnno)>>
  2024.    m.g_isfirstproc = .F.
  2025. ENDIF
  2026. RETURN
  2027.  
  2028. *!*****************************************************************************
  2029. *!
  2030. *!      Procedure: EXTRACTPROCS
  2031. *!
  2032. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  2033. *!
  2034. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2035. *!               : MATCH()            (function  in GENSCRN.PRG)
  2036. *!               : GETPROCNUM()       (function  in GENSCRN.PRG)
  2037. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  2038. *!               : HASCONFLICT()      (function  in GENSCRN.PRG)
  2039. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2040. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  2041. *!               : PROCCOMMENTBLOCK   (procedure in GENSCRN.PRG)
  2042. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  2043. *!
  2044. *!*****************************************************************************
  2045. PROCEDURE extractprocs
  2046. *)
  2047. *) EXTRACTPROCS - Output the procedures for the current platform in the current screen
  2048. *)
  2049. * We only get here if we are emitting for multiple platforms and the cleanup snippets
  2050. * for all platforms are not identical.  We are positioned on a screen header record for
  2051. * the g_genvers platform.
  2052. PARAMETER m.scrnno
  2053.  
  2054. PRIVATE m.hascontin, m.iscontin, m.sniplen, m.i, m.thisline, m.pnum, m.word1, m.word2
  2055.  
  2056. _MLINE = 0
  2057. m.sniplen   = LEN(proccode)
  2058. m.numlines  = MEMLINES(proccode)
  2059. m.hascontin = .F.
  2060. DO WHILE _MLINE < m.sniplen
  2061.    m.thisline  = UPPER(ALLTRIM(MLINE(proccode,1, _MLINE)))
  2062.    DO killcr WITH m.thisline
  2063.    m.iscontin  = m.hascontin
  2064.    m.hascontin = RIGHT(m.thisline,1) = ';'
  2065.    IF LEFT(m.thisline,1) $ "PF" AND !m.iscontin
  2066.       m.word1 = wordnum(m.thisline, 1)
  2067.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2068.          m.word2 = wordnum(m.thisline,2)
  2069.          * Does this procedure have a name conflict?
  2070.          m.pnum = getprocnum(m.word2)
  2071.          IF pnum > 0
  2072.             DO CASE
  2073.             CASE g_procs[m.pnum,C_MAXPLATFORMS+2]
  2074.                * This one has already been generated.  Skip past it now.
  2075.                DO emitproc WITH .F., m.thisline, m.sniplen, m.scrnno
  2076.                LOOP
  2077.             CASE hasconflict(pnum)
  2078.                * Name collision detected.  Output bracketed code for all platforms
  2079.                DO putmsg WITH "Generating code for procedure/function ";
  2080.                   +LOWER(g_procs[m.pnum,1])
  2081.                DO updtherm WITH thermadj(m.pnum,c_therm6 + (c_therm7-c_therm6)/m.g_procnames,c_therm7)
  2082.                DO proccommentblock WITH g_screens[m.scrnno,1], " "+PROPER(word1);
  2083.                   +" " + g_procs[m.pnum,1]
  2084.                DO emitbracket WITH m.pnum, m.scrnno
  2085.             OTHERWISE
  2086.                * This procedure has no name collision and has not been emitted yet.
  2087.                DO putmsg WITH "Generating code for procedure/function ";
  2088.                   +LOWER(g_procs[m.pnum,1])
  2089.                DO updtherm WITH thermadj(m.pnum,c_therm6 + (c_therm7-c_therm6)/m.g_procnames,c_therm7)
  2090.                *DO updtherm WITH (c_therm6 + ((c_therm7-c_therm6)/g_procnames) * m.pnum) * m.g_numplatforms
  2091.                DO proccommentblock WITH g_screens[m.scrnno,1], " "+PROPER(word1);
  2092.                   +" " + g_procs[m.pnum,1]
  2093.                DO emitproc WITH .T., m.thisline, m.sniplen, m.scrnno
  2094.             ENDCASE
  2095.             g_procs[pnum,C_MAXPLATFORMS+2] = .T.
  2096.          ENDIF
  2097.       ENDIF
  2098.    ENDIF
  2099. ENDDO
  2100. RETURN
  2101.  
  2102. *!*****************************************************************************
  2103. *!
  2104. *!      Procedure: EMITPROC
  2105. *!
  2106. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2107. *!
  2108. *!          Calls: WRITELINE          (procedure in GENSCRN.PRG)
  2109. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  2110. *!               : MATCH()            (function  in GENSCRN.PRG)
  2111. *!
  2112. *!*****************************************************************************
  2113. PROCEDURE emitproc
  2114. *)
  2115. *) EMITPROC - Scan through the next procedure/function in the current cleanup snippet.
  2116. *)            If dowrite is TRUE, emit the code as we go.  Otherwise, just skip over it
  2117. *)            and advance _MLINE.
  2118. *)
  2119. * We are positioned on the PROCEDURE or FUNCTION line now and there isn't a name
  2120. * conflict.
  2121. PARAMETER m.dowrite, m.thisline, m.sniplen, m.scrnno
  2122. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  2123.    m.iscontin, m.hascontin, m.platnum
  2124.    
  2125. m.hascontin = .F.
  2126. m.done = .F.
  2127.  
  2128. * Write the PROCEDURE/FUNCTION statement
  2129. m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2130.  
  2131. IF g_screens[m.scrnno,6]   && DOS 2.0 screen
  2132.    m.platnum = getplatnum("DOS")
  2133. ELSE
  2134.    m.platnum = getplatnum(m.g_genvers)
  2135. ENDIF
  2136.  
  2137. IF m.dowrite    && actually emit the procedure?
  2138.    DO writeline WITH m.thisline, m.g_genvers, m.platnum, m.upline, m.scrnno
  2139. ENDIF
  2140.  
  2141. * Write the body of the procedure
  2142. DO WHILE !m.done AND _MLINE < m.sniplen
  2143.    m.lastmline = _MLINE          && note where this line started
  2144.  
  2145.    m.line = MLINE(proccode,1, _MLINE)
  2146.    DO killcr WITH m.line
  2147.    m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2148.  
  2149.    m.iscontin = m.hascontin
  2150.    m.hascontin = RIGHT(m.upline,1) = ';'
  2151.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2152.       m.word1 = wordnum(m.upline, 1)
  2153.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2154.          done = .T.
  2155.          _MLINE = m.lastmline    && drop back one line and stop writing
  2156.          LOOP
  2157.       ENDIF
  2158.    ENDIF
  2159.  
  2160.    IF m.dowrite    && actually emit the procedure?
  2161.       DO writeline WITH m.line, m.g_genvers, m.platnum, m.upline, m.scrnno
  2162.    ENDIF
  2163.  
  2164. ENDDO
  2165. RETURN
  2166.  
  2167. *!*****************************************************************************
  2168. *!
  2169. *!      Procedure: EMITBRACKET
  2170. *!
  2171. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2172. *!
  2173. *!          Calls: PUSHINDENT         (procedure in GENSCRN.PRG)
  2174. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  2175. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  2176. *!
  2177. *!*****************************************************************************
  2178. PROCEDURE emitbracket
  2179. *)
  2180. *) EMITBRACKET - Emit DO CASE/CASE _DOS brackets and call putproc to emit code for this procedure
  2181. *)
  2182. PARAMETER m.pnum, m.scrnno
  2183. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  2184.    m.iscontin, m.hascontin, m.i
  2185. m.hascontin = .F.
  2186. m.done = .F.
  2187. \
  2188. \PROCEDURE <<g_procs[m.pnum,1]>>
  2189. IF !EMPTY(g_procs[m.pnum,C_MAXPLATFORMS+3])
  2190.    \PARAMETERS <<g_procs[m.pnum,C_MAXPLATFORMS+3]>>
  2191. ENDIF
  2192. \DO CASE
  2193.  
  2194. * Peek ahead and get the parameter statement
  2195. FOR m.platnum = 1 TO c_maxplatforms
  2196.    IF g_procs[m.pnum,m.platnum+1] < 0
  2197.       * There was no procedure for this platform
  2198.       LOOP
  2199.    ENDIF
  2200.    \CASE <<"_"+g_platlist[m.platnum]>>
  2201.    DO pushindent
  2202.    DO putproc WITH m.platnum, m.pnum, m.scrnno
  2203.    DO popindent
  2204. ENDFOR
  2205. \ENDCASE
  2206. RETURN
  2207.  
  2208. *!*****************************************************************************
  2209. *!
  2210. *!      Procedure: PUTPROC
  2211. *!
  2212. *!      Called by: EMITBRACKET        (procedure in GENSCRN.PRG)
  2213. *!
  2214. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2215. *!               : MATCH()            (function  in GENSCRN.PRG)
  2216. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2217. *!
  2218. *!*****************************************************************************
  2219. PROCEDURE putproc
  2220. *)
  2221. *) PUTPROC - Write actual code for procedure procnum in platform platnum
  2222. *)
  2223. PARAMETER m.platnum, m.procnum, m.scrnno
  2224. PRIVATE m.in_rec, m.oldmine, m.done, m.line, m.upline, m.iscontin, m.hascontin, ;
  2225.    m.word1, m.word2, m.platnum
  2226.  
  2227. m.in_rec    = RECNO()
  2228. * Store the _MLINE position in the original snippet
  2229. m.oldmline  = _MLINE
  2230. m.hascontin = .F.       && the previous line was not a continuation line.
  2231. LOCATE FOR platform = g_platlist[m.platnum] AND objtype = c_otscreen
  2232. IF FOUND()
  2233.    * go to the PROCEDURE/FUNCTION statement
  2234.    _MLINE = g_procs[m.procnum,m.platnum+1]
  2235.    * Skip the PROCEDURE line, since we've already output one.
  2236.    m.line = MLINE(proccode,1, _MLINE)
  2237.    DO killcr WITH m.line
  2238.  
  2239.    * We are now positioned at the line following the procedure statement.
  2240.    * Write until the end of the snippet or the next procedure.
  2241.    m.done = .F.
  2242.    DO WHILE !m.done
  2243.       m.line = MLINE(proccode,1, _MLINE)
  2244.       DO killcr WITH m.line
  2245.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2246.       m.iscontin = m.hascontin
  2247.       m.hascontin = RIGHT(m.upline,1) = ';'
  2248.       IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2249.          m.word1 = wordnum(m.upline, 1)
  2250.          IF RIGHT(m.word1,1) = ';'
  2251.             m.word1 = LEFT(m.word1,LEN(m.word1)-1)
  2252.          ENDIF
  2253.  
  2254.          DO CASE
  2255.          CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2256.             * Stop when we encounter the next snippet
  2257.             m.done = .T.
  2258.             LOOP
  2259.          CASE match(m.word1,"PARAMETERS")
  2260.             * Don't output it, but keep scanning for other code
  2261.             DO WHILE m.hascontin
  2262.                m.line = MLINE(proccode,1, _MLINE)
  2263.                DO killcr WITH m.line
  2264.                m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2265.                m.hascontin = RIGHT(m.upline,1) = ';'
  2266.             ENDDO
  2267.             LOOP
  2268.          ENDCASE
  2269.       ENDIF
  2270.  
  2271.       DO writeline WITH m.line, g_platlist[m.platnum], m.platnum, m.upline, m.scrnno
  2272.  
  2273.       * Stop if we've run out of snippet
  2274.       IF _MLINE >= LEN(proccode)
  2275.          m.done = .T.
  2276.       ENDIF
  2277.    ENDDO
  2278. ENDIF
  2279.  
  2280. GOTO m.in_rec
  2281. * Restore the _MLINE position in the main snippet we are outputing
  2282. _MLINE = m.oldmline
  2283. RETURN
  2284.  
  2285. *!*****************************************************************************
  2286. *!
  2287. *!       Function: GETPROCNUM
  2288. *!
  2289. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2290. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2291. *!
  2292. *!*****************************************************************************
  2293. FUNCTION getprocnum
  2294. *)
  2295. *) GETPROCNUM - Return the g_procs array position of the procedure named pname
  2296. *)
  2297. PARAMETER m.pname
  2298. PRIVATE m.i
  2299. FOR m.i = 1 TO g_procnames
  2300.    IF g_procs[m.i,1] == m.pname
  2301.       RETURN m.i
  2302.    ENDIF
  2303. ENDFOR
  2304. RETURN  0
  2305.  
  2306. *!*****************************************************************************
  2307. *!
  2308. *!       Function: HASCONFLICT
  2309. *!
  2310. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2311. *!
  2312. *!*****************************************************************************
  2313. FUNCTION hasconflict
  2314. *)
  2315. *) HASCONFLICT - Is there a name collision for procedure number num?
  2316. *)
  2317. PARAMETER m.num
  2318. PRIVATE m.i, m.cnt
  2319. m.cnt = 0
  2320. FOR m.i = 1 TO c_maxplatforms
  2321.    IF g_procs[m.num,m.i+1] > 0
  2322.       m.cnt = m.cnt +1
  2323.    ENDIF
  2324. ENDFOR
  2325. RETURN IIF(m.cnt > 1,.T.,.F.)
  2326.  
  2327.  
  2328. *!*****************************************************************************
  2329. *!
  2330. *!       Function: GETFIRSTPROC
  2331. *!
  2332. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  2333. *!
  2334. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2335. *!               : MATCH()            (function  in GENSCRN.PRG)
  2336. *!
  2337. *!*****************************************************************************
  2338. FUNCTION getfirstproc
  2339. *)
  2340. *) GETFIRSTPROC - Find first PROCEDURE or FUNCTION statement in a cleanup
  2341. *)                snippet and return the line number on which it occurs.
  2342. *)
  2343. PARAMETER m.snipname
  2344. PRIVATE proclineno, numlines, word1, first_space
  2345. _MLINE = 0
  2346. m.numlines = MEMLINES(&snipname)
  2347. FOR m.proclineno = 1 TO m.numlines
  2348.    m.line  = MLINE(&snipname, 1, _MLINE)
  2349.    DO killcr WITH m.line
  2350.    m.line  = UPPER(LTRIM(m.line))
  2351.    m.word1 = wordnum(m.line,1)
  2352.    IF !EMPTY(m.word1) AND (match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION"))
  2353.       RETURN m.proclineno
  2354.    ENDIF
  2355. ENDFOR
  2356. RETURN 0
  2357.  
  2358. *!*****************************************************************************
  2359. *!
  2360. *!      Procedure: SCANPROC
  2361. *!
  2362. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  2363. *!
  2364. *!          Calls: PROCSMATCH()       (function  in GENSCRN.PRG)
  2365. *!               : ISGENPLAT()        (function  in GENSCRN.PRG)
  2366. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2367. *!
  2368. *!*****************************************************************************
  2369. PROCEDURE scanproc
  2370. *)
  2371. *) SCANPROC - Find unique procedure names in cleanup snippets for all platforms
  2372. *)
  2373. PRIVATE m.in_rec
  2374. * See if all the cleanup snippets are the same.  If so, stop now.
  2375. m.g_procsmatch = .T.
  2376. FOR m.g_screen = 1 TO m.g_nscreens
  2377.    m.dbalias = g_screens[m.g_screen,5]
  2378.    SELECT (m.dbalias)
  2379.    IF !g_screens[m.g_screen,6]      && not applicable for FoxPro 2.0 screens
  2380.       m.g_procsmatch = m.g_procsmatch AND procsmatch()
  2381.     ENDIF
  2382. ENDFOR
  2383.  
  2384. IF !m.g_procsmatch
  2385.    FOR m.g_screen = 1 TO m.g_nscreens
  2386.       m.dbalias = g_screens[m.g_screen,5]
  2387.       SELECT (m.dbalias)
  2388.  
  2389.       IF !g_screens[m.g_screen,6]      && not applicable for FoxPro 2.0 screens
  2390.          SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  2391.             DO updprocarray
  2392.          ENDSCAN
  2393.       ENDIF
  2394.    ENDFOR
  2395.    m.g_screen = 0
  2396. ENDIF
  2397. RETURN
  2398.  
  2399. *!*****************************************************************************
  2400. *!
  2401. *!      Procedure: UPDPROCARRAY
  2402. *!
  2403. *!      Called by: SCANPROC           (procedure in GENSCRN.PRG)
  2404. *!
  2405. *!          Calls: VERSIONCAP()       (function  in GENSCRN.PRG)
  2406. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2407. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  2408. *!               : MATCH()            (function  in GENSCRN.PRG)
  2409. *!               : ADDPROCNAME        (procedure in GENSCRN.PRG)
  2410. *!               : GETPROCNUM()       (function  in GENSCRN.PRG)
  2411. *!               : CLEANPARAM()       (function  in GENSCRN.PRG)
  2412. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  2413. *!
  2414. *!*****************************************************************************
  2415. PROCEDURE updprocarray
  2416. *)
  2417. *) UPDPROCARRAY - Pick out the procedures names in the current cleanup snippet and call
  2418. *)                  AddProcName to update the g_procs array.
  2419. *)
  2420. PRIVATE m.i, m.numlines, m.line, m.upline, m.word1, m.word2, m.iscontin, m.hascontin, ;
  2421.    m.lastmline, m.thisproc
  2422.  
  2423. DO putmsg WITH "Scanning cleanup snippet for ";
  2424.    +versioncap( IIF(TYPE("platform")<>"U",platform,"DOS"), m.g_dualoutput )
  2425.  
  2426. _MLINE = 0
  2427. m.numlines = MEMLINES(proccode)
  2428. m.hascontin = .F.
  2429. FOR m.i = 1 TO m.numlines
  2430.    m.lastmline = _MLINE                && note starting position of this line
  2431.    m.line      = MLINE(proccode,1, _MLINE)
  2432.    DO killcr WITH m.line
  2433.    m.upline    = UPPER(ALLTRIM(m.line))
  2434.    m.iscontin  = m.hascontin
  2435.    m.hascontin = RIGHT(m.upline,1) = ';'
  2436.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2437.       m.word1 = CHRTRAN(wordnum(m.upline, 1),';','')
  2438.       DO CASE
  2439.       CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2440.          m.word2 = wordnum(m.upline,2)
  2441.          DO addprocname WITH m.word2, platform, m.i, m.lastmline
  2442.          m.lastproc = m.word2
  2443.       CASE match(m.word1,"PARAMETERS")
  2444.          * Associate this parameter statement with the last procedure or function
  2445.          m.thisproc = getprocnum(m.lastproc)
  2446.          IF m.thisproc > 0
  2447.             m.thisparam = ALLTRIM(SUBSTR(m.upline,AT(' ',m.upline)+1))
  2448.             * Deal with continued PARAMETER lines
  2449.             DO WHILE m.hascontin AND m.i <= m.numlines
  2450.                m.lastmline = _MLINE                && note the starting position of this line
  2451.                m.line   = MLINE(proccode,1, _MLINE)
  2452.                DO killcr WITH m.line
  2453.                m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2454.                m.thisparam = ;
  2455.                   m.thisparam + CHR(13)+CHR(10) + m.line
  2456.                m.hascontin = RIGHT(m.upline,1) = ';'
  2457.                m.i = m.i + 1
  2458.             ENDDO
  2459.             * Make sure that this parameter matches any others we've seen for this function
  2460.             DO CASE
  2461.             CASE EMPTY(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2462.                * First occurrence, or one platform has a parameter statement and another doesn't
  2463.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  2464.             CASE cleanparam(m.thisparam) == cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2465.                * It matches--do nothing
  2466.             CASE cleanparam(m.thisparam) = cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2467.                * The new one is a superset of the existing one.  Use the longer one.
  2468.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  2469.             CASE cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3]) = cleanparam(m.thisparam)
  2470.                * The old one is a superset of the new one.  Keep the longer one.
  2471.             OTHERWISE
  2472.                DO errorhandler WITH "Different parameters for "+g_procs[m.thisproc,1],;
  2473.                   LINENO(),c_error_3
  2474.             ENDCASE
  2475.          ENDIF
  2476.       ENDCASE
  2477.    ENDIF
  2478. ENDFOR
  2479. RETURN
  2480.  
  2481. *!*****************************************************************************
  2482. *!
  2483. *!      Procedure: ADDPROCNAME
  2484. *!
  2485. *!      Called by: UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2486. *!
  2487. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2488. *!
  2489. *!*****************************************************************************
  2490. PROCEDURE addprocname
  2491. *)
  2492. *) ADDPROCNAME - Update g_procs with pname data
  2493. *)
  2494. PARAMETER m.pname, m.platname, m.linenum, m.lastmline
  2495. PRIVATE m.rnum, m.platformcol, m.i, m.j
  2496. IF EMPTY(m.pname)
  2497.    RETURN
  2498. ENDIF
  2499.  
  2500. * Look up this name in the procedures array
  2501. m.rnum = 0
  2502. FOR m.i = 1 TO m.g_procnames
  2503.    IF g_procs[m.i,1] == m.pname
  2504.       m.rnum = m.i
  2505.       EXIT
  2506.    ENDIF
  2507. ENDFOR
  2508.  
  2509. IF m.rnum = 0
  2510.    * New name
  2511.    g_procnames = m.g_procnames + 1
  2512.    DIMENSION g_procs[m.g_procnames,C_MAXPLATFORMS+3]
  2513.    g_procs[m.g_procnames,1] = UPPER(ALLTRIM(m.pname))
  2514.    FOR m.j = 1 TO c_maxplatforms
  2515.       g_procs[m.g_procnames,m.j + 1] = -1
  2516.    ENDFOR
  2517.    g_procs[m.g_procnames,C_MAXPLATFORMS+2] = .F.   && not emitted yet
  2518.    g_procs[m.g_procnames,C_MAXPLATFORMS+3] = ""    && parameter statement
  2519.    m.rnum = m.g_procnames
  2520. ENDIF
  2521.  
  2522. m.platformcol = getplatnum(m.platname) + 1
  2523. IF m.platformcol > 1
  2524.    g_procs[m.rnum, m.platformcol] = m.lastmline
  2525. ENDIF
  2526. RETURN
  2527.  
  2528. *!*****************************************************************************
  2529. *!
  2530. *!       Function: GETPLATNUM
  2531. *!
  2532. *!      Called by: PREPWNAMES         (procedure in GENSCRN.PRG)
  2533. *!               : ADDPROCNAME        (procedure in GENSCRN.PRG)
  2534. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2535. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2536. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  2537. *!
  2538. *!*****************************************************************************
  2539. FUNCTION getplatnum
  2540. *)
  2541. *) GETPLATNUM - Return the g_platlist array index given a platform name
  2542. *)
  2543. PARAMETER m.platname
  2544. PRIVATE m.i
  2545. FOR m.i = 1 TO c_maxplatforms
  2546.    IF g_platlist[m.i] == UPPER(ALLTRIM(m.platname))
  2547.       RETURN m.i
  2548.    ENDIF
  2549. ENDFOR
  2550. RETURN 0
  2551.  
  2552. *!*****************************************************************************
  2553. *!
  2554. *!      Procedure: GENCASESTMT
  2555. *!
  2556. *!*****************************************************************************
  2557. PROCEDURE gencasestmt
  2558. *)
  2559. *) GENCASESTMT - Generate the CASE ... statement
  2560. *)
  2561. PARAMETER m.thisplat
  2562. DO CASE
  2563. CASE m.thisplat = "WINDOWS" and !hasrecords("MAC") and hasrecords("WINDOWS")
  2564.    \CASE _WINDOWS OR _MAC   && no MAC records in screen
  2565.     m.g_dualoutput = .T.
  2566. CASE m.thisplat = "MAC" and !hasrecords("WINDOWS") and hasrecords("MAC")
  2567.    \CASE _MAC OR _WINDOWS   && no Windows records in screen
  2568.     m.g_dualoutput = .T.
  2569. CASE m.thisplat = "UNIX" and !hasrecords("DOS") and hasrecords("UNIX")
  2570.    \CASE _UNIX OR _DOS      && no DOS records in screen
  2571.     m.g_dualoutput = .T.
  2572. CASE m.thisplat = "DOS" and !hasrecords("UNIX") and hasrecords("DOS")
  2573.    \CASE _DOS OR _UNIX      && no UNIX records in screen
  2574.     m.g_dualoutput = .T.
  2575. OTHERWISE
  2576.    \CASE _<<m.thisplat>>
  2577.     m.g_dualoutput = .F.
  2578. ENDCASE
  2579. RETURN
  2580.  
  2581. *!*****************************************************************************
  2582. *!
  2583. *!      Procedure: GENPARAMETER
  2584. *!
  2585. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  2586. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  2587. *!
  2588. *!*****************************************************************************
  2589. PROCEDURE genparameter
  2590. *)
  2591. *) GENPARAMETER - Generate the PARAMETER statement
  2592. *)
  2593. IF !EMPTY(m.g_parameter)
  2594.    \PARAMETERS <<m.g_parameter>>
  2595. ENDIF
  2596. RETURN
  2597.  
  2598. *!*****************************************************************************
  2599. *!
  2600. *!      Procedure: GENSECT1
  2601. *!
  2602. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  2603. *!
  2604. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  2605. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  2606. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2607. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  2608. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  2609. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2610. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  2611. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2612. *!
  2613. *!*****************************************************************************
  2614. PROCEDURE gensect1
  2615. *)
  2616. *) GENSECT1 - Generate #SECTION 1 code for all screens.
  2617. *)
  2618. PRIVATE m.i, m.dbalias, m.string, m.loop, m.j, m.end, m.msg, m.thisline
  2619. m.msg =  'Generating Setup Code'
  2620. IF multiplat()
  2621.    m.msg = m.msg + " for "+versioncap(m.g_genvers, m.g_dualoutput)
  2622. ENDIF
  2623. DO putmsg WITH m.msg
  2624. m.string = " Setup Code - SECTION 1"
  2625.  
  2626. FOR m.i = 1 TO m.g_nscreens
  2627.    m.g_screen = m.i
  2628.  
  2629.    m.dbalias = g_screens[m.i,5]
  2630.    SELECT (m.dbalias)
  2631.    DO seekheader WITH m.i
  2632.    IF EMPTY (setupcode)
  2633.       LOOP
  2634.    ENDIF
  2635.  
  2636.    m.g_sect1start= c_fromone
  2637.    m.g_sect2start= c_untilend
  2638.    m.loop  = .F.
  2639.  
  2640.    IF ATCLINE("#SECT", setupcode) <> 0
  2641.       m.g_sect1start = findsection(1, setupcode)+1
  2642.       m.g_sect2start = findsection(2, setupcode)
  2643.    ENDIF
  2644.    
  2645.    DO notedirectives WITH (m.i)
  2646.  
  2647.    * See if there are nondirective statements in SECTION 1
  2648.    IF m.g_sect2start-m.g_sect1start <= 3
  2649.       IF m.g_sect2start = 0
  2650.          m.end = MEMLINES(setupcode)
  2651.       ELSE
  2652.          m.end = m.g_sect2start-1
  2653.       ENDIF
  2654.       m.loop = .T.
  2655.       m.j = m.g_sect1start
  2656.       DO WHILE m.j <= m.end
  2657.          m.thisline = MLINE(setupcode,m.j)
  2658.          DO killcr WITH m.thisline
  2659.          IF AT('#',m.thisline) <> 1 OR AT('#INSE',m.thisline) = 1
  2660.             m.loop = .F.
  2661.             EXIT
  2662.          ENDIF
  2663.          m.j = m.j + 1
  2664.       ENDDO
  2665.    ENDIF
  2666.    IF m.loop
  2667.       LOOP
  2668.    ENDIF
  2669.    IF NOT (m.g_sect1start=1 OR (m.g_sect1start=m.g_sect2start) OR ;
  2670.          (m.g_sect2start<>0 AND m.g_sect1start>m.g_sect2start))
  2671.  
  2672.       DO commentblock WITH g_screens[m.i,1], m.string
  2673.       \#REGION <<INT(m.i)>>
  2674.       _MLINE = 0
  2675.       DO writecode WITH setupcode, getplatname(m.i), m.g_sect1start, m.g_sect2start, m.i, 'setup'
  2676.    ENDIF
  2677. ENDFOR
  2678. m.g_screen = 0
  2679. RETURN
  2680.  
  2681. *!*****************************************************************************
  2682. *!
  2683. *!      Procedure: GENSECT2
  2684. *!
  2685. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  2686. *!
  2687. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  2688. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  2689. *!               : NOTEDIRECTIVES     (procedure in GENSCRN.PRG)
  2690. *!               : COUNTDIRECTIVES()  (function  in GENSCRN.PRG)
  2691. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2692. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  2693. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2694. *!               
  2695. *!*****************************************************************************
  2696. PROCEDURE gensect2
  2697. *)
  2698. *) GENSECT2 - Generate Setup code #SECTION 2.
  2699. *)
  2700. PRIVATE m.i, m.dbalias, m.string, m.endline, m.srtline, ;
  2701.    m.linecnt, m.lcnt, m.sect1, m.sect2
  2702. m.string = " Setup Code - SECTION 2"
  2703.  
  2704. FOR m.i = 1 TO m.g_nscreens
  2705.    m.g_screen = m.i
  2706.    m.dbalias = g_screens[m.i,5]
  2707.    SELECT (m.dbalias)
  2708.    DO seekheader WITH m.i
  2709.    IF EMPTY (setupcode)
  2710.       LOOP
  2711.    ENDIF
  2712.  
  2713.    m.g_sect1start= c_fromone
  2714.    m.g_sect2start= c_untilend
  2715.    m.loop  = .F.
  2716.  
  2717.    IF ATCLINE("#SECT", setupcode)<>0
  2718.       m.g_sect1start = findsection(1, setupcode)+1
  2719.       m.g_sect2start = findsection(2, setupcode)
  2720.    ENDIF
  2721.  
  2722.    m.sect1 = m.g_sect1start <> 0
  2723.    m.sect2 = m.g_sect2start <> 0
  2724.  
  2725.    DO notedirectives WITH (m.i)
  2726.    m.lcnt = countdirectives(m.sect1, m.sect2, m.i)
  2727.  
  2728.    IF m.g_sect2start = 0 AND m.g_sect1start > 1
  2729.       * No Section2 to emit
  2730.       LOOP
  2731.    ENDIF
  2732.  
  2733.    m.linecnt = MEMLINES(setupcode)
  2734.  
  2735.    IF m.linecnt > m.lcnt AND m.g_sect2start < m.linecnt
  2736.       DO commentblock WITH g_screens[m.i,1], m.string
  2737.       \#REGION <<INT(m.i)>>
  2738.       DO writecode WITH setupcode, getplatname(m.i), m.g_sect2start, c_untilend, m.i, 'setup'
  2739.    ENDIF
  2740. ENDFOR
  2741. m.g_screen = 0
  2742. RETURN
  2743.  
  2744. *!*****************************************************************************
  2745. *!
  2746. *!       Function: COUNTDIRECTIVES
  2747. *!
  2748. *!      Called by: GENSECT2           (procedure in GENSCRN.PRG)
  2749. *!
  2750. *!*****************************************************************************
  2751. FUNCTION countdirectives
  2752. *)
  2753. *) COUNTDIRECTIVES - Count directives in setup snippet.
  2754. *)
  2755. *) This function counts the directives in setup.  It is used to figure out if there
  2756. *) are any non-directive statements in the setup snippet.
  2757. PARAMETER m.sect1, m.sect2, m.scrnno
  2758. PRIVATE m.numlines, m.i, m.lcnt, m.thisline, m.upline
  2759. m.lcnt = 0
  2760. IF AT('#',setupcode) > 0
  2761.    * AT test is optimization to avoid processing the snippet when there are no directives
  2762.    m.numlines = MEMLINES(setupcode)
  2763.    _MLINE = 0
  2764.    FOR m.i = 1 TO m.numlines
  2765.       m.thisline = MLINE(setupcode, 1, _MLINE)
  2766.       DO killcr WITH m.thisline
  2767.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2768.       IF LEFT(m.upline,1) = '#' AND !(LEFT(m.upline,5) = "#INSE")
  2769.          m.lcnt = m.lcnt + 1
  2770.       ENDIF
  2771.    ENDFOR
  2772. ENDIF
  2773. RETURN m.lcnt
  2774.  
  2775. *!*****************************************************************************
  2776. *!
  2777. *!      Procedure: NOTEDIRECTIVES
  2778. *!
  2779. *!      Called by: GENSECT2           (procedure in GENSCRN.PRG)
  2780. *!
  2781. *!*****************************************************************************
  2782. PROCEDURE notedirectives
  2783. *)
  2784. *) NOTEDIRECTIVES - Check for global directives such as #READCLAUSES, #NOREAD
  2785. *)
  2786. *) This function notes certain directives in the setup snippet and populates various
  2787. *) global variables so that we don't have to keep going back to the snippet to find
  2788. *) things.
  2789. PARAMETERS m.scrnno
  2790. PRIVATE m.numlines, m.i, m.thisline, m.upline
  2791. m.g_noread    = .F.
  2792. m.g_noreadplain = .F.
  2793. IF AT('#',setupcode) > 0
  2794.    * AT test is optimization to avoid processing the snippet when there are no directives
  2795.    m.numlines = MEMLINES(setupcode)
  2796.    _MLINE = 0
  2797.    FOR m.i = 1 TO m.numlines
  2798.       m.thisline = MLINE(setupcode, 1, _MLINE)
  2799.       DO killcr WITH m.thisline
  2800.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2801.       IF LEFT(m.upline,1) = '#'
  2802.          DO CASE
  2803.          CASE LEFT(m.upline,5) = "#READ"   && #READCLAUSES - Additional READ clauses
  2804.             IF m.g_rddir = .F.
  2805.                m.g_rddir = .T.
  2806.                m.g_rddirno = m.scrnno
  2807.             ENDIF
  2808.          CASE LEFT(m.upline,5) = "#NORE"   && #NOREAD - omit the READ statement
  2809.             m.g_noread = .T.
  2810.             IF AT(m.g_dblampersand,m.upline) > 0
  2811.                m.upline = LEFT(m.upline,AT(m.g_dblampersand,m.upline)-1)
  2812.             ENDIF 
  2813.             m.g_noreadplain = IIF(ATC(' PLAI',m.upline) > 0,.T.,.F.)
  2814.             IF m.g_noreadplain
  2815.                 m.g_openfiles    = .F.
  2816.                     m.g_closefiles   = .F.
  2817.                     m.g_defwin       = .F.
  2818.                     m.g_relwin       = .F.
  2819.             ENDIF
  2820.          ENDCASE
  2821.       ENDIF
  2822.    ENDFOR
  2823. ENDIF
  2824. RETURN
  2825.  
  2826. *!*****************************************************************************
  2827. *!
  2828. *!       Function: FINDSECTION
  2829. *!
  2830. *!      Called by: GENSECT1           (procedure in GENSCRN.PRG)
  2831. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  2832. *!
  2833. *!*****************************************************************************
  2834. FUNCTION findsection
  2835. *)
  2836. *) FINDSECTION - Find #SECT... directive.
  2837. *)
  2838. *) Description:
  2839. *) Locate and return the line on which the generator directive '#SECT'
  2840. *) is located on.  If no valid directive found, return 0.
  2841. *)
  2842. PARAMETER m.sectionid, m.memo
  2843. PRIVATE m.line, m.linecnt, m.textline
  2844. m.line    = ATCLINE("#SECT", m.memo)
  2845. m.linecnt = MEMLINE(m.memo)
  2846. DO WHILE m.line <= m.linecnt
  2847.    m.textline = LTRIM(MLINE(m.memo, m.line))
  2848.    DO killcr WITH m.textline
  2849.    IF ATC("#SECT", m.textline)=1
  2850.       IF m.sectionid = 1
  2851.          IF AT("1", m.textline)<>0
  2852.             m.sect1 = .T.
  2853.             RETURN m.line
  2854.          ELSE
  2855.             RETURN 0
  2856.          ENDIF
  2857.       ELSE
  2858.          IF AT("2", m.textline)<>0
  2859.             m.sect2 = .T.
  2860.             RETURN m.line
  2861.          ENDIF
  2862.       ENDIF
  2863.    ENDIF
  2864.    m.line = m.line + 1
  2865. ENDDO
  2866. RETURN 0
  2867.  
  2868. *!*****************************************************************************
  2869. *!
  2870. *!      Procedure: WRITECODE
  2871. *!
  2872. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  2873. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  2874. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  2875. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  2876. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  2877. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  2878. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  2879. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  2880. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  2881. *!               : INSERTFILE         (procedure in GENSCRN.PRG)
  2882. *!
  2883. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2884. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  2885. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  2886. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  2887. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  2888. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2889. *!               
  2890. *!*****************************************************************************
  2891. PROCEDURE writecode
  2892. *)
  2893. *) WRITECODE - Write contents of a memo to a low level file.
  2894. *)
  2895. *) Description:
  2896. *) Receive a memo field as a parameter and write its contents out
  2897. *) to the currently opened low level file whose handle is stored
  2898. *) in the system memory variable _TEXT.  Contents of the system
  2899. *) memory variable _PRETEXT will affect the positioning of the
  2900. *) generated text.
  2901. *)
  2902. PARAMETER m.memo, m.platname, m.start, m.end, m.scrnno, m.insetup
  2903. PRIVATE m.linecnt, m.i, m.line, m.upline, m.expr, m.platnum, m.at, m.in_exact
  2904.  
  2905. m.in_exact = SET("EXACT")
  2906. SET EXACT OFF
  2907.  
  2908. _MLINE = 0
  2909.  
  2910. m.start = MAX(1,m.start)  && if zero, start at 1
  2911.  
  2912. IF m.end > m.start
  2913.    m.linecnt = m.end-1
  2914. ELSE
  2915.    m.linecnt = MEMLINES(m.memo)
  2916. ENDIF
  2917.  
  2918. m.platnum = getplatnum(m.platname)
  2919.  
  2920. FOR m.i = 1 TO m.start - 1
  2921.    m.line = MLINE(m.memo, 1, _MLINE)
  2922. ENDFOR
  2923.  
  2924. * Window substitution names
  2925. m.subwindname = g_wnames[m.scrnno,m.platnum]
  2926. m.emptysubwind = IIF(EMPTY(m.subwindname),.T.,.F.)
  2927.  
  2928. IF NOT EMPTY(m.insetup)
  2929.    FOR m.i = m.start TO m.linecnt
  2930.       m.line = MLINE(m.memo, 1, _MLINE)
  2931.       DO killcr WITH m.line
  2932.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2933.       IF !geninsertcode(@upline,m.scrnno, m.insetup, m.platname)
  2934.          m.isparam =  isparameter(@upline)
  2935.          DO CASE
  2936.          CASE m.isparam
  2937.             * Accumulate continuation line but don't output it.
  2938.             DO WHILE RIGHT(m.upline,1) = ';'
  2939.                m.line = MLINE(m.memo, 1, _MLINE)
  2940.                m.upline = m.upline + ALLTRIM(UPPER(m.line))
  2941.                m.i = m.i + 1
  2942.             ENDDO
  2943.             DO killcr WITH m.line
  2944.          CASE m.upline = "#"
  2945.                * don't output a generator directive, but #DEFINES are OK
  2946.                IF LEFT(m.upline,5) = "#DEFI" ;
  2947.                     OR LEFT(m.upline,3) = "#IF" ;
  2948.                     OR LEFT(m.upline,5) = "#ELSE" ;
  2949.                     OR LEFT(m.upline,6) = "#ENDIF" ;
  2950.                     OR LEFT(m.upline,8) = "#INCLUDE" 
  2951.                 \<<m.line>>
  2952.                 ENDIF
  2953.            CASE m.emptysubwind    && the most common case
  2954.             \<<m.line>>
  2955.          OTHERWISE
  2956.             m.at = atwname(m.subwindname, m.line)
  2957.             IF m.at <> 0 AND !iscomment(@upline)
  2958.                m.expr = STUFF(m.line, m.at, ;
  2959.                   LEN(m.subwindname), ;
  2960.                   g_screens[m.scrnno,2])
  2961.                \<<m.expr>>
  2962.             ELSE
  2963.                \<<m.line>>
  2964.             ENDIF
  2965.          ENDCASE
  2966.       ENDIF
  2967.    ENDFOR
  2968. ELSE   && not in setup
  2969.    FOR m.i = m.start TO m.linecnt
  2970.       m.line = MLINE(m.memo, 1, _MLINE)
  2971.       DO killcr WITH m.line
  2972.       m.upline = UPPER(LTRIM(CHRTRAN(m.line,chr(9),' ')))
  2973.       DO writeline WITH m.line, m.platname, m.platnum, m.upline, m.scrnno
  2974.    ENDFOR
  2975. ENDIF
  2976. SET EXACT &in_exact
  2977. RETURN
  2978.  
  2979. *!*****************************************************************************
  2980. *!
  2981. *!      Procedure: WRITELINE
  2982. *!
  2983. *!      Called by: EMITPROC           (procedure in GENSCRN.PRG)
  2984. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  2985. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2986. *!
  2987. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2988. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  2989. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  2990. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  2991. *!
  2992. *!*****************************************************************************
  2993. PROCEDURE writeline
  2994. *)
  2995. *) WRITELINE - Emit a single line
  2996. *)
  2997. PARAMETER m.line, m.platname, m.platnum, m.upline, m.scrnno
  2998. PRIVATE m.at, m.expr
  2999.  
  3000. IF !geninsertcode(@upline, m.scrnno, .F., m.platname)   && by reference to save time
  3001.    IF !EMPTY(g_wnames[m.scrnno, m.platnum])
  3002.       m.at = atwname(g_wnames[m.scrnno, m.platnum], m.line)
  3003.       IF m.at <> 0 AND !iscomment(@upline)
  3004.          m.expr = STUFF(m.line, m.at, ;
  3005.             LEN(g_wnames[m.scrnno, m.platnum]), ;
  3006.             g_screens[m.scrnno,2])
  3007.          \<<m.expr>>
  3008.       ELSE
  3009.          IF !INLIST(LEFT(m.upline,2),"*!","*:") ;
  3010.                AND AT('#NAME', m.upline) <> 1
  3011.             \<<m.line>>
  3012.          ENDIF
  3013.       ENDIF
  3014.    ELSE
  3015.        * This code relies upon partial matching (e.g., "*! Comment" will equal "*")
  3016.       DO CASE
  3017.         CASE m.upline = "*"
  3018.            IF !(m.upline = "*!" OR m.upline = "*:")
  3019.             \<<m.line>>
  3020.             ENDIF
  3021.         CASE m.upline = "#"
  3022.            * don't output a generator directive, but #DEFINES are OK
  3023.            IF LEFT(m.upline,5) = "#DEFI" ;
  3024.                     OR LEFT(m.upline,3) = "#IF" ;
  3025.                     OR LEFT(m.upline,5) = "#ELSE" ;
  3026.                     OR LEFT(m.upline,6) = "#ENDIF" ;
  3027.                     OR LEFT(m.upline,8) = "#INCLUDE" 
  3028.             \<<m.line>>
  3029.            ENDIF
  3030.         OTHERWISE
  3031.          \<<m.line>>
  3032.       ENDCASE
  3033.    ENDIF
  3034. ENDIF
  3035. RETURN
  3036.  
  3037. *!*****************************************************************************
  3038. *!
  3039. *!      Procedure: GENINSERTCODE
  3040. *!
  3041. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3042. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3043. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3044. *!
  3045. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  3046. *!               : INSERTFILE         (procedure in GENSCRN.PRG)
  3047. *!
  3048. *!*****************************************************************************
  3049. PROCEDURE geninsertcode
  3050. *)
  3051. *) GENINSERTCODE - Emit code from the #insert file, if any
  3052. *)
  3053. *) Strg has to be trimmed before entering GenInsertCode.  It may be passed by reference.
  3054. PARAMETER m.strg, m.scrnno, m.insetup, m.platname
  3055. PRIVATE m.word1, m.filname
  3056. IF AT("#INSE",m.strg) = 1
  3057.    m.word1 = wordnum(m.strg,1)
  3058.    m.filname = SUBSTR(m.strg,LEN(m.word1)+1)
  3059.    m.filname = ALLTRIM(CHRTRAN(m.filname,CHR(9)," "))
  3060.    DO insertfile WITH m.filname, m.scrnno, m.insetup, m.platname
  3061.    RETURN .T.
  3062. ELSE
  3063.    RETURN .F.
  3064. ENDIF
  3065. RETURN
  3066.  
  3067. *!*****************************************************************************
  3068. *!
  3069. *!       Function: ISPARAMETER
  3070. *!
  3071. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3072. *!
  3073. *!          Calls: MATCH()            (function  in GENSCRN.PRG)
  3074. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  3075. *!
  3076. *!*****************************************************************************
  3077. FUNCTION isparameter
  3078. *)
  3079. *) ISPARAMETER - Determine if strg is a PARAMETERS statement
  3080. *)
  3081. PARAMETER m.strg
  3082. PRIVATE m.ispar
  3083. m.ispar = .F.
  3084. IF !EMPTY(strg) AND match(CHRTRAN(wordnum(strg,1),';',''),"PARAMETERS")
  3085.    m.ispar = .T.
  3086. ENDIF
  3087. RETURN m.ispar
  3088.  
  3089. *!*****************************************************************************
  3090. *!
  3091. *!       Function: ATWNAME
  3092. *!
  3093. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3094. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3095. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3096. *!
  3097. *!*****************************************************************************
  3098. FUNCTION atwname
  3099. *)
  3100. *) ATWNAME - Determine if valid m.string is in this line.
  3101. *)
  3102. *) Description:
  3103. *) Make sure that if m.string is in fact the string we want to do
  3104. *) the substitution on.
  3105. *)
  3106. PARAMETER m.string, m.line
  3107. PRIVATE m.pos, m.before, m.after
  3108. m.pos = AT(m.string,m.line)
  3109. IF m.pos = 0
  3110.    RETURN 0
  3111. ENDIF
  3112. IF m.pos = 1
  3113.    m.pos = AT(m.string+" ",m.line)
  3114. ELSE
  3115.    IF m.pos = LEN(m.line) - LEN(m.string) + 1
  3116.       m.pos = AT(" "+m.string,m.line)
  3117.       m.pos = IIF(m.pos<>0, m.pos+1,m.pos)
  3118.    ELSE
  3119.       m.before = SUBSTR(m.line,m.pos-1,1)
  3120.  
  3121.       IF m.before = c_under OR ;
  3122.             (m.before >= '0' AND m.before <= '9') OR ;
  3123.             (m.before >= 'a' AND m.before <= 'z') OR ;
  3124.             (m.before >= 'A' AND m.before <= 'Z')
  3125.  
  3126.          RETURN 0
  3127.       ENDIF
  3128.       m.after = SUBSTR(m.line,m.pos+LEN(m.string),1)
  3129.  
  3130.       IF m.after = c_under OR ;
  3131.             (m.after >= '0' AND m.after <= '9') OR ;
  3132.             (m.after >= 'a' AND m.after <= 'z') OR ;
  3133.             (m.after >= 'A' AND m.after <= 'Z')
  3134.  
  3135.          RETURN 0
  3136.       ENDIF
  3137.    ENDIF
  3138. ENDIF
  3139. RETURN m.pos
  3140.  
  3141. *!*****************************************************************************
  3142. *!
  3143. *!       Function: ISCOMMENT
  3144. *!
  3145. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3146. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3147. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3148. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  3149. *!
  3150. *!*****************************************************************************
  3151. FUNCTION iscomment
  3152. *)
  3153. *) ISCOMMENT - Determine if textline is a comment line.
  3154. *)
  3155. PARAMETER m.textline
  3156. PRIVATE m.asterisk, m.isnote, m.ampersand, m.statement
  3157. IF EMPTY(m.textline)
  3158.    RETURN .F.
  3159. ENDIF
  3160. m.statement = UPPER(LTRIM(m.textline))
  3161.  
  3162. m.asterisk  = AT("*", m.statement)
  3163. m.ampersand = AT(m.g_dblampersand, m.statement)
  3164. m.isnote    = AT("NOTE", m.statement)
  3165.  
  3166. DO CASE
  3167. CASE (m.asterisk = 1 OR m.ampersand = 1)
  3168.    RETURN .T.
  3169. CASE (m.isnote = 1 ;
  3170.       AND (LEN(m.statement) <= 4 OR SUBSTR(m.statement,5,1) = ' '))
  3171.    * Don't be fooled by something like "notebook = 7"
  3172.    RETURN .T.
  3173. ENDCASE
  3174. RETURN .F.
  3175.  
  3176. *!*****************************************************************************
  3177. *!
  3178. *!      Procedure: GENCLAUSECODE
  3179. *!
  3180. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  3181. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  3182. *!
  3183. *!          Calls: VALICLAUSE         (procedure in GENSCRN.PRG)
  3184. *!               : WHENCLAUSE         (procedure in GENSCRN.PRG)
  3185. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  3186. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  3187. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  3188. *!
  3189. *!*****************************************************************************
  3190. PROCEDURE genclausecode
  3191. *)
  3192. *) GENCLAUSECODE - Generate code for all read-level clauses.
  3193. *)
  3194. *) Description:
  3195. *) Generate functions containing the code from each screen's
  3196. *) READ level valid, show, when, activate, and deactivate clauses.
  3197. *)
  3198. PARAMETER m.screenno
  3199. DO valiclause WITH m.screenno
  3200. DO whenclause WITH m.screenno
  3201. DO acticlause WITH m.screenno
  3202. DO deatclause WITH m.screenno
  3203. DO showclause WITH m.screenno
  3204. RETURN
  3205.  
  3206. *!*****************************************************************************
  3207. *!
  3208. *!      Procedure: VALICLAUSE
  3209. *!
  3210. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3211. *!
  3212. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3213. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  3214. *!
  3215. *!*****************************************************************************
  3216. PROCEDURE valiclause
  3217. *)
  3218. *) VALICLAUSE - Generate Read level Valid clause function.
  3219. *)
  3220. *) Description:
  3221. *) Generate the function containing the code segment(s) provided
  3222. *) by the user for the read level VALID clause.
  3223. *) If multiple reads have been chosen, then this procedure generates
  3224. *) a function for a single screen.
  3225. *) If single read has been chosen and there are multiple screens,
  3226. *) we will concatenate valid clause code segments form all screens
  3227. *) to form a single function.
  3228. *)
  3229. PARAMETER m.screenno
  3230. PRIVATE m.i, m.dbalias, m.thispretext
  3231.  
  3232. IF m.g_validtype = "EXPR" OR EMPTY(m.g_validtype)
  3233.    RETURN
  3234. ENDIF
  3235. DO genfuncheader WITH m.g_validname, "Read Level Valid", .T.
  3236. \FUNCTION <<m.g_validname>>     && Read Level Valid
  3237.  
  3238. m.thispretext = _PRETEXT
  3239. _PRETEXT = ""
  3240. IF m.g_multreads
  3241.    DO genvalidbody WITH m.screenno
  3242. ELSE
  3243.    FOR m.i = 1 TO m.g_nscreens
  3244.       m.g_screen = m.i
  3245.       m.dbalias = g_screens[m.i,5]
  3246.       SELECT (m.dbalias)
  3247.       DO genvalidbody WITH m.i
  3248.    ENDFOR
  3249.    m.g_screen = 0
  3250. ENDIF
  3251. _PRETEXT = m.thispretext
  3252. RETURN
  3253.  
  3254. *!*****************************************************************************
  3255. *!
  3256. *!      Procedure: GENVALIDBODY
  3257. *!
  3258. *!      Called by: VALICLAUSE         (procedure in GENSCRN.PRG)
  3259. *!
  3260. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  3261. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3262. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3263. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3264. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3265. *!
  3266. *!*****************************************************************************
  3267. PROCEDURE genvalidbody
  3268. *)
  3269. *) GENVALIDBODY - Put out contents of a valid memo field.
  3270. *)
  3271. PARAMETER m.region
  3272. PRIVATE m.name, m.pos
  3273.  
  3274. IF g_screens[m.region, 6]
  3275.    LOCATE FOR objtype = c_otscreen
  3276. ELSE
  3277.    LOCATE FOR platform = g_screens[m.region, 7] AND objtype = c_otscreen
  3278. ENDIF
  3279. IF NOT FOUND()
  3280.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3281.       LINENO(), c_error_3
  3282.    RETURN
  3283. ENDIF
  3284. IF NOT EMPTY(VALID) AND validtype<>0
  3285.    IF NOT m.g_multread
  3286.       m.name  = basename(DBF())
  3287.       DO gencomment WITH "Valid Code from screen: "+m.name
  3288.    ENDIF
  3289.    \#REGION <<INT(m.region)>>
  3290.    DO writecode WITH VALID, getplatname(m.region), c_fromone, c_untilend, m.region
  3291. ENDIF
  3292. RETURN
  3293.  
  3294. *!*****************************************************************************
  3295. *!
  3296. *!      Procedure: WHENCLAUSE
  3297. *!
  3298. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3299. *!
  3300. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3301. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  3302. *!
  3303. *!*****************************************************************************
  3304. PROCEDURE whenclause
  3305. *)
  3306. *) WHENCLAUSE - Generate Read level When clause function.
  3307. *)
  3308. *) Description:
  3309. *) Generate the function containing the code segment(s) provided
  3310. *) by the user for the read level WHEN clause.
  3311. *) If multiple reads have been chosen, then this procedure generates
  3312. *) a function for a single screen (i.e., the one it has been called for).
  3313. *) If single read has been chosen and there are multiple screens,
  3314. *) we will concatenate when clause code segments from all screens
  3315. *) to form a single function.
  3316. *)
  3317. PARAMETER m.screenno
  3318. PRIVATE m.i, m.dbalias, m.thispretext
  3319.  
  3320. IF m.g_whentype = "EXPR" OR EMPTY(m.g_whentype)
  3321.    RETURN
  3322. ENDIF
  3323. DO genfuncheader WITH m.g_whenname, "Read Level When", .T.
  3324. \FUNCTION <<m.g_whenname>>     && Read Level When
  3325.  
  3326. m.thispretext = _PRETEXT
  3327. _PRETEXT = ""
  3328. IF m.g_multreads
  3329.    DO genwhenbody WITH m.screenno
  3330. ELSE
  3331.    FOR m.i = 1 TO m.g_nscreens
  3332.       m.g_screen = m.i
  3333.       m.dbalias = g_screens[m.i,5]
  3334.       SELECT (m.dbalias)
  3335.       DO genwhenbody WITH m.i
  3336.    ENDFOR
  3337.    m.g_screen = 0
  3338. ENDIF
  3339. _PRETEXT = m.thispretext
  3340. RETURN
  3341.  
  3342. *!*****************************************************************************
  3343. *!
  3344. *!      Procedure: GENWHENBODY
  3345. *!
  3346. *!      Called by: WHENCLAUSE         (procedure in GENSCRN.PRG)
  3347. *!
  3348. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  3349. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3350. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3351. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3352. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3353. *!
  3354. *!*****************************************************************************
  3355. PROCEDURE genwhenbody
  3356. *)
  3357. *) GENWHENBODY - Put out contents of when memo field.
  3358. *)
  3359. PARAMETER m.region
  3360. PRIVATE m.name, m.pos
  3361.  
  3362. IF g_screens[m.region, 6]
  3363.    LOCATE FOR objtype = c_otscreen
  3364. ELSE
  3365.    LOCATE FOR platform = g_screens[m.region, 7] AND objtype = c_otscreen
  3366. ENDIF
  3367. IF NOT FOUND()
  3368.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3369.       LINENO(), c_error_3
  3370.    RETURN
  3371. ENDIF
  3372.  
  3373. IF NOT EMPTY(WHEN) AND whentype<>0
  3374.    IF NOT m.g_multread
  3375.       m.name = basename(DBF())
  3376.       DO gencomment WITH "When Code from screen: "+m.name
  3377.    ENDIF
  3378.    \#REGION <<INT(m.region)>>
  3379.    DO writecode WITH WHEN, getplatname(m.region), c_fromone, c_untilend, m.region
  3380. ENDIF
  3381. RETURN
  3382.  
  3383. *!*****************************************************************************
  3384. *!
  3385. *!      Procedure: ACTICLAUSE
  3386. *!
  3387. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3388. *!
  3389. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3390. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3391. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3392. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3393. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3394. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3395. *!
  3396. *!*****************************************************************************
  3397. PROCEDURE acticlause
  3398. *)
  3399. *) ACTICLAUSE - Generate Read level Activate clause function.
  3400. *)
  3401. *) Description:
  3402. *) Generate the function containing the code segment(s) provided
  3403. *) by the user for the read level ACTIVATE clause.
  3404. *) If multiple reads have been chosen, then this procedure generates
  3405. *) a function for a single screen (i.e., the one it has been called for).
  3406. *) If single read has been chosen and there are multiple screens,
  3407. *) we will concatenate activate clause code segments from all screens
  3408. *) to form a single function.  Each individual screen's code
  3409. *) segment will be enclosed in "IF WOUTPUT('windowname')" statement.
  3410. *) Desk top will be represented by a null character. The above
  3411. *) mentioned is performed by the procedure genactibody.
  3412. *)
  3413. PARAMETER m.screenno
  3414. PRIVATE m.i, m.name
  3415.  
  3416. IF m.g_actitype = "EXPR" OR EMPTY(m.g_actitype)
  3417.    RETURN
  3418. ENDIF
  3419. DO genfuncheader WITH m.g_actiname, "Read Level Activate", .T.
  3420. \FUNCTION <<m.g_actiname>>     && Read Level Activate
  3421.  
  3422. IF m.g_multreads
  3423.    IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3424.       \#REGION <<INT(m.screenno)>>
  3425.       DO writecode WITH ACTIVATE, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3426.    ENDIF
  3427. ELSE
  3428.    FOR m.i = 1 TO m.g_nscreens
  3429.       m.g_screen = m.i
  3430.       m.dbalias = g_screens[m.i,5]
  3431.       SELECT (m.dbalias)
  3432.       IF g_screens[m.i, 6]
  3433.          LOCATE FOR objtype = c_otscreen
  3434.       ELSE
  3435.          LOCATE FOR platform = g_screens[m.i, 7] AND objtype = c_otscreen
  3436.       ENDIF
  3437.       IF NOT FOUND()
  3438.          DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3439.             LINENO(), c_error_3
  3440.          RETURN
  3441.       ENDIF
  3442.       IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3443.          m.name = basename(g_screens[m.i,1])
  3444.          DO gencomment WITH "Activate Code from screen: "+;
  3445.             m.name
  3446.       ENDIF
  3447.       IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3448.          \#REGION <<INT(m.i)>>
  3449.          DO writecode WITH ACTIVATE, getplatname(m.i), c_fromone, c_untilend, m.i
  3450.       ENDIF
  3451.    ENDFOR
  3452.    m.g_screen = 0
  3453. ENDIF
  3454. RETURN
  3455.  
  3456. *!*****************************************************************************
  3457. *!
  3458. *!      Procedure: DEATCLAUSE
  3459. *!
  3460. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3461. *!
  3462. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3463. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3464. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3465. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3466. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3467. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3468. *!
  3469. *!*****************************************************************************
  3470. PROCEDURE deatclause
  3471. *)
  3472. *) DEATCLAUSE - Generate Read level deactivate clause function.
  3473. *)
  3474. *) Description:
  3475. *) Generate the function containing the code segment(s) provided
  3476. *) by the user for the read level DEACTIVATE clause.
  3477. *) If multiple reads have been chosen, then this procedure generates
  3478. *) a function for a single screen (i.e., the one it has been called for).
  3479. *) If single read has been chosen and there are multiple screens,
  3480. *) we will concatenate deactivate clause code segments from all screens
  3481. *) to form a single function.  Each individual screen's code
  3482. *) segment will be enclosed in "IF WOUTPUT('windowname')" statement.
  3483. *) Desk top will be represented by a null character. The above
  3484. *) mentioned is performed by the procedure gendeatbody.
  3485. *)
  3486. PARAMETER m.screenno
  3487. PRIVATE m.i, m.name
  3488.  
  3489. IF m.g_deattype = "EXPR" OR EMPTY(m.g_deattype)
  3490.    RETURN
  3491. ENDIF
  3492. DO genfuncheader WITH m.g_deatname, "Read Level Deactivate", .T.
  3493. \FUNCTION <<m.g_deatname>>     && Read Level Deactivate
  3494.  
  3495. IF m.g_multreads
  3496.    IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3497.       \#REGION <<INT(m.screenno)>>
  3498.       DO writecode WITH DEACTIVATE, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3499.    ENDIF
  3500. ELSE
  3501.    FOR m.i = 1 TO m.g_nscreens
  3502.       m.g_screen = m.i
  3503.       m.dbalias = g_screens[m.i,5]
  3504.       SELECT (m.dbalias)
  3505.       IF g_screens[m.i,6]
  3506.          LOCATE FOR objtype = c_otscreen
  3507.       ELSE
  3508.          LOCATE FOR platform = g_screens[m.i, 7] AND objtype = c_otscreen
  3509.       ENDIF
  3510.       IF NOT FOUND()
  3511.          DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3512.             LINENO(), c_error_3
  3513.          RETURN
  3514.       ENDIF
  3515.       IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3516.          m.name = basename(g_screens[m.i,1])
  3517.          DO gencomment WITH "Deactivate Code from screen: "+;
  3518.             m.name
  3519.       ENDIF
  3520.       IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3521.          \#REGION <<INT(m.i)>>
  3522.          DO writecode WITH DEACTIVATE, getplatname(m.i), c_fromone, c_untilend, m.i
  3523.       ENDIF
  3524.    ENDFOR
  3525.    m.g_screen = 0
  3526. ENDIF
  3527. RETURN
  3528.  
  3529. *!*****************************************************************************
  3530. *!
  3531. *!      Procedure: SHOWCLAUSE
  3532. *!
  3533. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3534. *!
  3535. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3536. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3537. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3538. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3539. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  3540. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3541. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3542. *!
  3543. *!*****************************************************************************
  3544. PROCEDURE showclause
  3545. *)
  3546. *) SHOWCLAUSE - Generate Read level Show clause procedure.
  3547. *)
  3548. *) Description:
  3549. *) Generate the function containing the code segment(s) provided
  3550. *) by the user for the read level SHOW clause.  The function generated
  3551. *) for the show clause will consist of refreshable @...SAY code and
  3552. *) code segment(s) if applicable. If multiple reads have been chosen,
  3553. *) then this procedure generates a function for a single screen
  3554. *) (i.e., the one it has been called for).  If single read has been
  3555. *) chosen and there are multiple screens, we will concatenate show
  3556. *) clause code segments from all screens to form a single function.
  3557. *) Each individual screen's refreshable SAYs will be enclosed in
  3558. *) "IF SYS(2016)=('windowname') OR SYS(2016) = '*'" statement.
  3559. *) (Desk top will be represented by a null character.)
  3560. *)
  3561. PARAMETER m.screenno
  3562. PRIVATE m.i, m.comment, m.name, m.thispretext, m.oldshow, m.showmod
  3563.  
  3564. IF m.g_showtype = "EXPR" OR EMPTY(m.g_showtype)
  3565.    RETURN
  3566. ENDIF
  3567. DO genfuncheader WITH m.g_showname, "Read Level Show", .T.
  3568.  
  3569. \FUNCTION <<m.g_showname>>     && Read Level Show
  3570. \PRIVATE currwind
  3571.  
  3572. \STORE WOUTPUT() TO currwind
  3573. m.thispretext = _PRETEXT
  3574. _PRETEXT = ""
  3575.  
  3576. IF m.g_multreads
  3577.    DO seekheader WITH m.screenno
  3578.    m.oldshow = Show
  3579.  
  3580.    m.showmod = ChkShow()
  3581.  
  3582.    m.comment = .T.
  3583.    \#REGION <<INT(m.screenno)>>
  3584.    IF NOT EMPTY(show) AND showtype<>0
  3585.       DO writecode WITH show, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3586.    ENDIF
  3587.    DO placesays WITH m.comment, m.g_showname, m.screenno
  3588.    IF m.showmod
  3589.       REPLACE show WITH m.oldshow
  3590.    ENDIF
  3591. ELSE
  3592.    FOR m.i = 1 TO m.g_nscreens
  3593.       m.g_screen = m.i
  3594.       m.dbalias = g_screens[m.i,5]
  3595.       SELECT (m.dbalias)
  3596.       m.comment = .F.
  3597.  
  3598.       DO seekheader WITH m.i
  3599.  
  3600.       m.name = basename(g_screens[m.i,1])
  3601.       IF NOT EMPTY(show) AND showtype<>0
  3602.          m.oldshow = Show   && record show snippet
  3603.          m.showmod = ChkShow()         && may modify show snippet directly
  3604.  
  3605.          DO gencomment WITH "Show Code from screen: "+m.name
  3606.          \#REGION <<INT(m.i)>>
  3607.          m.comment = .T.
  3608.          DO writecode WITH show, getplatname(m.i), c_fromone, c_untilend, m.i
  3609.          IF m.showmod
  3610.             REPLACE show WITH m.oldshow
  3611.          ENDIF
  3612.       ENDIF
  3613.       DO seekheader WITH m.i
  3614.       DO placesays WITH m.comment, m.name, m.i
  3615.    ENDFOR
  3616.    m.g_screen = 0
  3617. ENDIF
  3618. _PRETEXT = m.thispretext
  3619.  
  3620. IF !m.g_noreadplain
  3621.    \IF NOT EMPTY(currwind)
  3622.    \    ACTIVATE WINDOW (currwind) SAME
  3623.    \ENDIF
  3624. ENDIF
  3625. RETURN
  3626.  
  3627. *!*****************************************************************************
  3628. *!
  3629. *!      Function: CHKSHOW
  3630. *!
  3631. *!*****************************************************************************
  3632. FUNCTION chkshow
  3633. PRIVATE m.thelineno, m.theline, m.oldmline, m.upline, m.newshow, m.found_one, m.leadspace, ;
  3634.    m.oldtext, m.theword, m.getsonly, m.j
  3635. * Check for a poisonous SHOW GETS in the SHOW snippet.  If one if executed
  3636. * there, runaway recursion results.
  3637. IF c_checkshow == 0   && check to see if this safety feature is enabled.
  3638.    RETURN .F.
  3639. ENDIF
  3640. m.thelineno = ATCLINE("SHOW GETS",show)
  3641. m.oldmline = _MLINE
  3642. m.oldtext = _TEXT
  3643. m.found_one = .F.
  3644. IF m.thelineno > 0
  3645.    * Step through the SHOW snippet a line at a time, commenting out any SHOW GETS or
  3646.    * SHOW GETS OFF statements.
  3647.    m.newshow = ""
  3648.    _MLINE = 0
  3649.    DO WHILE _MLINE < LEN(show)
  3650.       m.theline = MLINE(show,1,_MLINE)
  3651.       DO killcr WITH m.theline
  3652.       m.upline  = UPPER(LTRIM(m.theline))
  3653.       IF wordnum(m.upline,1) == "SHOW" AND wordnum(m.upline,2) == "GETS" ;
  3654.              AND (EMPTY(wordnum(m.upline,3)) OR wordnum(m.upline,3) == "OFF")
  3655.          m.leadspace = LEN(m.theline) - LEN(m.upline)
  3656.          m.newshow = m.newshow + SPACE(m.leadspace) + ;
  3657.             "* Commented out by GENSCRN: " + LTRIM(m.theline) + CHR(13) + CHR(10)
  3658.          DO errorhandler WITH "SHOW GETS statement commented out of SHOW snippet.",;
  3659.               LINENO(),c_error_1
  3660.          m.found_one = .T.
  3661.       ELSE
  3662.          m.newshow = m.newshow + m.theline + CHR(13) + CHR(10)
  3663.       ENDIF
  3664.    ENDDO
  3665.    IF m.found_one
  3666.       REPLACE show WITH m.newshow
  3667.    ENDIF
  3668. ENDIF
  3669. _MLINE = m.oldmline
  3670. _TEXT  = m.oldtext
  3671. RETURN m.found_one
  3672.  
  3673. *!*****************************************************************************
  3674. *!
  3675. *!      Procedure: PLACESAYS
  3676. *!
  3677. *!      Called by: SHOWCLAUSE         (procedure in GENSCRN.PRG)
  3678. *!
  3679. *!          Calls: GENCOMMENT         (procedure in GENSCRN.PRG)
  3680. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  3681. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  3682. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  3683. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  3684. *!               : ANYPICTURE         (procedure in GENSCRN.PRG)
  3685. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  3686. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  3687. *!
  3688. *!*****************************************************************************
  3689. PROCEDURE placesays
  3690. *)
  3691. *) PLACESAYS - Generate @...SAY for refreshable says in the .PRG file.
  3692. *)
  3693. *) Description:
  3694. *) Place @...SAY code for all refreshable say statements into
  3695. *) the generated SHOW clause function.
  3696. *)
  3697. PARAMETER m.comment, m.scrnname, m.g_thisscreen
  3698. PRIVATE m.iswindow, m.sayfound, m.windowname, m.theexpr, m.occur, m.pos
  3699.  
  3700. IF EMPTY(STYLE)
  3701.    m.iswindow = .F.
  3702. ELSE
  3703.    m.iswindow = .T.
  3704.    m.windowname = g_screens[m.g_thisscreen,2]
  3705. ENDIF
  3706. m.sayfound = .T.
  3707. SCAN FOR ((objtype = c_otfield AND objcode = c_sgsay) OR ;
  3708.       (objtype = c_otpicture)) AND ;
  3709.       REFRESH = .T. AND (g_screens[m.g_thisscreen, 6] OR platform = g_screens[m.g_thisscreen, 7])
  3710.    IF m.sayfound
  3711.       IF NOT m.comment
  3712.          DO gencomment WITH "Show Code from screen: "+m.scrnname
  3713.          \#REGION <<INT(m.g_thisscreen)>>
  3714.       ENDIF
  3715.       IF !m.g_noreadplain    && not just emitting plain @ SAYs/GETs
  3716.          \IF SYS(2016) =
  3717.          IF m.iswindow
  3718.             \\ "<<UPPER(m.windowname)>>" OR SYS(2016) = "*"
  3719.             \    ACTIVATE WINDOW <<m.windowname>> SAME
  3720.          ELSE
  3721.             \\ "" OR SYS(2016) = "*"
  3722.             \    ACTIVATE SCREEN
  3723.          ENDIF
  3724.       ENDIF
  3725.       m.sayfound = .F.
  3726.    ENDIF
  3727.  
  3728.    IF objtype = c_otpicture
  3729.       DO genpicture
  3730.    ELSE
  3731.       m.theexpr = expr
  3732.       IF g_screens[m.g_thisscreen, 7] = 'WINDOWS' OR g_screens[m.g_thisscreen, 7] = 'MAC'
  3733.          SET DECIMALS TO 3
  3734.          m.occur = 1
  3735.          m.pos = AT(CHR(13), m.theexpr, m.occur)
  3736.  
  3737.          * Sometimes the screen builder surrounds text with single quotes and other
  3738.          * times with double quotes.
  3739.          q1 = LEFT(LTRIM(m.theexpr),1)
  3740.  
  3741.          DO WHILE m.pos > 0
  3742.             IF q1 = "'"
  3743.                m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  3744.                   "' + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "'" ;
  3745.                   + SUBSTR(m.theexpr, m.pos + 1)
  3746.             ELSE
  3747.                m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  3748.                   '" + CHR(13) + ;' + CHR(13)  + CHR(9) + CHR(9) + '"' ;
  3749.                   + SUBSTR(m.theexpr, m.pos + 1)
  3750.             ENDIF
  3751.             m.occur = m.occur + 1
  3752.             m.pos = AT(CHR(13), m.theexpr, m.occur)
  3753.          ENDDO
  3754.          IF mode = 1 AND objtype = c_otfield  AND objcode = c_sgsay    && transparent SAY text
  3755.             * Clear the space that the SAY is going into.  This makes refreshable SAYS
  3756.             * work with transparent fonts.
  3757.             \    @ <<Vpos>>,<<Hpos>> CLEAR TO <<Vpos+Height>>,<<Hpos+Width>>
  3758.          ENDIF
  3759.       ENDIF
  3760.       \    @ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  3761.       \        SIZE <<Height>>,<<Width>>, <<Spacing>>
  3762.       SET DECIMALS TO 0
  3763.       DO pushindent
  3764.       DO anyfont
  3765.       DO anystyle
  3766.       DO anypicture
  3767.       DO anyscheme
  3768.       DO popindent
  3769.    ENDIF
  3770. ENDSCAN
  3771. IF NOT m.sayfound
  3772.    \ENDIF
  3773. ENDIF
  3774. RETURN
  3775.  
  3776. *!*****************************************************************************
  3777. *!
  3778. *!      Procedure: GENCLOSEDBFS
  3779. *!
  3780. *!      Called by: GENCLNENVIRON      (procedure in GENSCRN.PRG)
  3781. *!
  3782. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  3783. *!               : UNIQUEDBF()        (function  in GENSCRN.PRG)
  3784. *!
  3785. *!*****************************************************************************
  3786. PROCEDURE genclosedbfs
  3787. *)
  3788. *) GENCLOSEDBFS - Generate code to close all previously opened databases.
  3789. *)
  3790. PRIVATE m.i, m.dbalias, m.dbfcnt, m.firstfound
  3791. m.firstfound = .T.
  3792. m.dbfcnt = 0
  3793. g_dbfs = ""
  3794. FOR m.i = 1 TO m.g_nscreens
  3795.    m.g_screen = m.i
  3796.    m.dbalias = g_screens[m.i,5]
  3797.    SELECT (m.dbalias)
  3798.    SCAN FOR objtype = c_otworkarea AND (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  3799.       IF m.firstfound
  3800.          DO commentblock WITH ""," Closing Databases"
  3801.          m.firstfound = .F.
  3802.       ENDIF
  3803.       IF uniquedbf(TAG)
  3804.          m.dbfcnt = m.dbfcnt + 1
  3805.          DIMENSION g_dbfs[m.dbfcnt]
  3806.          g_dbfs[m.dbfcnt] = TAG
  3807.       ELSE
  3808.          LOOP
  3809.       ENDIF
  3810.       \IF USED("<<LOWER(stripext(strippath(Tag)))>>")
  3811.       \    SELECT <<LOWER(stripext(strippath(Tag)))>>
  3812.       \    USE
  3813.       \ENDIF
  3814.       \
  3815.    ENDSCAN
  3816. ENDFOR
  3817. m.g_screen = 0
  3818. IF m.g_closefiles 
  3819.    \SELECT (m.currarea)
  3820.    \
  3821. ENDIF
  3822. DIMENSION g_dbfs[1]
  3823. RETURN
  3824.  
  3825. *!*****************************************************************************
  3826. *!
  3827. *!      Procedure: GENOPENDBFS
  3828. *!
  3829. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  3830. *!
  3831. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  3832. *!               : UNIQUEDBF()        (function  in GENSCRN.PRG)
  3833. *!               : GENUSESTMTS        (procedure in GENSCRN.PRG)
  3834. *!               : STRIPPATH()        (function  in GENSCRN.PRG)
  3835. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3836. *!               : GENRELATIONS       (procedure in GENSCRN.PRG)
  3837. *!
  3838. *!*****************************************************************************
  3839. PROCEDURE genopendbfs
  3840. *)
  3841. *) GENOPENDBFS - Generate USE... statement(s).
  3842. *)
  3843. *) Description:
  3844. *) Generate code to open databases, set indexes, and relations as
  3845. *) specified by the user.
  3846. *)
  3847. PRIVATE m.dbalias, m.i, m.dbfcnt, m.string, m.msg, m.firstfound
  3848. m.firstfound = .T.
  3849. FOR m.i = 1 TO m.g_nscreens
  3850.    m.g_screen = m.i
  3851.    m.dbalias = g_screens[m.i,5]
  3852.    SELECT (m.dbalias)
  3853.    m.dbfcnt = 0
  3854.    SCAN FOR objtype = c_otworkarea AND (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  3855.       IF m.firstfound
  3856.          DO commentblock WITH m.dbalias, ;
  3857.             " Databases, Indexes, Relations"
  3858.          m.firstfound = .F.
  3859.       ENDIF
  3860.       IF uniquedbf(TAG)
  3861.          m.dbfcnt = m.dbfcnt + 1
  3862.          DIMENSION g_dbfs[m.dbfcnt]
  3863.          g_dbfs[m.dbfcnt] = TAG
  3864.       ELSE
  3865.          LOOP
  3866.       ENDIF
  3867.       DO genusestmts WITH m.i
  3868.    ENDSCAN
  3869.  
  3870.    IF m.dbfcnt > 1
  3871.       IF NOT EMPTY(m.g_current)
  3872.          \SELECT <<m.g_current>>
  3873.       ELSE
  3874.          m.msg = "Please RE-SAVE screen environment... SCREEN: "+;
  3875.             strippath(g_screens[m.i,1])
  3876.          DO errorhandler WITH m.msg, LINENO(), c_error_1
  3877.       ENDIF
  3878.       \
  3879.    ENDIF
  3880. ENDFOR
  3881. m.g_screen = 0
  3882. DO genrelations
  3883. RETURN
  3884.  
  3885. *!*****************************************************************************
  3886. *!
  3887. *!       Function: UNIQUEDBF
  3888. *!
  3889. *!      Called by: GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  3890. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  3891. *!
  3892. *!*****************************************************************************
  3893. FUNCTION uniquedbf
  3894. *)
  3895. *) UNIQUEDBF - Check if database name already seen.
  3896. *)
  3897. PARAMETER m.dbfname
  3898. RETURN IIF(ASCAN(g_dbfs, m.dbfname)=0,.T.,.F.)
  3899.  
  3900. *!*****************************************************************************
  3901. *!
  3902. *!      Procedure: GENUSESTMTS
  3903. *!
  3904. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  3905. *!
  3906. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  3907. *!               : GENORDER           (procedure in GENSCRN.PRG)
  3908. *!               : GENINDEXES()       (function  in GENSCRN.PRG)
  3909. *!
  3910. *!*****************************************************************************
  3911. PROCEDURE genusestmts
  3912. *)
  3913. *) GENUSESTMTS - Generate USE... statements
  3914. *)
  3915. *) Description:
  3916. *) Generate USE... statements for each database encoded in the
  3917. *) screen database.  Generate ORDER statement if appropriate.
  3918. *)
  3919. PARAMETER m.i
  3920. PRIVATE m.workarea, saverecno, MARGIN, m.name, m.order, m.tag
  3921. m.workarea  = objcode
  3922. saverecno = RECNO()
  3923. m.order   = LOWER(ALLTRIM(ORDER))
  3924. m.tag     = LOWER(ALLTRIM(tag2))
  3925. m.name    = LOWER(TAG)
  3926. m.relpath = LOWER(findrelpath(name))
  3927.  
  3928. IF UNIQUE AND EMPTY(m.g_current)
  3929.    m.g_current = m.name
  3930. ENDIF
  3931.  
  3932. MARGIN = 4
  3933. IF EMPTY(name)
  3934.    \SELECT <<m.name>>
  3935.    RETURN
  3936. ENDIF
  3937. \IF USED("<<m.name>>")
  3938. \    SELECT <<m.name>>
  3939. IF genindexes ("select", m.i)=0
  3940.    indexfound = 0
  3941.    \    SET ORDER TO
  3942.    DO genorder WITH indexfound,m.order,m.tag,m.name
  3943. ELSE
  3944.    indexfound = 1
  3945.    \\ ADDITIVE ;
  3946.    \        ORDER
  3947.    DO genorder WITH indexfound,m.order,m.tag,m.name
  3948. ENDIF
  3949.  
  3950. \ELSE
  3951. \    SELECT 0
  3952. \    USE (LOCFILE("<<m.relpath>>","DBF",
  3953. \\"Where is <<basename(m.relpath)>>?"));
  3954. \        AGAIN ALIAS <<m.name>>
  3955. MARGIN = 42+LEN(m.relpath)+2*LEN(m.name)
  3956. = genindexes("use", m.i)
  3957.  
  3958. GOTO saverecno
  3959. \\ ;
  3960. \        ORDER
  3961. DO genorder WITH indexfound,m.order,m.tag,m.name
  3962. \ENDIF
  3963. \
  3964. RETURN
  3965.  
  3966. *!*****************************************************************************
  3967. *!
  3968. *!       Function: FINDRELPATH
  3969. *!
  3970. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3971. *!               : GENINDEXES()       (function  in GENSCRN.PRG)
  3972. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  3973. *!               : ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  3974. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  3975. *!               : ANYICON            (procedure in GENSCRN.PRG)
  3976. *!
  3977. *!*****************************************************************************
  3978. FUNCTION findrelpath
  3979. *)
  3980. *) FINDRELPATH - Find relative path for DATABASES.
  3981. *)
  3982. PARAMETER m.name
  3983. PRIVATE m.fullpath, m.relpath
  3984. m.fullpath = UPPER(FULLPATH(m.name, g_screens[1,1]))
  3985. m.relpath  = SYS(2014, m.fullpath, UPPER(m.g_homedir))
  3986. RETURN m.relpath
  3987.  
  3988. *!*****************************************************************************
  3989. *!
  3990. *!      Procedure: GENORDER
  3991. *!
  3992. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3993. *!
  3994. *!*****************************************************************************
  3995. PROCEDURE genorder
  3996. *)
  3997. *) GENORDER - Generate ORDER clause.
  3998. *)
  3999. PARAMETER m.indexfound, m.order, m.tag, m.dbfname
  4000. IF EMPTY(m.order) AND EMPTY(m.tag)
  4001.    \\ 0
  4002.    RETURN
  4003. ENDIF
  4004. IF m.indexfound=0
  4005.    \\ TAG "<<m.tag>>"
  4006. ELSE
  4007.    IF EMPTY(m.tag)
  4008.       \\ <<basename(m.order)>>
  4009.    ELSE
  4010.       \\ TAG "<<m.tag>>"
  4011.       IF NOT EMPTY (m.order)
  4012.          \\ OF <<m.order>>
  4013.       ENDIF
  4014.    ENDIF
  4015. ENDIF
  4016. RETURN
  4017.  
  4018. *!*****************************************************************************
  4019. *!
  4020. *!       Function: GENINDEXES
  4021. *!
  4022. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  4023. *!
  4024. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  4025. *!
  4026. *!*****************************************************************************
  4027. FUNCTION genindexes
  4028. *)
  4029. *) GENINDEXES - Generate index names for a USE statement.
  4030. *)
  4031. PARAMETER m.placement, m.i
  4032. PRIVATE m.idxcount, m.relpath
  4033. m.idxcount = 0
  4034.  
  4035. SCAN FOR objtype = c_otindex AND objcode = WORKAREA AND;
  4036.       (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4037.    m.relpath = LOWER(findrelpath(name))
  4038.    IF m.idxcount > 0
  4039.       IF MARGIN > 55
  4040.          MARGIN = 8 + LEN(m.relpath)
  4041.          \\, ;
  4042.          \        <<m.relpath>>
  4043.       ELSE
  4044.          \\, <<m.relpath>>
  4045.          MARGIN = MARGIN + 2 + LEN(m.relpath)
  4046.       ENDIF
  4047.    ELSE
  4048.       IF m.placement = "use"
  4049.          \\ ;
  4050.          \        INDEX <<m.relpath>>
  4051.          MARGIN = 8 + LEN(m.relpath)
  4052.       ELSE
  4053.          \    SET INDEX TO <<m.relpath>>
  4054.          MARGIN = 17
  4055.          MARGIN = MARGIN + LEN(m.relpath)
  4056.       ENDIF
  4057.    ENDIF
  4058.    m.idxcount = m.idxcount + 1
  4059. ENDSCAN
  4060. RETURN m.idxcount
  4061.  
  4062. *!*****************************************************************************
  4063. *!
  4064. *!      Procedure: GENRELATIONS
  4065. *!
  4066. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  4067. *!
  4068. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  4069. *!               : GENRELSTMTS        (procedure in GENSCRN.PRG)
  4070. *!
  4071. *!*****************************************************************************
  4072. PROCEDURE genrelations
  4073. *)
  4074. *) GENRELATIONS - Generate code to set all existing relations as they
  4075. *)                 are encoded in the screen file(s).
  4076. *)
  4077. *) Description:
  4078. *) Generate code for all relations as encoded in the screen database.
  4079. *)
  4080. PRIVATE m.dbalias, m.i
  4081. FOR m.i = 1 TO m.g_nscreens
  4082.    m.g_screen = m.i
  4083.    m.dbalias  = g_screens[m.i,5]
  4084.    SELECT (m.dbalias)
  4085.  
  4086.    DO seekheader WITH m.i
  4087.    DO genrelstmts WITH m.i
  4088. ENDFOR
  4089. m.g_screen = 0
  4090. RETURN
  4091.  
  4092. *!*****************************************************************************
  4093. *!
  4094. *!      Procedure: GENRELSTMTS
  4095. *!
  4096. *!      Called by: GENRELATIONS       (procedure in GENSCRN.PRG)
  4097. *!
  4098. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  4099. *!
  4100. *!*****************************************************************************
  4101. PROCEDURE genrelstmts
  4102. *)
  4103. *) GENRELSTMTS - Generate relation statements.
  4104. *)
  4105. PARAMETER m.i
  4106. PRIVATE m.saverec, m.last, m.firstrel, m.firstsel, m.dbalias, m.setskip
  4107. m.dbalias  = ""
  4108. m.firstrel = .T.
  4109. m.firstsel = .T.
  4110. m.last     = 0
  4111. m.setskip  = ""
  4112.  
  4113. SCAN FOR objtype = c_otrel AND ;
  4114.       (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4115.    IF m.last<> objcode
  4116.       IF NOT (m.firstrel OR EMPTY(m.setskip))
  4117.          \SET SKIP TO <<m.setskip>>
  4118.          \
  4119.       ENDIF
  4120.       m.saverec = RECNO()
  4121.       m.last= objcode
  4122.  
  4123.       SCAN FOR objtype = c_otworkarea AND objcode = m.last AND ;
  4124.             (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4125.          m.dbalias = LOWER(basename(TAG))
  4126.          IF NOT (m.firstrel AND m.g_current = m.dbalias)
  4127.             \SELECT <<m.dbalias>>
  4128.          ENDIF
  4129.          m.setskip = ALLTRIM(LOWER(expr))
  4130.       ENDSCAN
  4131.  
  4132.       GOTO RECORD m.saverec
  4133.       m.firstrel = .F.
  4134.    ENDIF
  4135.  
  4136.    IF !(m.firstsel AND LOWER(tag2) == LOWER(m.g_current))
  4137.       \SELECT <<LOWER(Tag2)>>
  4138.       \
  4139.    ENDIF
  4140.    \SET RELATION OFF INTO <<LOWER(Tag)>>
  4141.    \SET RELATION TO <<LOWER(Expr)>> INTO <<LOWER(Tag)>> ADDITIVE
  4142.    \
  4143.  
  4144.    m.firstsel = .F.
  4145. ENDSCAN
  4146.  
  4147. IF m.last<> 0
  4148.    IF NOT EMPTY(m.setskip)
  4149.       \SET SKIP TO <<m.setskip>>
  4150.       \
  4151.    ENDIF
  4152.    IF NOT EMPTY(m.g_current)
  4153.       \SELECT <<m.g_current>>
  4154.    ENDIF
  4155. ENDIF
  4156. RETURN
  4157.  
  4158. **
  4159. ** Code Associated With Building of the Format file statements.
  4160. **
  4161.  
  4162. *!*****************************************************************************
  4163. *!
  4164. *!      Procedure: BUILDFMT
  4165. *!
  4166. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4167. *!
  4168. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  4169. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  4170. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  4171. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  4172. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4173. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4174. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  4175. *!               : ANYWINDOWS         (procedure in GENSCRN.PRG)
  4176. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  4177. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  4178. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  4179. *!               : GENLINES           (procedure in GENSCRN.PRG)
  4180. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  4181. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  4182. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  4183. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  4184. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  4185. *!               : GENLIST            (procedure in GENSCRN.PRG)
  4186. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  4187. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  4188. *!               : GENACTISTMTS       (procedure in GENSCRN.PRG)
  4189. *!               : PLACEREAD          (procedure in GENSCRN.PRG)
  4190. *!
  4191. *!*****************************************************************************
  4192. PROCEDURE buildfmt
  4193. *)
  4194. *) BUILDFMT - Build Format file statements.
  4195. *)
  4196. *) Description:
  4197. *) Generate all boxes, text, fields, push buttons, radio buttons,
  4198. *) popups, check boxes and scrollable lists encoded in a screen set.
  4199. *)
  4200. PARAMETER pnum   && platform number
  4201. PRIVATE m.pos, m.dbalias, m.adjuster, m.recadjust, m.increment, m.i, m.sn
  4202. m.msg = 'Generating Screen Code'
  4203. IF multiplat()
  4204.    m.msg = m.msg + " for "+versioncap(m.g_genvers, m.g_dualoutput)
  4205. ENDIF
  4206. DO putmsg WITH m.msg
  4207. m.g_nwindows = 0
  4208. m.adjuster   = INT((c_therm4-c_therm3)/m.g_nscreens)  && total therm. range to cover
  4209. m.recadjust  = c_therm3                 && starting position for thermometer
  4210. FOR m.sn = 1 TO m.g_nscreens
  4211.    m.g_screen = m.sn
  4212.    m.dbalias = g_screens[m.sn,5]
  4213.    SELECT (m.dbalias)
  4214.    DO seekheader WITH m.sn
  4215.  
  4216.    DO commentblock WITH g_screens[m.sn,1], " Screen Layout"
  4217.    \#REGION <<INT(m.sn)>>
  4218.    IF ATC('#ITSE',setupcode)<>0
  4219.       DO gendirective WITH ;
  4220.          MLINE(setupcode,ATCLINE('#ITSE',setupcode)),;
  4221.          '#ITSE'
  4222.    ENDIF
  4223.  
  4224.    * Figure out thermometer increment
  4225.    IF g_screens[m.sn, 6] OR m.g_numplatforms = 1
  4226.       m.recs = RECCOUNT()
  4227.    ELSE 
  4228.       GOTO TOP
  4229.       COUNT FOR platform = g_screens[m.sn, 7] TO m.recs
  4230.    ENDIF 
  4231.    m.increment = m.adjuster/m.recs
  4232.  
  4233.    SCAN FOR (g_screens[m.sn, 6] OR platform = g_screens[m.sn, 7])
  4234.       m.recadjust = m.recadjust + m.increment
  4235.  
  4236.       DO updtherm WITH thermadj(m.pnum,INT(m.recadjust),c_therm5)
  4237.  
  4238.       DO genusercode WITH c_premode
  4239.       
  4240.       DO CASE
  4241.       CASE objtype = c_otscreen
  4242.          DO anywindows WITH (m.sn)
  4243.       CASE objtype = c_ottext
  4244.          DO gentext
  4245.       CASE objtype = c_otfield
  4246.          DO genfields
  4247.       CASE objtype = c_otbox
  4248.          DO genboxes
  4249.       CASE objtype = c_otline
  4250.          DO genlines
  4251.       CASE objtype = c_ottxtbut
  4252.          DO genpush
  4253.       CASE objtype = c_otradbut
  4254.          DO genradbut
  4255.       CASE objtype = c_otinvbut
  4256.          DO geninvbut
  4257.       CASE objtype = c_otpopup
  4258.          DO genpopup
  4259.       CASE objtype = c_otchkbox
  4260.          DO genchkbox
  4261.       CASE objtype = c_otlist
  4262.          DO genlist
  4263.       CASE objtype = c_otpicture
  4264.          DO genpicture
  4265.       CASE objtype = c_otspinner
  4266.          DO genspinner
  4267.       ENDCASE
  4268.       
  4269.       DO genusercode WITH c_postmode
  4270.       
  4271.    ENDSCAN
  4272.    DO genactistmts WITH (m.sn)
  4273.    IF !m.g_noread
  4274.       DO placeread WITH (m.sn)
  4275.    ENDIF
  4276. ENDFOR
  4277. m.g_screen = 0
  4278. RETURN
  4279.  
  4280.  
  4281. *!*****************************************************************************
  4282. *!
  4283. *!      Procedure: GENUSERCODE
  4284. *!
  4285. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4286. *!
  4287. *!*****************************************************************************
  4288. PROCEDURE genusercode
  4289. PARAMETER usermode
  4290. PRIVATE m.thelinenum, m.theline, m.thecommand, m.tagline
  4291.  
  4292. IF m.usermode = c_premode
  4293.     m.tagline = c_userprecode
  4294. ELSE
  4295.      m.tagline = c_userpostcode
  4296. ENDIF
  4297.          
  4298. m.thelinenum = ATCLINE(m.tagline, comment)
  4299. IF m.thelinenum > 0
  4300.     m.theline = MLINE(comment, m.thelinenum)
  4301.     m.thecommand = ALLTRIM(SUBSTR(m.theline, LEN(m.tagline)+1))
  4302.     \<<m.thecommand>>
  4303. ENDIF
  4304.  
  4305. *!*****************************************************************************
  4306. *!
  4307. *!      Procedure: ANYWINDOWS
  4308. *!
  4309. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4310. *!
  4311. *!          Calls: GENACTWINDOW       (procedure in GENSCRN.PRG)
  4312. *!
  4313. *!*****************************************************************************
  4314. PROCEDURE anywindows
  4315. *)
  4316. *) ANYWINDOWS - Issue ACTIVATE WINDOW ... SAME.
  4317. *)
  4318. *) Description:
  4319. *) If windows present issue ACTIVATE WINDOW...SAME to make sure
  4320. *) that the windows stack on screen in the correct order.
  4321. *)
  4322. PARAMETER m.scrnno
  4323. PRIVATE m.pos
  4324. IF m.g_noreadplain
  4325.    RETURN
  4326. ENDIF
  4327.    
  4328. IF NOT EMPTY(STYLE)
  4329.    DO genactwindow WITH m.scrnno
  4330.  
  4331.    m.g_lastwindow = g_screens[m.scrnno,2]
  4332.    m.pos = ASCAN(g_wndows, m.g_lastwindow)
  4333.    * m.pos contains the element number (not the row) that matches.
  4334.    * The element number + 1 is a number representing window sequence.
  4335.    IF EMPTY(g_wndows[m.pos+1])
  4336.       m.g_nwindows = m.g_nwindows + 1
  4337.       g_wndows[m.pos+1] = m.g_nwindows
  4338.    ENDIF
  4339.  
  4340.    m.g_defasch1 = SCHEME
  4341.    m.g_defasch2 = scheme2
  4342. ELSE
  4343.    m.g_defasch1 = 0
  4344.    m.g_defasch2 = 0
  4345.  
  4346.    IF m.g_lastwindow<>""
  4347.       \HIDE WINDOW ALL
  4348.       \ACTIVATE SCREEN
  4349.       m.g_lastwindow = ""
  4350.    ENDIF
  4351. ENDIF
  4352. RETURN
  4353.  
  4354. *!*****************************************************************************
  4355. *!
  4356. *!      Procedure: GENACTISTMTS
  4357. *!
  4358. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4359. *!
  4360. *!*****************************************************************************
  4361. PROCEDURE genactistmts
  4362. *)
  4363. *) GENACTISTMTS - Generate Activate window statements.
  4364. *)
  4365. *) Description:
  4366. *) Generate ACTIVATE WINDOW... statements in order to activate all
  4367. *) windows which have been previously activated with SAME clause.
  4368. *)
  4369. PARAMETER m.scrnno
  4370. PRIVATE m.j, m.pos
  4371. \
  4372. IF m.scrnno=m.g_nscreens AND NOT m.g_multreads AND NOT m.g_noreadplain
  4373.    IF m.g_nwindows = 1
  4374.       \IF NOT WVISIBLE("<<g_wndows[1,1]>>")
  4375.       \    ACTIVATE WINDOW <<g_wndows[1,1]>>
  4376.       \ENDIF
  4377.       RETURN
  4378.    ENDIF
  4379.    FOR m.j = m.g_nwindows TO 1 STEP -1
  4380.       m.pos = ASCAN(g_wndows, m.j)
  4381.       * pos contains the element *numbered* j.  This will be somewhere in g_wndows[*,2].
  4382.       * Look to the preceding element to get the window name.
  4383.       IF m.pos<>0
  4384.          \IF NOT WVISIBLE("<<g_wndows[m.pos-1]>>")
  4385.          \    ACTIVATE WINDOW <<g_wndows[m.pos-1]>>
  4386.          \ENDIF
  4387.       ENDIF
  4388.    ENDFOR
  4389.    \
  4390. ENDIF
  4391. RETURN
  4392.  
  4393. *!*****************************************************************************
  4394. *!
  4395. *!      Procedure: PLACEREAD
  4396. *!
  4397. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4398. *!
  4399. *!          Calls: ANYMODAL           (procedure in GENSCRN.PRG)
  4400. *!               : ANYLOCK            (procedure in GENSCRN.PRG)
  4401. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4402. *!               : GENWITHCLAUSE      (procedure in GENSCRN.PRG)
  4403. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  4404. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4405. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4406. *!               : GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4407. *!               : GENCLAUSECODE      (procedure in GENSCRN.PRG)
  4408. *!
  4409. *!*****************************************************************************
  4410. PROCEDURE placeread
  4411. *)
  4412. *) PLACEREAD - Generate a 'READ' statement.
  4413. *)
  4414. *) Description:
  4415. *) Called once per screen in the screen set.
  4416. *) Generate a READ statement.  Depending on whether this is a single
  4417. *) or multiread the read statement may be generated between @...SAY/GETs
  4418. *) from each screen or at the end of a set of all @...SAY/GETs.
  4419. *)
  4420. PARAMETER m.scrnno
  4421. PRIVATE thispretext
  4422.  
  4423. \
  4424. IF m.g_multreads
  4425.    DO newreadclauses
  4426.    \READ
  4427.    IF m.g_readcycle AND m.scrnno = m.g_nscreens
  4428.       \\ CYCLE
  4429.    ENDIF
  4430.    DO anymodal
  4431.    DO anylock
  4432.    DO doplaceclause WITH m.scrnno
  4433.    DO genwithclause
  4434.    DO gengivenread WITH m.scrnno
  4435. ELSE
  4436.    IF NOT EMPTY(m.g_rddir) AND m.scrnno = m.g_nscreens
  4437.       DO commentblock WITH "","READ contains clauses from SCREEN "+;
  4438.          LOWER(g_screens[m.g_rddirno,5])
  4439.    ENDIF
  4440.    DO findreadclauses WITH m.scrnno
  4441.    IF m.scrnno = m.g_nscreens
  4442.       \READ
  4443.       IF m.g_readcycle
  4444.          \\ CYCLE
  4445.       ENDIF
  4446.       DO anymodal
  4447.       DO anylock
  4448.       DO genreadclauses
  4449.       DO genwithclause
  4450.       DO gengivenread WITH m.scrnno
  4451.       _TEXT = m.g_tmphandle
  4452.       m.thispretext = _PRETEXT
  4453.       _PRETEXT = ""
  4454.       DO genclausecode WITH m.scrnno
  4455.       _TEXT = m.g_orghandle
  4456.       _PRETEXT = m.thispretext
  4457.    ENDIF
  4458. ENDIF
  4459. \
  4460. RETURN
  4461.  
  4462. *!*****************************************************************************
  4463. *!
  4464. *!      Procedure: ANYMODAL
  4465. *!
  4466. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4467. *!
  4468. *!*****************************************************************************
  4469. *)
  4470. *) ANYMODAL - Generate MODAL clause on READ.
  4471. *)
  4472. PROCEDURE anymodal
  4473. IF m.g_readmodal
  4474.    \\ MODAL
  4475. ENDIF
  4476. RETURN
  4477.  
  4478. *!*****************************************************************************
  4479. *!
  4480. *!      Procedure: ANYLOCK
  4481. *!
  4482. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4483. *!
  4484. *!*****************************************************************************
  4485. PROCEDURE anylock
  4486. *)
  4487. *) ANYLOCK - Generate LOCK/NOLOCK clause on READ.
  4488. *)
  4489. IF m.g_readlock
  4490.    \\ NOLOCK
  4491. ENDIF
  4492. RETURN
  4493.  
  4494. *!*****************************************************************************
  4495. *!
  4496. *!      Procedure: GENWITHCLAUSE
  4497. *!
  4498. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4499. *!
  4500. *!*****************************************************************************
  4501. PROCEDURE genwithclause
  4502. *)
  4503. *) GENWITHCLAUSE - Generate WITH clause on a READ.
  4504. *)
  4505. IF NOT EMPTY(m.g_withlist)
  4506.    \\ ;
  4507.    \    WITH <<m.g_withlist>>
  4508. ENDIF
  4509. RETURN
  4510.  
  4511. *!*****************************************************************************
  4512. *!
  4513. *!      Procedure: DOPLACECLAUSE
  4514. *!
  4515. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4516. *!
  4517. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  4518. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4519. *!               : GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4520. *!               : GENCLAUSECODE      (procedure in GENSCRN.PRG)
  4521. *!
  4522. *!*****************************************************************************
  4523. PROCEDURE doplaceclause
  4524. *)
  4525. *) DOPLACECLAUSE - Place READ level clauses for multiple reads.
  4526. *)
  4527. *) Description:
  4528. *) According to the read level clauses encoded in the screen file
  4529. *) set variables holding information about each clause.
  4530. *)
  4531. PARAMETER m.scrnno
  4532. PRIVATE thispretext
  4533. IF g_screens[m.scrnno, 6]
  4534.    LOCATE FOR objtype = c_otscreen
  4535. ELSE
  4536.    LOCATE FOR platform = g_screens[m.scrnno, 7] AND objtype = c_otscreen
  4537. ENDIF
  4538. IF NOT FOUND()
  4539.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  4540.       LINENO(), c_error_3
  4541.    RETURN
  4542. ENDIF
  4543.  
  4544. DO findreadclauses WITH m.scrnno
  4545. DO genreadclauses
  4546. _TEXT = m.g_tmphandle
  4547. m.thispretext = _PRETEXT
  4548. _PRETEXT = ""
  4549.  
  4550. DO genclausecode WITH m.scrnno
  4551. _TEXT = m.g_orghandle
  4552. _PRETEXT = m.thispretext
  4553. RETURN
  4554.  
  4555. *!*****************************************************************************
  4556. *!
  4557. *!      Procedure: FINDREADCLAUSES
  4558. *!
  4559. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4560. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4561. *!
  4562. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  4563. *!               : SETCLAUSEFLAGS     (procedure in GENSCRN.PRG)
  4564. *!               : ORCLAUSEFLAGS      (procedure in GENSCRN.PRG)
  4565. *!
  4566. *!*****************************************************************************
  4567. PROCEDURE findreadclauses
  4568. *)
  4569. *) FINDREADCLAUSES - Find clauses for the final READ statement.
  4570. *)
  4571. *) Description:
  4572. *) Keep track of clauses that were already seen to determine what
  4573. *) clauses are placed on final read.  If this procedure is called for
  4574. *) a multiple read setting, flag's settings apply only to the current
  4575. *) screen.
  4576. *)
  4577. PARAMETER m.scrnno
  4578. PRIVATE m.dbalias, m.cur_rec
  4579. IF g_screens[m.scrnno,6]
  4580.    LOCATE FOR objtype = c_otscreen
  4581. ELSE
  4582.    LOCATE FOR platform = g_screens[m.scrnno, 7] AND objtype = c_otscreen
  4583. ENDIF
  4584. IF NOT FOUND()
  4585.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  4586.       LINENO(), c_error_3
  4587.    RETURN
  4588. ENDIF
  4589.  
  4590. IF EMPTY(m.g_validtype) AND !EMPTY(VALID)
  4591.    DO setclauseflags WITH validtype, VALID, m.g_validname,;
  4592.       m.g_validtype
  4593. ENDIF
  4594. IF EMPTY(m.g_whentype) AND !EMPTY(WHEN)
  4595.    DO setclauseflags  WITH whentype, WHEN, m.g_whenname,;
  4596.       m.g_whentype
  4597. ENDIF
  4598. IF EMPTY(m.g_actitype) AND !EMPTY(ACTIVATE)
  4599.    DO setclauseflags WITH activtype, ACTIVATE, m.g_actiname,;
  4600.       m.g_actitype
  4601. ENDIF
  4602. IF EMPTY(m.g_deattype) AND !EMPTY(DEACTIVATE)
  4603.    DO setclauseflags WITH deacttype, DEACTIVATE, m.g_deatname,;
  4604.       m.g_deattype
  4605. ENDIF
  4606.  
  4607. * SHOW is a special case since it can be generated with both procedures (for refreshable
  4608. * SAYs or just regular procedures) and expressions.  OR the flags together.
  4609. IF !EMPTY(SHOW)
  4610.    IF showtype != c_genexpr
  4611.       DO orclauseflags WITH showtype, SHOW, m.g_showname, m.g_showtype
  4612.    ELSE
  4613.       m.cur_rec = RECNO()
  4614.       * It's an expression, but look for refreshable SAYs too.
  4615.       LOCATE FOR ((objtype = c_otfield AND objcode = c_sgsay) OR (objtype = c_otpicture)) AND ;
  4616.          REFRESH = .T. AND (g_screens[m.scrnno, 6] OR platform = g_screens[m.scrnno, 7])
  4617.       IF FOUND()
  4618.          GOTO m.cur_rec
  4619.          DO orclauseflags WITH c_genboth, SHOW,   m.g_showname, m.g_showtype
  4620.       ELSE
  4621.          GOTO m.cur_rec
  4622.          DO orclauseflags WITH c_genexpr, SHOW,   m.g_showname, m.g_showtype
  4623.       ENDIF
  4624.       m.g_showexpr = m.g_showname
  4625.    ENDIF
  4626. ELSE
  4627.    * Look for refreshable SAYS
  4628.    LOCATE FOR ((objtype = c_otfield AND objcode = c_sgsay) OR (objtype = c_otpicture)) AND ;
  4629.       REFRESH = .T. AND (g_screens[m.scrnno, 6] OR platform = g_screens[m.scrnno, 7])
  4630.    IF FOUND()
  4631.       DO orclauseflags WITH c_gencode, SHOW,   m.g_showname, m.g_showtype
  4632.    ENDIF
  4633. ENDIF
  4634. RETURN
  4635.  
  4636. *!*****************************************************************************
  4637. *!
  4638. *!      Procedure: SETCLAUSEFLAGS
  4639. *!
  4640. *!      Called by: FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4641. *!
  4642. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  4643. *!
  4644. *!*****************************************************************************
  4645. PROCEDURE setclauseflags
  4646. *)
  4647. *) SETCLAUSEFLAGS - Load global flags with information about clauses.
  4648. *)
  4649. *) Description:
  4650. *) If a clause is a snippet then a generic name is provided for the
  4651. *) clause call statement in the READ and that same name is used to
  4652. *) construct the corresponding function.
  4653. *)
  4654. *) The BOTH setting is used for SHOW clauses that are defined as expressions,
  4655. *) in screens that also contain refreshable SAYS.  We have to generate a
  4656. *) procedure to contain the code to refresh the SAYS.
  4657. *)
  4658. PARAMETER m.flagtype, m.memo, m.name, m.type
  4659. DO CASE
  4660. CASE m.flagtype = c_genexpr
  4661.    m.name = m.memo
  4662.    m.type = "EXPR"
  4663. CASE m.flagtype = c_genboth
  4664.    m.name = m.memo
  4665.    m.type = "BOTH"
  4666. OTHERWISE
  4667.    m.name = getcname(m.memo)
  4668.    m.type = "CODE"
  4669. ENDCASE
  4670. RETURN
  4671.  
  4672. *!*****************************************************************************
  4673. *!
  4674. *!      Procedure: ORCLAUSEFLAGS
  4675. *!
  4676. *!      Called by: FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4677. *!
  4678. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  4679. *!
  4680. *!*****************************************************************************
  4681. PROCEDURE orclauseflags
  4682. *)
  4683. *) ORCLAUSEFLAGS - Logical OR two flagtypes
  4684. *)
  4685. PARAMETER m.flagtype, m.memo, m.name, m.type
  4686. DO CASE
  4687. CASE m.flagtype = c_genexpr
  4688.    m.name = m.memo
  4689.    IF INLIST(m.type,"BOTH","CODE")
  4690.       m.type = "BOTH"
  4691.    ELSE
  4692.       m.type = "EXPR"
  4693.    ENDIF
  4694. CASE m.flagtype = c_genboth
  4695.    m.name = m.memo
  4696.    m.type = "BOTH"
  4697. OTHERWISE
  4698.    * Code of some sort.  The expr code is different for expanded snippets, closed snippets, etc.
  4699.    * It is 2 for expanded snippets and 3 for minimized snippets, for example.
  4700.    m.name = getcname(m.memo)
  4701.    IF INLIST(m.type,"BOTH","EXPR")
  4702.       m.type = "BOTH"
  4703.    ELSE
  4704.       m.type = "CODE"
  4705.    ENDIF
  4706. ENDCASE
  4707. RETURN
  4708.  
  4709. *!*****************************************************************************
  4710. *!
  4711. *!      Procedure: GENREADCLAUSES
  4712. *!
  4713. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4714. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4715. *!
  4716. *!          Calls: GENCLAUSE          (procedure in GENSCRN.PRG)
  4717. *!
  4718. *!*****************************************************************************
  4719. PROCEDURE genreadclauses
  4720. *)
  4721. *) GENREADCLAUSES - Generate Clauses on a READ.
  4722. *)
  4723. *) Description:
  4724. *) Check if clause is appropriate, if so call GENCLAUSE to
  4725. *) generate the clause keyword.
  4726. *)
  4727. IF NOT EMPTY(m.g_validtype)
  4728.    DO genclause WITH "VALID", m.g_validname, m.g_validtype
  4729. ENDIF
  4730. IF NOT EMPTY(m.g_whentype)
  4731.    DO genclause WITH "WHEN", m.g_whenname, m.g_whentype
  4732. ENDIF
  4733. IF NOT EMPTY(m.g_actitype)
  4734.    DO genclause WITH "ACTIVATE", m.g_actiname, m.g_actitype
  4735. ENDIF
  4736. IF NOT EMPTY(m.g_deattype)
  4737.    DO genclause WITH "DEACTIVATE", m.g_deatname, m.g_deattype
  4738. ENDIF
  4739. IF NOT EMPTY(m.g_showtype)
  4740.    DO genclause WITH "SHOW", m.g_showname, m.g_showtype, m.g_showexpr
  4741. ENDIF
  4742. RETURN
  4743.  
  4744. *!*****************************************************************************
  4745. *!
  4746. *!      Procedure: GENCLAUSE
  4747. *!
  4748. *!      Called by: GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4749. *!
  4750. *!*****************************************************************************
  4751. PROCEDURE genclause
  4752. *)
  4753. *) GENCLAUSE - Generate Read Level Clause keyword.
  4754. *)
  4755. *) Description:
  4756. *) Generate SHOW,ACTIVATE,WHEN, or VALID clause keyword for a
  4757. *) READ statement.
  4758. *)
  4759. PARAMETER m.keyword, m.name, m.type, m.expr
  4760. PRIVATE m.codename
  4761. \\ ;
  4762. \    <<m.keyword>>
  4763. DO CASE
  4764. CASE m.type = "CODE"
  4765.    \\ <<m.name>>
  4766.    \\()
  4767. CASE m.type = "EXPR"
  4768.    \\ <<stripCR(m.name)>>
  4769. CASE m.type = "BOTH"
  4770.    * This is tricky.  We need to generate the user's expression followed by
  4771.    * a procedure, presumably containing code to handle refreshable SAYS in
  4772.    * a READ ... SHOW clause.  Right now, the name variable contains the
  4773.    * expression.  Emit it, generate a random name for the SHOW snippet, then
  4774.    * record that random name in the m.name field so that we can remember it
  4775.    * later.  The expression needs to come second (due to the boolean short-cutting
  4776.    * optimization in the interpreter).
  4777.    IF EMPTY(m.expr)
  4778.       m.codename = LOWER(SYS(2015))
  4779.       \\ <<m.codename>>() AND (<<stripCR(m.name)>>)
  4780.       m.name     = m.codename
  4781.    ELSE
  4782.       * There was an explicit expression passed to us.  Use it.
  4783.       m.codename = LOWER(SYS(2015))
  4784.       \\ <<m.codename>>() AND (<<stripCR(m.expr)>>)
  4785.       m.name     = m.codename
  4786.    ENDIF
  4787. ENDCASE
  4788. RETURN
  4789.  
  4790. *!*****************************************************************************
  4791. *!
  4792. *!      Procedure: GENGIVENREAD
  4793. *!
  4794. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4795. *!
  4796. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  4797. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4798. *!
  4799. *!*****************************************************************************
  4800. PROCEDURE gengivenread
  4801. *)
  4802. *) GENGIVENREAD - Generate another clause on the READ.
  4803. *)
  4804. PARAMETER m.screen
  4805. PRIVATE m.i, m.dbalias
  4806. IF m.g_multreads
  4807.    DO seekheader WITH m.screen
  4808.  
  4809.    IF ATC('#READ',setupcode) <> 0
  4810.       DO gendirective WITH ;
  4811.          MLINE(setupcode,ATCLINE('#READ',setupcode)),'#READ'
  4812.    ENDIF
  4813. ELSE
  4814.    FOR m.i = 1 TO m.g_nscreens
  4815.       m.g_screen = m.i
  4816.       m.dbalias = g_screens[m.i,5]
  4817.       SELECT (m.dbalias)
  4818.       DO seekheader WITH m.i
  4819.  
  4820.       IF ATC('#READ',setupcode)<>0
  4821.          DO gendirective WITH ;
  4822.             MLINE(setupcode,ATCLINE('#READ',setupcode)),'#READ'
  4823.          RETURN
  4824.       ENDIF
  4825.    ENDFOR
  4826.    m.g_screen = 0
  4827. ENDIF
  4828. RETURN
  4829.  
  4830. *!*****************************************************************************
  4831. *!
  4832. *!      Procedure: GENDIRECTIVE
  4833. *!
  4834. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4835. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  4836. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  4837. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  4838. *!
  4839. *!          Calls: SKIPWHITESPACE()   (function  in GENSCRN.PRG)
  4840. *!
  4841. *!*****************************************************************************
  4842. PROCEDURE gendirective
  4843. *)
  4844. *) GENDIRECTIVE - Process #ITSEXPRESSION, #READCLAUSES generator directives.
  4845. *)
  4846. PARAMETER m.line, m.directive
  4847. PRIVATE m.newline
  4848. IF ATC(m.directive,m.line)=1
  4849.    IF UPPER(m.directive) = '#REDE'
  4850.       m.g_redefi = .T.
  4851.       RETURN
  4852.    ENDIF
  4853.    m.newline = skipwhitespace(m.line)
  4854.    IF NOT EMPTY(m.newline)
  4855.       DO CASE
  4856.       CASE UPPER(m.directive) = '#READ'
  4857.          \\ ;
  4858.          \    <<UPPER(m.newline)>>
  4859.       CASE UPPER(m.directive) = '#WCLA'
  4860.          \\ ;
  4861.          \    <<UPPER(m.newline)>>
  4862.       CASE UPPER(m.directive) = '#ITSE'
  4863.          m.g_itse = SUBSTR(m.newline,1,1)
  4864.       ENDCASE
  4865.    ENDIF
  4866. ENDIF
  4867. RETURN
  4868.  
  4869. *!*****************************************************************************
  4870. *!
  4871. *!       Function: SKIPWHITESPACE
  4872. *!
  4873. *!      Called by: PREPWNAMES         (procedure in GENSCRN.PRG)
  4874. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4875. *!
  4876. *!*****************************************************************************
  4877. FUNCTION skipwhitespace
  4878. *)
  4879. *) SKIPWHITESPACE - Trim all white space from parameter string.
  4880. *)
  4881. PARAMETER m.line
  4882. PRIVATE m.whitespace
  4883. m.whitespace = AT(' ',m.line)
  4884. IF m.whitespace = 0
  4885.    m.whitespace = AT(CHR(9),m.line)
  4886. ENDIF
  4887. m.line = ALLTRIM(SUBSTR(m.line,m.whitespace))
  4888. DO WHILE SUBSTR(m.line,1,1) = CHR(9)
  4889.    m.line = ALLTRIM(SUBSTR(m.line, 2))
  4890. ENDDO
  4891. RETURN m.line
  4892.  
  4893. **
  4894. ** Code Generating Various Screen Objects
  4895. **
  4896.  
  4897. *!*****************************************************************************
  4898. *!
  4899. *!      Procedure: DEFPOPUPS
  4900. *!
  4901. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4902. *!
  4903. *!          Calls: GENPOPDEFI         (procedure in GENSCRN.PRG)
  4904. *!
  4905. *!*****************************************************************************
  4906. PROCEDURE defpopups
  4907. *)
  4908. *) DEFPOPUPS - Define popups used in scrollable list definition.
  4909. *)
  4910. *) Description:
  4911. *) Define popup which is later used in the definition of a
  4912. *) scrollable list.
  4913. *)
  4914. PRIVATE m.i, m.dbalias, m.cnt, m.anylists
  4915. m.cnt = 0
  4916. FOR m.i = 1 TO m.g_nscreens
  4917.    m.g_screen = m.i
  4918.    m.anylists = .F.
  4919.    m.dbalias = g_screens[m.i,5]
  4920.    SELECT (m.dbalias)
  4921.    SCAN FOR objtype = c_otlist AND STYLE > 1 AND ;
  4922.          (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4923.       IF NOT m.anylists
  4924.          \
  4925.          \#REGION <<INT(m.i)>>
  4926.          m.anylists = .T.
  4927.          m.g_somepops = .T.
  4928.       ENDIF
  4929.       m.cnt = m.cnt + 1
  4930.       g_popups[m.cnt,1] = m.dbalias
  4931.       g_popups[m.cnt,2] = RECNO()
  4932.       g_popups[m.cnt,3] = LOWER(SYS(2015))
  4933.  
  4934.       IF MOD(m.cnt,25)=0
  4935.          DIMENSION g_popups[ALEN(g_popups,1)+25,3]
  4936.       ENDIF
  4937.  
  4938.       DO genpopdefi
  4939.    ENDSCAN
  4940. ENDFOR
  4941. m.g_screen = 0
  4942. RETURN
  4943.  
  4944. *!*****************************************************************************
  4945. *!
  4946. *!      Procedure: GENPOPDEFI
  4947. *!
  4948. *!      Called by: DEFPOPUPS          (procedure in GENSCRN.PRG)
  4949. *!
  4950. *!*****************************************************************************
  4951. PROCEDURE genpopdefi
  4952. *)
  4953. *) GENPOPDEFI
  4954. *)
  4955. IF m.g_noreadplain
  4956.    RETURN
  4957. ENDIF
  4958.    
  4959. \DEFINE POPUP <<g_popups[m.cnt,3]>> ;
  4960. DO CASE
  4961. CASE STYLE = 2
  4962.    \    PROMPT STRUCTURE
  4963. CASE STYLE = 3
  4964.    \    PROMPT FIELD <<ALLTRIM(Expr)>>
  4965. CASE STYLE = 4
  4966.    \    PROMPT FILES
  4967.    IF NOT EMPTY(expr)
  4968.       \\ LIKE <<ALLTRIM(Expr)>>
  4969.    ENDIF
  4970. ENDCASE
  4971. \\ ;
  4972. \    SCROLL
  4973. IF m.g_genvers = 'DOS' OR m.g_genvers = 'UNIX'
  4974.    \\ ;
  4975.    \    MARGIN ;
  4976.    \    MARK ""
  4977.    \
  4978. ENDIF
  4979. RETURN
  4980.  
  4981. *!*****************************************************************************
  4982. *!
  4983. *!      Procedure: RELPOPUPS
  4984. *!
  4985. *!      Called by: GENCLNENVIRON      (procedure in GENSCRN.PRG)
  4986. *!
  4987. *!*****************************************************************************
  4988. PROCEDURE relpopups
  4989. *)
  4990. *) RELPOPUPS - Generate code to release generated popups.
  4991. *)
  4992. *) Description:
  4993. *) Generate code to release all popups defined by the generator
  4994. *) in conjunction with generating scrollable lists.
  4995. *)
  4996. PRIVATE m.popcnt, m.i, m.margin
  4997. m.popcnt = ALEN(g_popups,1)
  4998. m.margin = 16
  4999.  
  5000. IF EMPTY(g_popups[1,1]) OR m.g_noreadplain
  5001.    RETURN
  5002. ENDIF
  5003.  
  5004. \RELEASE POPUPS <<g_popups[1,3]>>
  5005. m.i = 2
  5006. DO WHILE m.i <= m.popcnt
  5007.    IF EMPTY(g_popups[m.i,1])
  5008.       RETURN
  5009.    ENDIF
  5010.    IF m.margin > 60
  5011.       m.margin = 4
  5012.       \\,;
  5013.       \    <<g_popups[m.i,3]>>
  5014.    ELSE
  5015.       \\, <<g_popups[m.i,3]>>
  5016.    ENDIF
  5017.    m.margin = m.margin + 3 + LEN(g_popups[m.i,3])
  5018.    m.i = m.i + 1
  5019. ENDDO
  5020. \
  5021. RETURN
  5022.  
  5023. *!*****************************************************************************
  5024. *!
  5025. *!      Procedure: DEFWINDOWS
  5026. *!
  5027. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  5028. *!
  5029. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  5030. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  5031. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  5032. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  5033. *!
  5034. *!*****************************************************************************
  5035. PROCEDURE defwindows
  5036. *)
  5037. *) DEFWINDOWS - Generate code for windows.
  5038. *)
  5039. *) Description:
  5040. *) Generate code to define windows designed in the screen builder.
  5041. *) Process all SCX databases and if window definitions found
  5042. *) call GENWINDEFI to define the windows.
  5043. *)
  5044. PRIVATE m.dbalias, m.pos, m.savearea, m.row, m.col, m.firstfound, m.i
  5045. m.firstfound = .T.
  5046. m.savearea = SELECT()
  5047. FOR m.i = 1 TO m.g_nscreens
  5048.    m.g_screen = m.i
  5049.    m.dbalias = g_screens[m.i,5]
  5050.    SELECT (m.dbalias)
  5051.  
  5052.    SCAN FOR objtype = c_otscreen AND ;
  5053.          (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  5054.  
  5055.       IF m.firstfound AND !m.g_noreadplain
  5056.          DO commentblock WITH ""," Window definitions"
  5057.          m.firstfound = .F.
  5058.       ENDIF
  5059.  
  5060.       IF NOT EMPTY(STYLE)
  5061.          IF ATC('#ITSE',setupcode)<>0
  5062.             DO gendirective WITH ;
  5063.                MLINE(setupcode,ATCLINE('#ITSE',setupcode)),'#ITSE'
  5064.          ENDIF
  5065.          IF ATC('#REDE',setupcode)<>0
  5066.             DO gendirective WITH ;
  5067.                MLINE(setupcode,ATCLINE('#REDE',setupcode)),'#REDE'
  5068.          ENDIF
  5069.          DO genwindefi WITH m.i
  5070.       ELSE
  5071.          IF ATC('#ITSE',setupcode)<>0
  5072.             DO gendirective WITH ;
  5073.                MLINE(setupcode,ATCLINE('#ITSE',setupcode)),'#ITSE'
  5074.          ENDIF
  5075.          DO gendesktop WITH m.i
  5076.       ENDIF
  5077.    ENDSCAN
  5078. ENDFOR
  5079. m.g_screen = 0
  5080. SELECT (m.savearea)
  5081. RETURN
  5082.  
  5083. *!*****************************************************************************
  5084. *!
  5085. *!      Procedure: GENDESKTOP
  5086. *!
  5087. *!      Called by: DEFWINDOWS         (procedure in GENSCRN.PRG)
  5088. *!
  5089. *!          Calls: WINDOWFROMTO       (procedure in GENSCRN.PRG)
  5090. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  5091. *!               : ANYTITLEORFOOTER   (procedure in GENSCRN.PRG)
  5092. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5093. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5094. *!               : ANYWINDOWCHARS     (procedure in GENSCRN.PRG)
  5095. *!               : ANYBORDER          (procedure in GENSCRN.PRG)
  5096. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  5097. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5098. *!               : ANYICON            (procedure in GENSCRN.PRG)
  5099. *!
  5100. *!*****************************************************************************
  5101. PROCEDURE gendesktop
  5102. *)
  5103. *) GENDESKTOP - Generate statements to change the desktop font
  5104. *)
  5105. *) Description:
  5106. *) Generate code to change the desktop font if this screen is on
  5107. *) the desktop.  This is done only if the user chose the define window
  5108. *) option in the generate dialog.
  5109. *)
  5110. PARAMETER m.g_screen
  5111. PRIVATE m.center_flag, m.arrange_flag, m.row, m.col, m.j, m.entries
  5112.  
  5113. IF (g_screens[m.g_screen, 7] != 'WINDOWS' AND g_screens[m.g_screen, 7] != 'MAC')
  5114.    RETURN
  5115. ENDIF
  5116.  
  5117. m.center_flag = .F.
  5118. m.arrange_flag = .F.
  5119.  
  5120. IF NOT m.g_defwin
  5121.    RETURN
  5122. ENDIF
  5123.  
  5124. m.g_moddesktop = .T.
  5125.  
  5126. \MODIFY WINDOW SCREEN ;
  5127.  
  5128. IF g_screens[m.g_screen,6]
  5129.    DO windowfromto
  5130.    IF m.g_genvers = "WINDOWS" OR m.g_genvers = "MAC"
  5131.       \\ ;
  5132.       \    FONT "FoxFont", 9
  5133.    ENDIF
  5134. ELSE
  5135.    SELECT (m.g_projalias)
  5136.    GOTO RECORD g_screens[m.g_screen,3]
  5137.  
  5138.    DO getarrange WITH m.dbalias, m.arrange_flag, m.center_flag
  5139.  
  5140.    DO anytitleorfooter
  5141.    DO anyfont
  5142.    DO anystyle
  5143.    DO anywindowchars
  5144.    DO anyborder
  5145.  
  5146.    IF  !EMPTY(PICTURE)
  5147.       DO anywallpaper
  5148.    ELSE
  5149.       DO anyscheme
  5150.    ENDIF
  5151.    DO anyicon
  5152.  
  5153.    IF (CENTER OR m.center_flag) AND !m.arrange_flag
  5154.       \MOVE WINDOW SCREEN CENTER
  5155.    ENDIF
  5156. ENDIF
  5157. \CLEAR
  5158. RETURN
  5159.  
  5160. *!*****************************************************************************
  5161. *!
  5162. *!      Procedure: GENWINDEFI
  5163. *!
  5164. *!      Called by: DEFWINDOWS         (procedure in GENSCRN.PRG)
  5165. *!
  5166. *!          Calls: UNIQUEWIN()        (function  in GENSCRN.PRG)
  5167. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  5168. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  5169. *!               : ANYTITLEORFOOTER   (procedure in GENSCRN.PRG)
  5170. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5171. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5172. *!               : ANYWINDOWCHARS     (procedure in GENSCRN.PRG)
  5173. *!               : ANYBORDER          (procedure in GENSCRN.PRG)
  5174. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  5175. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5176. *!               : ANYICON            (procedure in GENSCRN.PRG)
  5177. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  5178. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  5179. *!
  5180. *!*****************************************************************************
  5181. PROCEDURE genwindefi
  5182. *)
  5183. *) GENWINDEFI - Generate window definition
  5184. *)
  5185. *) Description:
  5186. *) Check to see if window name is unique, if not provide a unique name
  5187. *) with the use of SYS(2015) and display a warning message if
  5188. *) appropriate.  The window definition is generated only if the
  5189. *) user selected that option in the generator dialog.
  5190. *)
  5191. PARAMETER m.g_screen
  5192. PRIVATE m.name, m.pos, m.dupname, m.arrange_flag, m.center_flag, m.in_parms, m.j
  5193. m.arrange_flag = .F.
  5194. m.center_flag = .F.
  5195. m.dupname = .F.
  5196. m.name = IIF(!EMPTY(g_screens[m.g_screen,2]), g_screens[m.g_screen,2], LOWER(SYS(2015)))
  5197. m.pos = uniquewin(LOWER(m.name), m.g_nwindows, @g_wndows)
  5198. IF m.pos = 0
  5199.    m.dupname = .T.
  5200.    m.name = LOWER(SYS(2015))
  5201.    g_screens[m.g_screen,2] = m.name
  5202.    m.pos = uniquewin(m.name, m.g_nwindows, @g_wndows)
  5203. ENDIF
  5204.  
  5205. * Insert one row (two elements)
  5206. = AINS(g_wndows, m.pos)
  5207. g_wndows[m.pos,1] = m.name
  5208. g_wndows[m.pos,2] = .F.  && it will get a sequence number in AnyWindows
  5209. m.g_nwindows = m.g_nwindows + 1
  5210.  
  5211. m.g_windows = .T.
  5212. IF NOT m.g_defwin
  5213.    RETURN
  5214. ENDIF
  5215.  
  5216. IF NOT m.g_redefi
  5217.    \IF NOT WEXIST("<<m.name>>")
  5218.    * We can safely omit this extra code if the name was a randomly generated one
  5219.    IF  UPPER(LEFT(m.name,2)) <> UPPER(LEFT(SYS(2015),2))
  5220.       \\ ;
  5221.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'PJX'))>>" ;
  5222.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'SCX'))>>" ;
  5223.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'MNX'))>>" ;
  5224.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'PRG'))>>" ;
  5225.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'FRX'))>>" ;
  5226.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'QPR'))>>"
  5227.    ENDIF
  5228.    DO pushindent
  5229. ENDIF
  5230. \DEFINE WINDOW <<m.name>> ;
  5231.  
  5232. SELECT (m.g_projalias)
  5233. GOTO RECORD g_screens[m.g_screen,3]
  5234.  
  5235. DO getarrange WITH m.dbalias, m.arrange_flag, m.center_flag
  5236.  
  5237. DO anytitleorfooter
  5238. DO anyfont
  5239. DO anystyle
  5240. DO anywindowchars
  5241. DO anyborder
  5242.  
  5243. IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC')
  5244.    IF TAB
  5245.       \\ ;
  5246.       \    HALFHEIGHT
  5247.    ENDIF
  5248.    IF  !EMPTY(PICTURE)
  5249.       DO anywallpaper
  5250.    ELSE
  5251.       DO anyscheme
  5252.    ENDIF
  5253.    DO anyicon
  5254. ELSE
  5255.    DO anyscheme
  5256. ENDIF
  5257.  
  5258. * If the user defined additional window clauses, put them here
  5259. IF ATC("#WCLA",setupcode) > 0
  5260.    DO gendirective WITH ;
  5261.       MLINE(setupcode,ATCLINE('#WCLA',setupcode)),'#WCLA'
  5262. ENDIF
  5263.  
  5264. * Emit the MOVE WINDOW ... CENTER after all the window clauses have been emitted
  5265. IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC')
  5266.    IF (CENTER OR m.center_flag) AND !m.arrange_flag
  5267.       \MOVE WINDOW <<m.name>> CENTER
  5268.    ENDIF
  5269. ENDIF
  5270.  
  5271. IF !m.g_redefi
  5272.    DO popindent
  5273.    \ENDIF
  5274. ENDIF
  5275. \
  5276. RETURN
  5277.  
  5278. *!*****************************************************************************
  5279. *!
  5280. *!      Procedure: GETARRANGE
  5281. *!
  5282. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  5283. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  5284. *!
  5285. *!          Calls: WINDOWFROMTO       (procedure in GENSCRN.PRG)
  5286. *!
  5287. *!*****************************************************************************
  5288. PROCEDURE getarrange
  5289. PARAMETER m.dbalias, m.arrange_flag, m.center_flag
  5290. PRIVATE m.j, m.pname, m.entries, m.row, m.col
  5291. IF !EMPTY(arranged)
  5292.    m.entries = INT(LEN(arranged)/26)
  5293.    m.j = 1
  5294.    DO WHILE m.j <= m.entries
  5295.       m.pname = ALLTRIM(UPPER(SUBSTR(arranged,(m.j-1)*26+1,8)))
  5296.       m.pname = ALLTRIM(CHRTRAN(m.pname,CHR(0)," "))
  5297.       IF m.pname == m.g_genvers    && found the right one
  5298.          IF INLIST(UPPER(SUBSTR(arranged,(m.j-1)*26 + 9,1)),'Y','T')    && is it arranged?
  5299.             IF INLIST(UPPER(SUBSTR(arranged,(m.j-1)*26 +10,1)),'Y','T') && is it centered?
  5300.                m.center_flag = .T.
  5301.             ELSE
  5302.                m.arrange_flag = .T.
  5303.                m.row = VAL(SUBSTR(arranged,(m.j-1)*26 + 11,8))
  5304.                m.col = VAL(SUBSTR(arranged,(m.j-1)*26 + 19,8))
  5305.             ENDIF
  5306.          ENDIF
  5307.          EXIT
  5308.       ENDIF
  5309.       m.j = m.j + 1
  5310.    ENDDO
  5311. ENDIF
  5312. SELECT (m.dbalias)
  5313. IF m.arrange_flag
  5314.    DO windowfromto WITH m.row, m.col
  5315. ELSE
  5316.    DO windowfromto
  5317. ENDIF
  5318. RETURN
  5319.  
  5320. *!*****************************************************************************
  5321. *!
  5322. *!      Procedure: GENBOXES
  5323. *!
  5324. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5325. *!
  5326. *!          Calls: ANYPATTERN         (procedure in GENSCRN.PRG)
  5327. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5328. *!               : ANYPEN             (procedure in GENSCRN.PRG)
  5329. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5330. *!
  5331. *!*****************************************************************************
  5332. PROCEDURE genboxes
  5333. *)
  5334. *) GENBOXES - Generate code for boxes.
  5335. *)
  5336. *) Description:
  5337. *) Generate code to display all boxes as they appear on the painted
  5338. *) screen(s).  Note since there is no FILL clause on @...TO command
  5339. *) we use the command @...BOX whenever the fill option has been chosen.
  5340. *) If Fill option is not chosen, then we use the simpler form for
  5341. *) generating boxes, @...TO command which supplies us with clauses
  5342. *) DOUBLE and PANEL for the box borders.
  5343. *)
  5344. PRIVATE m.bottom, m.right, m.thisbox
  5345. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5346.    SET DECIMALS TO 3
  5347.    m.bottom = HEIGHT+vpos
  5348.    m.right = WIDTH+hpos
  5349. ELSE
  5350.    m.bottom = HEIGHT+vpos-1
  5351.    m.right = WIDTH+hpos-1
  5352. ENDIF
  5353. IF (m.g_genvers = 'WINDOWS' OR m.g_genvers = 'MAC')
  5354.    IF fillchar <> c_null AND fillchar <> " "
  5355.       \@ <<Vpos>>,<<Hpos>>,<<m.bottom>>,<<m.right>>
  5356.       DO CASE
  5357.       CASE objcode = c_sgbox
  5358.          m.thisbox = c_single
  5359.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5360.       CASE objcode = c_sgboxd
  5361.          m.thisbox = c_double
  5362.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5363.       CASE objcode = c_sgboxp
  5364.          m.thisbox = c_panel
  5365.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5366.       CASE objcode = c_sgboxc
  5367.          IF boxchar = '"'
  5368.             \\ BOX REPLICATE('<<Boxchar>>',8)
  5369.          ELSE
  5370.             \\ BOX REPLICATE("<<Boxchar>>",8)
  5371.          ENDIF
  5372.          IF fillchar = '"'
  5373.             \\+'<<Fillchar>>'
  5374.          ELSE
  5375.             \\+"<<Fillchar>>"
  5376.          ENDIF
  5377.       ENDCASE
  5378.       SET DECIMALS TO 0
  5379.       RETURN
  5380.    ELSE
  5381.       \@ <<Vpos>>,<<Hpos>> TO <<m.bottom>>,<<m.right>>
  5382.    ENDIF
  5383. ELSE
  5384.    IF fillchar <> c_null
  5385.       \@ <<Vpos>>,<<Hpos>>,<<m.bottom>>,<<m.right>>
  5386.       DO CASE
  5387.       CASE objcode = c_sgbox
  5388.          m.thisbox = c_single
  5389.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5390.       CASE objcode = c_sgboxd
  5391.          m.thisbox = c_double
  5392.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5393.       CASE objcode = c_sgboxp
  5394.          m.thisbox = c_panel
  5395.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5396.       CASE objcode = c_sgboxc
  5397.          IF boxchar = '"'
  5398.             \\ BOX REPLICATE('<<Boxchar>>',8)
  5399.          ELSE
  5400.             \\ BOX REPLICATE("<<Boxchar>>",8)
  5401.          ENDIF
  5402.          IF fillchar = '"'
  5403.             \\+'<<Fillchar>>'
  5404.          ELSE
  5405.             \\+"<<Fillchar>>"
  5406.          ENDIF
  5407.       ENDCASE
  5408.  
  5409.       IF (!EMPTY(colorpair) OR SCHEME <> 0)
  5410.          * Color the inside of the box if it is filled with something.
  5411.          \@ <<Vpos>>,<<Hpos>> FILL TO <<m.bottom>>,<<m.right>>
  5412.          DO anypattern
  5413.          DO anyscheme
  5414.       ENDIF
  5415.       SET DECIMALS TO 0
  5416.       RETURN
  5417.    ELSE
  5418.       \@ <<Vpos>>,<<Hpos>> TO <<m.bottom>>,<<m.right>>
  5419.    ENDIF
  5420. ENDIF
  5421.  
  5422. SET DECIMALS TO 0
  5423. DO CASE
  5424. CASE objcode = c_sgboxd
  5425.    \\ DOUBLE
  5426. CASE objcode = c_sgboxp
  5427.    \\ PANEL
  5428. CASE objcode = c_sgboxc
  5429.    IF boxchar = '"'
  5430.       \\ '<<Boxchar>>'
  5431.    ELSE
  5432.       \\ "<<Boxchar>>"
  5433.    ENDIF
  5434. ENDCASE
  5435. DO anypattern
  5436. DO anypen
  5437. DO anystyle
  5438. DO anyscheme
  5439. RETURN
  5440.  
  5441. *!*****************************************************************************
  5442. *!
  5443. *!      Procedure: GENLINES
  5444. *!
  5445. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5446. *!
  5447. *!          Calls: ANYPEN             (procedure in GENSCRN.PRG)
  5448. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5449. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5450. *!
  5451. *!*****************************************************************************
  5452. PROCEDURE genlines
  5453. *)
  5454. *) GENLINES - Generate code for lines.
  5455. *)
  5456. *) Description:
  5457. *) Generate code to display all lines as they appear on the painted
  5458. *) screen(s).
  5459. *)
  5460. PRIVATE m.x, m.y
  5461. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5462.    SET DECIMALS TO 3
  5463.    IF STYLE = 0
  5464.       m.x = HEIGHT+vpos
  5465.       m.y = hpos
  5466.    ELSE
  5467.       m.x = vpos
  5468.       m.y = WIDTH+hpos
  5469.    ENDIF
  5470. ELSE
  5471.    m.x = HEIGHT+vpos-1
  5472.    m.y = WIDTH+hpos-1
  5473. ENDIF
  5474.  
  5475. \@ <<Vpos>>,<<Hpos>> TO <<m.x>>,<<m.y>>
  5476. SET DECIMALS TO 0
  5477. IF BORDER = 1
  5478.    \\ DOUBLE
  5479. ENDIF
  5480. DO anypen
  5481. DO anystyle
  5482. DO anyscheme
  5483. RETURN
  5484.  
  5485.  
  5486. *!*****************************************************************************
  5487. *!
  5488. *!      Procedure: GENTEXT
  5489. *!
  5490. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5491. *!
  5492. *!          Calls: ANYPICTURE         (procedure in GENSCRN.PRG)
  5493. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5494. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5495. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5496. *!
  5497. *!*****************************************************************************
  5498. PROCEDURE gentext
  5499. *)
  5500. *) GENTEXT - Generate code for text.
  5501. *)
  5502. *) Description:
  5503. *) Generate code that will display the text exactly as it appears
  5504. *) in the painted screen(s).
  5505. *)
  5506. PRIVATE m.theexpr, m.occur, m.pos
  5507. m.theexpr = expr
  5508. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5509.    SET DECIMALS TO 3
  5510.    m.occur = 1
  5511.    m.pos = AT(CHR(13), m.theexpr, m.occur)
  5512.    * Sometimes the screen builder surrounds text with single quotes and other
  5513.    * times with double quotes.
  5514.    q1 = LEFT(LTRIM(m.theexpr),1)
  5515.  
  5516.    DO WHILE m.pos > 0
  5517.       DO CASE
  5518.       CASE q1 = "'"
  5519.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5520.             "' + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "'" ;
  5521.             + SUBSTR(m.theexpr, m.pos + 1)
  5522.       CASE q1 = '['
  5523.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5524.             "] + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "[" ;
  5525.             + SUBSTR(m.theexpr, m.pos + 1)
  5526.       OTHERWISE
  5527.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5528.             '" + CHR(13) + ;' + CHR(13)  + CHR(9) + CHR(9) + '"' ;
  5529.             + SUBSTR(m.theexpr, m.pos + 1)
  5530.       ENDCASE
  5531.       m.occur = m.occur + 1
  5532.       m.pos = AT(CHR(13), m.theexpr, m.occur)
  5533.    ENDDO
  5534.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> 
  5535.    IF height > 1
  5536.       \\ ;
  5537.       \    SIZE <<Height>>,<<Width>>, <<Spacing>>
  5538.    ENDIF
  5539. ELSE
  5540.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  5541.    \    SIZE <<Height>>,<<Width>>, <<Spacing>>
  5542. ENDIF
  5543.  
  5544. SET DECIMALS TO 0
  5545. DO anypicture
  5546. DO anyfont
  5547. DO anystyle
  5548. DO anyscheme
  5549. RETURN
  5550.  
  5551. *!*****************************************************************************
  5552. *!
  5553. *!      Procedure: GENFIELDS
  5554. *!
  5555. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5556. *!
  5557. *!          Calls: ANYFONT            (procedure in GENSCRN.PRG)
  5558. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5559. *!               : ANYPICTURE         (procedure in GENSCRN.PRG)
  5560. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5561. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5562. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  5563. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5564. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5565. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5566. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5567. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5568. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5569. *!
  5570. *!*****************************************************************************
  5571. PROCEDURE genfields
  5572. *)
  5573. *) GENFIELDS - Generate fields.
  5574. *)
  5575. *) Description:
  5576. *) Generate code to display SAY, GET, and EDIT statements exactly as they
  5577. *) appear in the painted screen(s).
  5578. *)
  5579. PRIVATE m.theexpr
  5580. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5581.    SET DECIMALS TO 3
  5582. ENDIF
  5583. DO CASE
  5584. CASE objcode = c_sgsay
  5585.    m.theexpr = expr
  5586.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  5587.    \    SIZE <<Height>>,<<Width>>
  5588.    SET DECIMALS TO 0
  5589.    DO anyfont
  5590.    DO anystyle
  5591.    DO anypicture
  5592.    DO anyscheme
  5593.    RETURN
  5594. CASE objcode = c_sgget
  5595.    \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5596.    \    SIZE <<Height>>,<<Width>>
  5597.    DO elemrange
  5598. CASE objcode = c_sgedit
  5599.    DO gentxtrgn
  5600.    RETURN
  5601. ENDCASE
  5602. SET DECIMALS TO 0
  5603.  
  5604. DO gendefault
  5605. DO anyfont
  5606. DO anystyle
  5607. DO anypicture
  5608. DO anywhen
  5609. DO anyvalid
  5610. DO anymessage
  5611. DO anyerror
  5612. DO anydisabled
  5613. DO anyscheme
  5614. RETURN
  5615.  
  5616. *!*****************************************************************************
  5617. *!
  5618. *!      Procedure: GENINVBUT
  5619. *!
  5620. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5621. *!
  5622. *!          Calls: ANYFONT            (procedure in GENSCRN.PRG)
  5623. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5624. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5625. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5626. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5627. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5628. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5629. *!
  5630. *!*****************************************************************************
  5631. PROCEDURE geninvbut
  5632. *)
  5633. *) GENINVBUT - Generate Invisible buttons.
  5634. *)
  5635. *) Description:
  5636. *) Generate code to display invisible buttons exactly as they appear
  5637. *) in the painted screen(s).
  5638. *)
  5639.  
  5640. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5641.    SET DECIMALS TO 3
  5642. ENDIF
  5643. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5644. \    PICTURE <<Picture>> ;
  5645. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5646. \    DEFAULT 0
  5647. SET DECIMALS TO 0
  5648.  
  5649. DO anyfont
  5650. DO anystyle
  5651. DO anywhen
  5652. DO anyvalid
  5653. DO anydisabled
  5654. DO anymessage
  5655. DO anyscheme
  5656. RETURN
  5657.  
  5658. *!*****************************************************************************
  5659. *!
  5660. *!      Procedure: GENTXTRGN
  5661. *!
  5662. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  5663. *!
  5664. *!          Calls: ANYPICTURE         (procedure in GENSCRN.PRG)
  5665. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5666. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5667. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5668. *!               : ANYTAB             (procedure in GENSCRN.PRG)
  5669. *!               : ANYSCROLL          (procedure in GENSCRN.PRG)
  5670. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5671. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5672. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5673. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5674. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5675. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5676. *!
  5677. *!*****************************************************************************
  5678. PROCEDURE gentxtrgn
  5679. *)
  5680. *) GENTXTRGN - Generate some statements for text edit region.
  5681. *)
  5682. *) Description:
  5683. *) Generate code to display text edit regions exactly as they
  5684. *) appear on the painted screen(s).
  5685. *)
  5686. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5687.    SET DECIMALS TO 3
  5688. ENDIF
  5689. \@ <<Vpos>>,<<Hpos>> EDIT <<Name>> ;
  5690. \    SIZE <<IIF(Height < 1, 1, Height)>>,<<Width>>,<<Initialnum>>
  5691. SET DECIMALS TO 0
  5692.  
  5693. IF NOT EMPTY(PICTURE)
  5694.    DO anypicture
  5695. ENDIF
  5696. DO gendefault
  5697. DO anyfont
  5698. DO anystyle
  5699. DO anytab
  5700. DO anyscroll
  5701. DO anywhen
  5702. DO anyvalid
  5703. DO anymessage
  5704. DO anyerror
  5705. DO anydisabled
  5706. DO anyscheme
  5707. RETURN
  5708.  
  5709. *!*****************************************************************************
  5710. *!
  5711. *!      Procedure: GENPUSH
  5712. *!
  5713. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5714. *!
  5715. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5716. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5717. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5718. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5719. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5720. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5721. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5722. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5723. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5724. *!
  5725. *!*****************************************************************************
  5726. PROCEDURE genpush
  5727. *)
  5728. *) GENPUSH - Generate Push buttons.
  5729. *)
  5730. *) Description:
  5731. *) Generate code to display push buttons exactly as they appear
  5732. *) in the painted screen(s).
  5733. *)
  5734. PRIVATE m.thepicture
  5735.  
  5736. m.thepicture = PICTURE
  5737. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5738.    SET DECIMALS TO 3
  5739. ENDIF
  5740. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5741. DO anybitmapctrl WITH m.thepicture
  5742. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5743. SET DECIMALS TO 0
  5744. \    DEFAULT <<Initialnum>>
  5745. DO anyfont
  5746. DO anystyle
  5747. DO anywhen
  5748. DO anyvalid
  5749. DO anydisabled
  5750. DO anymessage
  5751. DO anyerror
  5752. DO anyscheme
  5753. RETURN
  5754.  
  5755. *!*****************************************************************************
  5756. *!
  5757. *!      Procedure: GENRADBUT
  5758. *!
  5759. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5760. *!
  5761. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5762. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5763. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5764. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5765. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5766. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5767. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5768. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5769. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5770. *!
  5771. *!*****************************************************************************
  5772. PROCEDURE genradbut
  5773. *)
  5774. *) GENRADBUT - Generate Radio Buttons.
  5775. *)
  5776. *) Description:
  5777. *) Generate code to display radio buttons exactly as they appear
  5778. *) in the painted screen(s).
  5779. *)
  5780. PRIVATE m.thepicture
  5781.  
  5782. m.thepicture = PICTURE
  5783. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5784.    SET DECIMALS TO 3
  5785. ENDIF
  5786. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5787. DO anybitmapctrl WITH m.thepicture
  5788. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5789. SET DECIMALS TO 0
  5790. \    DEFAULT <<Initialnum>>
  5791. DO anyfont
  5792. DO anystyle
  5793. DO anywhen
  5794. DO anyvalid
  5795. DO anydisabled
  5796. DO anymessage
  5797. DO anyerror
  5798. DO anyscheme
  5799. RETURN
  5800.  
  5801. *!*****************************************************************************
  5802. *!
  5803. *!      Procedure: GENCHKBOX
  5804. *!
  5805. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5806. *!
  5807. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5808. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5809. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5810. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5811. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5812. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5813. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5814. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5815. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5816. *!
  5817. *!*****************************************************************************
  5818. PROCEDURE genchkbox
  5819. *)
  5820. *) GENCHKBOX - Generate Check Boxes
  5821. *)
  5822. *) Description:
  5823. *) Generate code to display check boxes exactly as they appear
  5824. *) in the painted screen(s).
  5825. *)
  5826. PRIVATE m.thepicture
  5827.  
  5828. m.thepicture = PICTURE
  5829. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5830.    SET DECIMALS TO 3
  5831. ENDIF
  5832.  
  5833. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5834. DO anybitmapctrl WITH m.thepicture
  5835. \    SIZE <<Height>>,<<Width>> ;
  5836. SET DECIMALS TO 0
  5837. \    DEFAULT <<Initialnum>>
  5838. DO anyfont
  5839. DO anystyle
  5840. DO anywhen
  5841. DO anyvalid
  5842. DO anydisabled
  5843. DO anymessage
  5844. DO anyerror
  5845. DO anyscheme
  5846. RETURN
  5847.  
  5848. *!*****************************************************************************
  5849. *!
  5850. *!      Procedure: GENLIST
  5851. *!
  5852. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5853. *!
  5854. *!          Calls: CHOPPICTURE        (procedure in GENSCRN.PRG)
  5855. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5856. *!               : FROMPOPUP          (procedure in GENSCRN.PRG)
  5857. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5858. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5859. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5860. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5861. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5862. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5863. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5864. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5865. *!
  5866. *!*****************************************************************************
  5867. PROCEDURE genlist
  5868. *)
  5869. *) GENLIST - Generate Scrollable Lists.
  5870. *)
  5871. *) Description:
  5872. *) Generate code to display scrollable lists exactly as they appear
  5873. *) in the painted screen(s).
  5874. *)
  5875. PRIVATE m.pos, m.start
  5876. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5877.    SET DECIMALS TO 3
  5878. ENDIF
  5879. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5880. SET DECIMALS TO 0
  5881. IF NOT EMPTY(PICTURE)
  5882.    \     PICTURE
  5883.    DO choppicture WITH PICTURE
  5884.    \\ ;
  5885. ENDIF
  5886. IF STYLE = 0
  5887.    \    FROM <<Expr>>
  5888.    DO elemrange
  5889.    \\ ;
  5890.    IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5891.       SET DECIMALS TO 3
  5892.    ENDIF
  5893.    \    SIZE <<Height>>,<<Width>> ;
  5894.    SET DECIMALS TO 0
  5895.    \    DEFAULT 1
  5896. ELSE
  5897.    DO frompopup
  5898. ENDIF
  5899.  
  5900. DO anyfont
  5901. DO anystyle
  5902. DO anywhen
  5903. DO anyvalid
  5904. DO anydisabled
  5905. DO anymessage
  5906. DO anyerror
  5907. DO anyscheme
  5908. RETURN
  5909.  
  5910. *!*****************************************************************************
  5911. *!
  5912. *!      Procedure: GENPICTURE
  5913. *!
  5914. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  5915. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  5916. *!
  5917. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  5918. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5919. *!
  5920. *!*****************************************************************************
  5921. PROCEDURE genpicture
  5922. *)
  5923. *) GENPICTURE - Generate code for pictures.
  5924. *)
  5925. *) Description:
  5926. *) Generate code to display pictures (bitmaps or bitmaps in general fields).
  5927. *)
  5928. PRIVATE m.relpath
  5929. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5930.    SET DECIMALS TO 3
  5931.    \@ <<Vpos>>,<<Hpos>> SAY
  5932.    IF STYLE = 0
  5933.       m.relpath = LOWER(findrelpath(SUBSTR(PICTURE,2,LEN(PICTURE)-2)))
  5934.         IF EMPTY(justext(m.relpath))
  5935.            m.relpath = m.relpath + "."
  5936.         ENDIF
  5937.       \\ (LOCFILE("<<m.relpath>>",<<bitmapstr(c_all)>>, "Where is <<basename(m.relpath)>>?"
  5938.         IF _MAC
  5939.             * Use the "type" parameter to get all PICT files on the Mac,
  5940.             * regardless of extension.
  5941.             \\, "PICT"
  5942.         ENDIF
  5943.         \\ )) BITMAP ;
  5944.    ELSE
  5945.       \\ <<Name>> ;
  5946.    ENDIF
  5947.    \    SIZE <<Height>>,<<Width>>
  5948.  
  5949.    IF CENTER
  5950.       \\ ;
  5951.       \    CENTER
  5952.    ENDIF
  5953.  
  5954.    DO CASE
  5955.    CASE BORDER = 1
  5956.       \\ ;
  5957.       \    ISOMETRIC
  5958.    CASE BORDER = 2
  5959.       \\ ;
  5960.       \    STRETCH
  5961.    ENDCASE
  5962.  
  5963.    SET DECIMALS TO 0
  5964.    DO anystyle
  5965. ENDIF
  5966. RETURN
  5967.  
  5968. *!*****************************************************************************
  5969. *!
  5970. *!      Procedure: GENSPINNER
  5971. *!
  5972. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5973. *!
  5974. *!          Calls: CHOPPICTURE        (procedure in GENSCRN.PRG)
  5975. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5976. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5977. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5978. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5979. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5980. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5981. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5982. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5983. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5984. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5985. *!
  5986. *!*****************************************************************************
  5987. PROCEDURE genspinner
  5988. *)
  5989. *) GENSPINNER - Generate Spinners
  5990. *)
  5991. *) Description:
  5992. *) Generate code to display spinners exactly as they appear
  5993. *) in the painted screen(s).
  5994. *)
  5995. PRIVATE m.thepicture
  5996.  
  5997. m.thepicture = PICTURE
  5998. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5999.    SET DECIMALS TO 3
  6000. ENDIF
  6001.  
  6002. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  6003. \    SPINNER
  6004.  
  6005. ** Generate the increment value
  6006. IF !EMPTY(initialval)
  6007.    IF INT(VAL(initialval)) <> VAL(initialval)
  6008.       SET DECIMALS TO LEN(initialval) - AT('.',initialval)
  6009.    ENDIF
  6010.    \\ <<VAL(Initialval)>>
  6011.    SET DECIMALS TO 3
  6012. ELSE
  6013.    \\ 1.000
  6014. ENDIF
  6015.  
  6016. ** Generate the minimum value.
  6017. IF !EMPTY(TAG)
  6018.    \\, <<Tag>>
  6019. ELSE
  6020.    IF !EMPTY(tag2)
  6021.       \\,
  6022.    ENDIF
  6023. ENDIF
  6024.  
  6025. ** Generate the maximum value.
  6026. IF !EMPTY(tag2)
  6027.    \\, <<Tag2>>
  6028. ENDIF
  6029. \\ ;
  6030.  
  6031. IF !EMPTY(m.thepicture)
  6032.    \    PICTURE
  6033.    DO choppicture WITH m.thepicture
  6034.    \\ ;
  6035. ENDIF
  6036. \    SIZE <<Height>>, <<Width>>
  6037.  
  6038. ** Put out a default which corresponds to the range of valid values.
  6039. DO CASE
  6040. CASE !EMPTY(TAG)
  6041.    \\ ;
  6042.    \    DEFAULT <<VAL(Tag)>>
  6043. CASE !EMPTY(tag2)
  6044.    \\ ;
  6045.    \    DEFAULT <<VAL(Tag2)>>
  6046. CASE EMPTY(TRIM(initialval))
  6047.    \\ ;
  6048.    \    DEFAULT 1
  6049. OTHERWISE
  6050.    DO gendefault
  6051. ENDCASE
  6052.  
  6053. DO elemrange
  6054. DO anywhen
  6055. DO anyvalid
  6056. DO anydisabled
  6057. DO anymessage
  6058. DO anyerror
  6059. SET DECIMALS TO 0
  6060. DO anyfont
  6061. DO anystyle
  6062. DO anyscheme
  6063. RETURN
  6064.  
  6065. *!*****************************************************************************
  6066. *!
  6067. *!      Procedure: FROMPOPUP
  6068. *!
  6069. *!      Called by: GENLIST            (procedure in GENSCRN.PRG)
  6070. *!
  6071. *!*****************************************************************************
  6072. PROCEDURE frompopup
  6073. *)
  6074. *) FROMPOPUP - Generate code for scrollable list defined from a popup.
  6075. *)
  6076. *) Description:
  6077. *) Generate POPUP <popup name> code as part of a scrollable list
  6078. *) definition.  Popup name may either be name explicitly provided by
  6079. *) the user or a unique name generated by SYS(2015) function.
  6080. *)
  6081. PRIVATE m.start, m.pos
  6082. \    POPUP
  6083. IF STYLE < 2
  6084.    IF NOT EMPTY(expr)
  6085.       \\ <<Expr>> ;
  6086.    ENDIF
  6087. ELSE
  6088.    m.start = 1
  6089.    m.pos   = 0
  6090.    DO WHILE .T.
  6091.       m.pos = ASCAN(g_popups, m.dbalias, m.start)
  6092.       IF g_popups[m.pos+1] = RECNO()
  6093.          EXIT
  6094.       ENDIF
  6095.       m.start = m.pos + 3
  6096.    ENDDO
  6097.    \\ <<g_popups[m.pos+2]>> ;
  6098. ENDIF
  6099.  
  6100. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6101.    SET DECIMALS TO 3
  6102. ENDIF
  6103. \    SIZE <<Height>>,<<Width>> ;
  6104. \    DEFAULT " "
  6105. SET DECIMALS TO 0
  6106. RETURN
  6107.  
  6108. *!*****************************************************************************
  6109. *!
  6110. *!      Procedure: GENPOPUP
  6111. *!
  6112. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  6113. *!
  6114. *!          Calls: ELEMRANGE          (procedure in GENSCRN.PRG)
  6115. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  6116. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  6117. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  6118. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  6119. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  6120. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  6121. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  6122. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  6123. *!
  6124. *!*****************************************************************************
  6125. PROCEDURE genpopup
  6126. *)
  6127. *) GENPOPUP - Generate Popups.
  6128. *)
  6129. *) Description:
  6130. *) Generate code to display popups exactly as they appear in the
  6131. *) painted screen(s).
  6132. *)
  6133. PRIVATE m.thepicture, m.theinitval
  6134.  
  6135. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6136.    SET DECIMALS TO 3
  6137. ENDIF
  6138. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  6139. IF objcode = c_sgget
  6140.    m.thepicture = PICTURE
  6141.    m.theinitval = initialval
  6142.    \    PICTURE <<m.thepicture>> ;
  6143.    \    SIZE <<Height>>,<<Width>> ;
  6144.    \    DEFAULT <<IIF(EMPTY(m.theinitval), '" "', m.theinitval)>>
  6145. ELSE
  6146.     * e.g., popup from array
  6147.    \    PICTURE "<<ctrlclause(picture)>>" ;
  6148.    \    FROM <<Expr>> ;
  6149.    \    SIZE <<Height>>,<<Width>>
  6150.    DO elemrange
  6151.    \\ ;
  6152.    \    DEFAULT 1
  6153. ENDIF
  6154. SET DECIMALS TO 0
  6155.  
  6156. DO anyfont
  6157. DO anystyle
  6158. DO anywhen
  6159. DO anyvalid
  6160. DO anydisabled
  6161. DO anymessage
  6162. DO anyerror
  6163. DO anyscheme
  6164. RETURN
  6165.  
  6166. *!*****************************************************************************
  6167. *!
  6168. *!      Procedure: ELEMRANGE
  6169. *!
  6170. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6171. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6172. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6173. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6174. *!
  6175. *!          Calls: ADDTOCTRL          (procedure in GENSCRN.PRG)
  6176. *!
  6177. *!*****************************************************************************
  6178. PROCEDURE elemrange
  6179. *)
  6180. *) ELEMRANGE - Element range clause for popup and scrollable list
  6181. *)                defined form an array.
  6182. *)
  6183. PRIVATE m.firstelem, m.genericname
  6184. m.firstelem = .F.
  6185. IF NOT EMPTY(rangelo)
  6186.    m.firstelem = .T.
  6187.    \\ ;
  6188.    \    RANGE
  6189.    IF lotype = 0
  6190.       \\ <<ALLTRIM(CHRTRAN(Rangelo,CHR(13)+CHR(10),""))>>
  6191.    ELSE
  6192.       m.genericname = LOWER(SYS(2015))
  6193.       \\ <<m.genericname>>()
  6194.       DO CASE
  6195.       CASE objtype = c_otfield
  6196.          DO addtoctrl WITH m.genericname, "GET Low RANGE", rangelo, name
  6197.       CASE objtype = c_otspinner
  6198.          DO addtoctrl WITH m.genericname, "SPINNER Low RANGE", rangelo, name
  6199.       OTHERWISE
  6200.          DO addtoctrl WITH m.genericname, "Popup From", rangelo, name
  6201.       ENDCASE
  6202.    ENDIF
  6203. ENDIF
  6204. IF NOT EMPTY(rangehi)
  6205.    IF NOT m.firstelem
  6206.       \\ ;
  6207.       \    RANGE ,
  6208.    ELSE
  6209.       \\,
  6210.    ENDIF
  6211.    IF hitype = 0
  6212.       \\ <<CHRTRAN(ALLTRIM(Rangehi),CHR(13)+CHR(10),"")>>
  6213.    ELSE
  6214.       m.genericname = LOWER(SYS(2015))
  6215.       \\ <<m.genericname>>()
  6216.       DO CASE
  6217.       CASE objtype = c_otfield
  6218.          DO addtoctrl WITH m.genericname, "GET High RANGE", rangehi, name
  6219.       CASE objtype = c_otspinner
  6220.          DO addtoctrl WITH m.genericname, "SPINNER High RANGE", rangehi, name
  6221.       OTHERWISE
  6222.          DO addtoctrl WITH m.genericname, "Popup From", rangehi, name
  6223.       ENDCASE
  6224.    ENDIF
  6225. ENDIF
  6226. RETURN
  6227.  
  6228. *!*****************************************************************************
  6229. *!
  6230. *!      Procedure: GENACTWINDOW
  6231. *!
  6232. *!      Called by: ANYWINDOWS         (procedure in GENSCRN.PRG)
  6233. *!
  6234. *!*****************************************************************************
  6235. PROCEDURE genactwindow
  6236. *)
  6237. *) GENACTWINDOW - Generate Activate Window Command.
  6238. *)
  6239. *) Description:
  6240. *) Generate the ACTIVATE WINDOW... command.
  6241. *)
  6242. PARAMETER m.cnt
  6243. IF !m.g_noreadplain
  6244.    IF m.g_lastwindow == g_screens[m.cnt,2]
  6245.       \@ 0,0 CLEAR
  6246.    ENDIF
  6247.    IF m.g_multreads
  6248.       \ACTIVATE WINDOW <<g_screens[m.cnt,2]>>
  6249.       RETURN
  6250.    ENDIF
  6251.    
  6252.    \IF WVISIBLE("<<g_screens[m.cnt,2]>>")
  6253.    \    ACTIVATE WINDOW <<g_screens[m.cnt,2]>> SAME
  6254.    \ELSE
  6255.    \    ACTIVATE WINDOW <<g_screens[m.cnt,2]>> NOSHOW
  6256.    \ENDIF
  6257. ENDIF
  6258. RETURN
  6259.  
  6260. *!*****************************************************************************
  6261. *!
  6262. *!      Procedure: GENDEFAULT
  6263. *!
  6264. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6265. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6266. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6267. *!
  6268. *!*****************************************************************************
  6269. PROCEDURE gendefault
  6270. *)
  6271. *) GENDEFAULT - Generate Default Clause.
  6272. *)
  6273. PRIVATE m.theinitval
  6274. IF EMPTY(TRIM(initialval)) AND EMPTY(fillchar)
  6275.    RETURN
  6276. ENDIF
  6277. \\ ;
  6278. \    DEFAULT
  6279. IF EMPTY(TRIM(initialval))
  6280.    DO CASE
  6281.    CASE fillchar = "D"
  6282.       \\ {  /  /  }
  6283.    CASE fillchar = "C" OR fillchar = "M" OR fillchar = "G"
  6284.       \\ " "
  6285.    CASE fillchar = "L"
  6286.       \\ .F.
  6287.    CASE fillchar = "N"
  6288.       \\ 0
  6289.    CASE fillchar = "F"
  6290.       \\ 0.0
  6291.    ENDCASE
  6292. ELSE
  6293.    m.theinitval = initialval
  6294.    \\ <<ALLTRIM(m.theinitval)>>
  6295. ENDIF
  6296. RETURN
  6297.  
  6298. **
  6299. **  Procedures Generating Various Clauses for Screen Objects
  6300. **
  6301.  
  6302. *!*****************************************************************************
  6303. *!
  6304. *!      Procedure: ANYBITMAPCTRL
  6305. *!
  6306. *!      Called by: GENPUSH            (procedure in GENSCRN.PRG)
  6307. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6308. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6309. *!
  6310. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6311. *!               : CHOPPICTURE        (procedure in GENSCRN.PRG)
  6312. *!
  6313. *!*****************************************************************************
  6314. PROCEDURE anybitmapctrl
  6315. *)
  6316. *) ANYBITMAPCTRL - Parse the picture clause for a bitmap control (Push button, radio button, checkbox) and return it
  6317. *)        with LOCAFILE and a relative path in place of each absolute path.
  6318. *)
  6319. PARAMETER m.picture
  6320. PRIVATE m.name, m.relpath, m.count
  6321.  
  6322. IF AT("B", SUBSTR(m.picture,1, AT(" ",m.picture))) <> 0
  6323.    \    PICTURE <<LEFT(m.picture, AT(" ",m.picture))>>"
  6324.  
  6325.    m.picture = SUBSTR(m.picture, AT(" ", m.picture)+1)
  6326.    m.picture = LEFT(m.picture, LEN(m.picture)-1)
  6327.    m.count = 0
  6328.  
  6329.    DO WHILE LEN(m.picture) <> 0
  6330.       m.count = m.count + 1
  6331.       IF AT(";", m.picture) <> 0
  6332.          m.name = LEFT(m.picture, AT(";", m.picture)-1)
  6333.          m.picture = SUBSTR(m.picture, AT(";",m.picture)+1)
  6334.       ELSE
  6335.          m.name = m.picture
  6336.          m.picture = ""
  6337.       ENDIF
  6338.  
  6339.       m.relpath = LOWER(findrelpath(m.name))
  6340.  
  6341.       IF m.count = 1
  6342.          \\ + ;
  6343.       ELSE
  6344.          \\ + ";" + ;
  6345.       ENDIF
  6346.         IF EMPTY(justext(m.relpath))
  6347.            m.relpath = m.relpath + "."
  6348.         ENDIF
  6349.       \        (LOCFILE("<<m.relpath>>",<<bitmapstr(c_all)>>,"Where is <<basename(m.relpath)>>?"
  6350.         IF _MAC
  6351.             \\,"PICT"
  6352.         ENDIF
  6353.         \\))
  6354.    ENDDO
  6355.  
  6356.    \\ ;
  6357. ELSE
  6358.    \    PICTURE
  6359.    DO choppicture WITH m.picture
  6360.    \\ ;
  6361. ENDIF
  6362. RETURN
  6363.  
  6364. *!*****************************************************************************
  6365. *!
  6366. *!      Procedure: CHOPPICTURE
  6367. *!
  6368. *!      Called by: GENLIST            (procedure in GENSCRN.PRG)
  6369. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6370. *!               : ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  6371. *!
  6372. *!*****************************************************************************
  6373. PROCEDURE choppicture
  6374. *)
  6375. *) CHOPPICTURE - Breaks a Picture clause into multiple 250 character segments to avoid
  6376. *)        the maximum string length limit.
  6377. *)
  6378. PARAMETER m.pict
  6379. PRIVATE m.quotechar, m.first
  6380. m.quotechar = LEFT(m.pict,1)
  6381. m.first = .T.
  6382.  
  6383. DO WHILE LEN(m.pict) > 250
  6384.    IF m.first
  6385.       \\ <<LEFT(m.pict,250) + m.quotechar>> + ;
  6386.       m.first = .F.
  6387.    ELSE
  6388.       \        <<LEFT(m.pict,250) + m.quotechar>> + ;
  6389.    ENDIF
  6390.    m.pict = m.quotechar + SUBSTR(m.pict,251)
  6391. ENDDO
  6392.  
  6393. IF m.first
  6394.    \\ <<m.pict>>
  6395. ELSE
  6396.    \    <<m.pict>>
  6397. ENDIF
  6398. RETURN
  6399.  
  6400. *!*****************************************************************************
  6401. *!
  6402. *!      Procedure: ANYDISABLED
  6403. *!
  6404. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6405. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6406. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6407. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6408. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6409. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6410. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6411. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6412. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6413. *!
  6414. *!*****************************************************************************
  6415. PROCEDURE anydisabled
  6416. *)
  6417. *) ANYDISABLED - Place ENABLE/DISABLE clause.
  6418. *)
  6419. IF disabled
  6420.    \\ ;
  6421.    \    DISABLE
  6422. ENDIF
  6423. RETURN
  6424.  
  6425. *!*****************************************************************************
  6426. *!
  6427. *!      Procedure: ANYPICTURE
  6428. *!
  6429. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6430. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6431. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6432. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6433. *!
  6434. *!*****************************************************************************
  6435. PROCEDURE anypicture
  6436. *)
  6437. *) ANYPICTURE
  6438. *)
  6439. PRIVATE m.string, m.expr_pos, m.newstring
  6440. IF NOT EMPTY(PICTURE) AND PICTURE <> '" "'
  6441.    \\ ;
  6442.    m.string = SUBSTR(PICTURE,2)   && drop opening quotation mark
  6443.    DO CASE
  6444.    CASE SUBSTR(m.string,1,1) = m.g_itse
  6445.       \    PICTURE <<SUBSTR(m.string,2,RAT(LEFT(picture,1),m.string)-2)>>
  6446.    CASE hasexpr(m.string) > 0 && an #ITSEXPRESSION character somewhere in the middle
  6447.        m.expr_pos = hasexpr(picture)
  6448.        * Emit the first part of the PICTURE
  6449.        \    PICTURE <<LEFT(picture,expr_pos-1)>>
  6450.        * Emit a closing quotation mark, which will be the same as the opening one
  6451.        \\<<LEFT(picture,1)>>
  6452.        * Now emit the expression portion of the picture clause, not including a closing quote
  6453.        \\ + <<SUBSTR(picture,expr_pos+1,LEN(picture)-expr_pos-1))>>
  6454.    OTHERWISE
  6455.       \    PICTURE <<Picture>>
  6456.    ENDCASE
  6457. ENDIF
  6458.  
  6459.  
  6460. FUNCTION hasexpr
  6461. PARAMETER m.thepicture
  6462. RETURN ATC(m.g_itse,m.thepicture)
  6463.  
  6464. *!*****************************************************************************
  6465. *!
  6466. *!      Procedure: ANYSCROLL
  6467. *!
  6468. *!      Called by: GENTXTRGN          (procedure in GENSCRN.PRG)
  6469. *!
  6470. *!*****************************************************************************
  6471. PROCEDURE anyscroll
  6472. *)
  6473. *) ANYSCROLL - Place Scroll clause if applicable.
  6474. *)
  6475. IF scrollbar
  6476.    \\ ;
  6477.    \    SCROLL
  6478. ENDIF
  6479. RETURN
  6480.  
  6481. *!*****************************************************************************
  6482. *!
  6483. *!      Procedure: ANYTAB
  6484. *!
  6485. *!      Called by: GENTXTRGN          (procedure in GENSCRN.PRG)
  6486. *!
  6487. *!*****************************************************************************
  6488. PROCEDURE anytab
  6489. *)
  6490. *) ANYTAB - Place Tab clause on an @...EDIT command.
  6491. *)
  6492. IF TAB
  6493.    \\ ;
  6494.    \    TAB
  6495. ENDIF
  6496. RETURN
  6497.  
  6498. *!*****************************************************************************
  6499. *!
  6500. *!      Procedure: ANYFONT
  6501. *!
  6502. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6503. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6504. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6505. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6506. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6507. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6508. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6509. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6510. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6511. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6512. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6513. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6514. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6515. *!
  6516. *!*****************************************************************************
  6517. PROCEDURE anyfont
  6518. *)
  6519. *) ANYFONT - Place font clause on an object if in a graphical
  6520. *)        environment
  6521. *)
  6522. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6523.    \\ ;
  6524.    \    FONT "<<Fontface>>", <<Fontsize>>
  6525. ENDIF
  6526. RETURN
  6527.  
  6528. *!*****************************************************************************
  6529. *!
  6530. *!      Procedure: ANYSTYLE
  6531. *!
  6532. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6533. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6534. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6535. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  6536. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6537. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6538. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6539. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6540. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6541. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6542. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6543. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6544. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6545. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  6546. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6547. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6548. *!
  6549. *!*****************************************************************************
  6550. PROCEDURE anystyle
  6551. *)
  6552. *) ANYSTYLE - Place a Style clause in an object.
  6553. *)
  6554. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6555.    IF NOT EMPTY(fontstyle) OR mode != 0 OR ;
  6556.          (NOT EMPTY(STYLE) AND objtype != c_otscreen AND ;
  6557.          objtype != c_ottext )
  6558.       \\ ;
  6559.       \    STYLE "
  6560.         \\<<num2style(fontstyle)>>
  6561.  
  6562.         * Is it transparent?
  6563.       IF mode = 1
  6564.          \\T
  6565.       ENDIF
  6566.  
  6567.       IF NOT EMPTY(STYLE) AND objtype != c_otscreen AND ;
  6568.             objtype != c_otlist AND objtype != c_ottext AND ;
  6569.                         objtype != c_otpicture
  6570.          \\<<Style>>
  6571.       ENDIF
  6572.       \\"
  6573.    ENDIF
  6574. ENDIF
  6575. RETURN
  6576.  
  6577. *!*****************************************************************************
  6578. *!
  6579. *!      Procedure: ANYPATTERN
  6580. *!
  6581. *!      Called by: GENBOXES           (procedure in GENSCRN.PRG)
  6582. *!
  6583. *!*****************************************************************************
  6584. PROCEDURE anypattern
  6585. *)
  6586. *) ANYPATTERN - Place a PATTERN clause for boxes.
  6587. *)
  6588. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6589.    IF fillpat != 0
  6590.       \\ ;
  6591.       \    PATTERN <<Fillpat>>
  6592.    ENDIF
  6593. ENDIF
  6594. RETURN
  6595.  
  6596. *!*****************************************************************************
  6597. *!
  6598. *!      Procedure: ANYSCHEME
  6599. *!
  6600. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6601. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6602. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6603. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  6604. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6605. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6606. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6607. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6608. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6609. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6610. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6611. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6612. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6613. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6614. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6615. *!
  6616. *!*****************************************************************************
  6617. PROCEDURE anyscheme
  6618. *)
  6619. *) ANYSCHEME - Place Color Scheme clause if applicable.
  6620. *)
  6621.  
  6622. IF NOT EMPTY(colorpair)
  6623.    \\ ;
  6624.    \    COLOR <<Colorpair>>
  6625.    RETURN
  6626. ENDIF
  6627. IF SCHEME <> 0
  6628.    \\ ;
  6629.    \    COLOR SCHEME <<Scheme>>
  6630.    IF objtype = c_otpopup AND scheme2<>0
  6631.       \\, <<Scheme2>>
  6632.    ENDIF
  6633. ELSE
  6634.    IF m.g_defasch2 <> 0
  6635.       DO CASE
  6636.       CASE objtype = c_ottext AND HEIGHT > 1
  6637.          \\ ;
  6638.          \    COLOR SCHEME <<m.g_defasch2>>
  6639.       CASE objtype = c_otlist
  6640.          \\ ;
  6641.          \    COLOR SCHEME <<m.g_defasch2>>
  6642.       CASE objtype = c_otpopup
  6643.          \\ ;
  6644.          \    COLOR SCHEME <<m.g_defasch1>>, <<m.g_defasch2>>
  6645.       ENDCASE
  6646.    ELSE
  6647.       IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC' ) ;
  6648.             AND ((ObjTYpe = c_otscreen AND fillred >=0) ;
  6649.              OR (ObjType <> c_otscreen AND (penred >= 0 OR fillred >= 0)) )
  6650.          m.ctrlflag = .F.   && .T. if this is a control-type object (e.g., radio button)
  6651.          \\ ;
  6652.          \    COLOR
  6653.          DO CASE
  6654.          CASE INLIST(objtype,c_otfield,c_otspinner)
  6655.             ** Field or spinner - color pair 2
  6656.             DO CASE
  6657.             CASE objcode = c_sgget OR objcode = c_sgedit
  6658.                \\ ,RGB(
  6659.             CASE objcode = c_sgsay
  6660.                \\ RGB(
  6661.             CASE objcode = c_sgfrom
  6662.                \\ ,,,,,,,,RGB(
  6663.             ENDCASE
  6664.  
  6665.          CASE objtype = c_otlist
  6666.             m.ctrlflag = .T.    && remember that this is a control object
  6667.             \\ RGB(
  6668.  
  6669.  
  6670.          CASE objtype = c_ottext OR objtype = c_otscreen OR ;
  6671.                objtype = c_otbox OR objtype = c_otline
  6672.             ** Text, Box, Line, or Screen - color pair 1
  6673.             \\ RGB(
  6674.  
  6675.          OTHERWISE
  6676.             m.ctrlflag = .T.    && remember that this is a control object
  6677.             \\ ,,,,,,,,RGB(
  6678.          ENDCASE
  6679.  
  6680.          IF penred >= 0
  6681.             \\<<Penred>>,<<Pengreen>>,<<Penblue>>,
  6682.          ELSE
  6683.             \\,,,
  6684.          ENDIF
  6685.          IF fillred >= 0
  6686.             \\<<Fillred>>,<<Fillgreen>>,<<Fillblue>>)
  6687.          ELSE
  6688.             \\,,,)
  6689.          ENDIF
  6690.  
  6691.          IF m.ctrlflag AND INLIST(objtype, c_otradbut, c_otchkbox, c_otpopup,c_otlist)
  6692.             * Add one more RGB clause to control the disabled colors for control
  6693.             * objects such as radio buttons, check boxes, popups, etc.
  6694.             \\,RGB(
  6695.             IF penred >= 0
  6696.                \\<<Penred>>,<<Pengreen>>,<<Penblue>>,
  6697.             ELSE
  6698.                \\,,,
  6699.             ENDIF
  6700.             IF fillred >= 0
  6701.                \\<<Fillred>>,<<Fillgreen>>,<<Fillblue>>)
  6702.             ELSE
  6703.                \\,,,)
  6704.             ENDIF
  6705.          ENDIF
  6706.       ENDIF
  6707.    ENDIF
  6708. ENDIF
  6709. RETURN
  6710.  
  6711. *!*****************************************************************************
  6712. *!
  6713. *!      Procedure: ANYPEN
  6714. *!
  6715. *!      Called by: GENBOXES           (procedure in GENSCRN.PRG)
  6716. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6717. *!
  6718. *!*****************************************************************************
  6719. PROCEDURE anypen
  6720. *)
  6721. *) ANYPEN - Place Color Scheme clause if applicable.
  6722. *)
  6723. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6724.    \\ ;
  6725.    \    PEN <<Pensize>>, <<Penpat>>
  6726. ENDIF
  6727. RETURN
  6728.  
  6729. *!*****************************************************************************
  6730. *!
  6731. *!      Procedure: ANYVALID
  6732. *!
  6733. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6734. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6735. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6736. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6737. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6738. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6739. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6740. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6741. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6742. *!
  6743. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6744. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6745. *!
  6746. *!*****************************************************************************
  6747. PROCEDURE anyvalid
  6748. *)
  6749. *) ANYVALID - Place Valid clause if applicable.
  6750. *)
  6751. PRIVATE m.genericname, m.valid
  6752. IF NOT EMPTY(VALID)
  6753.    \\ ;
  6754.    IF validtype = 0
  6755.       m.valid = VALID
  6756.       \    VALID <<stripcr(m.valid)>>
  6757.    ELSE
  6758.       m.genericname = getcname(VALID)
  6759.       \    VALID <<m.genericname>>()
  6760.       DO addtoctrl WITH m.genericname, "VALID", VALID, name
  6761.    ENDIF
  6762. ENDIF
  6763.  
  6764. *!*****************************************************************************
  6765. *!
  6766. *!      Procedure: ANYTITLEORFOOTER
  6767. *!
  6768. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6769. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6770. *!
  6771. *!*****************************************************************************
  6772. PROCEDURE anytitleorfooter
  6773. *)
  6774. *) ANYTITLEORFOOTER - Place Window Title/Footer clause.
  6775. *)
  6776. PRIVATE m.string, m.thetag
  6777. IF NOT EMPTY(TAG)
  6778.    \\ ;
  6779.    m.string = SUBSTR(TAG,2)
  6780.    IF SUBSTR(m.string,1,1) = m.g_itse
  6781.       \    TITLE <<SUBSTR(m.string, 2, RAT('"',m.string)-2)>>
  6782.    ELSE
  6783.       m.thetag = TAG
  6784.       \    TITLE <<m.thetag>>
  6785.    ENDIF
  6786. ENDIF
  6787. IF NOT EMPTY(tag2)
  6788.    \\ ;
  6789.    m.string = SUBSTR(tag2,2)
  6790.    IF SUBSTR(m.string,1,1) = m.g_itse
  6791.       \    FOOTER <<SUBSTR(m.string, 2, RAT('"',m.string)-2)>>
  6792.    ELSE
  6793.       m.thetag = tag2
  6794.       \    FOOTER <<m.thetag>>
  6795.    ENDIF
  6796. ENDIF
  6797. RETURN
  6798.  
  6799.  
  6800. *!*****************************************************************************
  6801. *!
  6802. *!      Procedure: ANYWHEN
  6803. *!
  6804. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6805. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6806. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6807. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6808. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6809. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6810. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6811. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6812. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6813. *!
  6814. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6815. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6816. *!
  6817. *!*****************************************************************************
  6818. PROCEDURE anywhen
  6819. *)
  6820. *) ANYWHEN - Place a When clause in a Get field.
  6821. *)
  6822. PRIVATE m.genericname, m.when
  6823. IF EMPTY(WHEN)
  6824.    RETURN
  6825. ENDIF
  6826. \\ ;
  6827. IF whentype = 0
  6828.    m.when = WHEN
  6829.    \    WHEN <<stripcr(m.when)>>
  6830. ELSE
  6831.    m.genericname = getcname(WHEN)
  6832.    \    WHEN <<m.genericname>>()
  6833.    DO addtoctrl WITH m.genericname, "WHEN", WHEN, name
  6834. ENDIF
  6835. RETURN
  6836.  
  6837. *!*****************************************************************************
  6838. *!
  6839. *!      Procedure: ANYMESSAGE
  6840. *!
  6841. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6842. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6843. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6844. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6845. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6846. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6847. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6848. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6849. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6850. *!
  6851. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6852. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6853. *!
  6854. *!*****************************************************************************
  6855. PROCEDURE anymessage
  6856. *)
  6857. *) ANYMESSAGE - Place a message clause whenever appropriate.
  6858. *)
  6859. PRIVATE m.genericname, m.mess
  6860. IF EMPTY(MESSAGE)
  6861.    RETURN
  6862. ENDIF
  6863. \\ ;
  6864. IF messtype = 0
  6865.    m.mess = MESSAGE
  6866.    \    MESSAGE
  6867.    \\ <<stripcr(m.mess)>>
  6868. ELSE
  6869.    m.genericname = getcname(MESSAGE)
  6870.    \    MESSAGE <<m.genericname>>()
  6871.    DO addtoctrl WITH m.genericname, "MESSAGE", MESSAGE, name
  6872. ENDIF
  6873. RETURN
  6874.  
  6875. *!*****************************************************************************
  6876. *!
  6877. *!      Procedure: ANYERROR
  6878. *!
  6879. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6880. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6881. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6882. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6883. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6884. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6885. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6886. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6887. *!
  6888. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6889. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6890. *!
  6891. *!*****************************************************************************
  6892. PROCEDURE anyerror
  6893. *)
  6894. *) ANYERROR - Place an error clause whenever appropriate.
  6895. *)
  6896. PRIVATE m.genericname, m.err
  6897. IF EMPTY(ERROR)
  6898.    RETURN
  6899. ENDIF
  6900. \\ ;
  6901. IF errortype = 0
  6902.    m.err = ERROR
  6903.    \    ERROR
  6904.    \\ <<stripcr(m.err)>>
  6905. ELSE
  6906.    m.genericname = getcname(ERROR)
  6907.    \    ERROR <<m.genericname>>()
  6908.    DO addtoctrl WITH m.genericname, "ERROR", ERROR, name
  6909. ENDIF
  6910. RETURN
  6911.  
  6912. *!*****************************************************************************
  6913. *!
  6914. *!      Procedure: ANYFILL
  6915. *!
  6916. *!*****************************************************************************
  6917. PROCEDURE anyfill
  6918. *)
  6919. *) ANYFILL - Place the Fill clause whenever appropriate.
  6920. *)
  6921. IF fillchar <> c_null
  6922.    \\ ;
  6923.    \    FILL "<<Fillchar>>"
  6924. ENDIF
  6925. RETURN
  6926.  
  6927. *!*****************************************************************************
  6928. *!
  6929. *!      Procedure: ANYWINDOWCHARS
  6930. *!
  6931. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6932. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6933. *!
  6934. *!*****************************************************************************
  6935. PROCEDURE anywindowchars
  6936. *)
  6937. *) ANYWINDOWCHARS - Place window characteristics options.
  6938. *)
  6939. *) Description:
  6940. *) Place the FLOAT, GROW, CLOSE, ZOOM, SHADOW, and MINIMIZE clauses
  6941. *) for a window painted by the user.
  6942. *)
  6943. \\ ;
  6944. \    <<IIF(Float, "FLOAT ;", "NOFLOAT ;")>>
  6945. \    <<IIF(Close, "CLOSE", "NOCLOSE")>>
  6946. IF SHADOW
  6947.    \\ ;
  6948.    \    SHADOW
  6949. ENDIF
  6950. IF m.g_genvers <> "MAC"
  6951.     IF MINIMIZE
  6952.        \\ ;
  6953.        \    MINIMIZE
  6954.     ELSE
  6955.        \\ ;
  6956.        \    NOMINIMIZE
  6957.     ENDIF
  6958. ENDIF
  6959. RETURN
  6960.  
  6961. *!*****************************************************************************
  6962. *!
  6963. *!      Procedure: ANYBORDER
  6964. *!
  6965. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6966. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6967. *!
  6968. *!*****************************************************************************
  6969. PROCEDURE anyborder
  6970. *)
  6971. *) ANYBORDER - Place Border type clause on a box.
  6972. *)
  6973. *) Description:
  6974. *) Place border type clause on a box depending on the setting of
  6975. *) the field Border.
  6976. *)
  6977. IF BORDER<>1
  6978.    \\ ;
  6979. ENDIF
  6980.  
  6981. DO CASE
  6982. CASE BORDER = 0
  6983.    \    NONE
  6984. CASE BORDER = 2
  6985.    \    DOUBLE
  6986. CASE BORDER = 3
  6987.    \    PANEL
  6988. CASE BORDER = 4
  6989.    \    SYSTEM
  6990. ENDCASE
  6991. RETURN
  6992.  
  6993. *!*****************************************************************************
  6994. *!
  6995. *!      Procedure: ANYWALLPAPER
  6996. *!
  6997. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6998. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6999. *!
  7000. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  7001. *!
  7002. *!*****************************************************************************
  7003. PROCEDURE anywallpaper
  7004. *)
  7005. *) ANYWALLPAPER - Place FILL FILE clause on any window.
  7006. *)
  7007. IF !EMPTY(PICTURE) 
  7008.    m.relpath = findrelpath(SUBSTR(PICTURE, 2, LEN(PICTURE) - 2))
  7009.     IF !EMPTY(basename(m.relpath))
  7010.       \\ ;
  7011.       \    FILL FILE LOCFILE("<<m.relpath>>",<<bitmapstr(c_all)>>, ;
  7012.       \        "Where is <<LOWER(basename(m.relpath))>>?")
  7013.    ENDIF
  7014. ENDIF
  7015. RETURN
  7016.  
  7017. *!*****************************************************************************
  7018. *!
  7019. *!      Procedure: ANYICON
  7020. *!
  7021. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  7022. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  7023. *!
  7024. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  7025. *!
  7026. *!*****************************************************************************
  7027. PROCEDURE anyicon
  7028. *)
  7029. *) ANYICON - Place ICON FILE clause on any window.
  7030. *)
  7031. IF !EMPTY(ORDER) AND ORDER <> '""'
  7032.    m.relpath = findrelpath(SUBSTR(ORDER, 2, LEN(ORDER) - 2))
  7033.     IF !EMPTY(basename(m.relpath))
  7034.       \\ ;
  7035.       \    ICON FILE LOCFILE("<<m.relpath>>","<<iconstr()>>", ;
  7036.       \        "Where is <<LOWER(basename(m.relpath))>>?")
  7037.    ENDIF
  7038. ENDIF
  7039. RETURN
  7040.  
  7041. *!*****************************************************************************
  7042. *!
  7043. *!      Procedure: WINDOWFROMTO
  7044. *!
  7045. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  7046. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  7047. *!
  7048. *!*****************************************************************************
  7049. PROCEDURE windowfromto
  7050. *)
  7051. *) WINDOWFROMTO - Place FROM...TO clause on any window.
  7052. *)
  7053. *) Description:
  7054. *) Place FROM...TO clause on any window designed in the screen
  7055. *) painter.  If window is to be centered, then adjust the coordinates
  7056. *) accordingly.
  7057. *)
  7058. PARAMETER m.xcoord, m.ycoord
  7059. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  7060.    SET DECIMALS TO 3
  7061. ENDIF
  7062. IF PARAMETERS() = 0
  7063.    IF CENTER
  7064.       IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  7065.          \    AT  <<Vpos>>, <<Hpos>>  ;
  7066.          \    SIZE <<Height>>,<<Width>>
  7067.       ELSE
  7068.          \    FROM INT((SROW()-<<Height>>)/2),
  7069.          \\INT((SCOL()-<<Width>>)/2) ;
  7070.          \    TO INT((SROW()-<<Height>>)/2)+<<Height-1>>,
  7071.          \\INT((SCOL()-<<Width>>)/2)+<<Width-1>>
  7072.       ENDIF
  7073.    ELSE
  7074.       IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  7075.          \    AT <<Vpos>>, <<Hpos>> ;
  7076.          \    SIZE <<Height>>,<<Width>>
  7077.       ELSE
  7078.          \    FROM <<Vpos>>, <<Hpos>> ;
  7079.          \    TO <<Height+Vpos-1>>,<<Width+Hpos-1>>
  7080.       ENDIF
  7081.    ENDIF
  7082. ELSE
  7083.    IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  7084.       \    AT <<m.xcoord>>, <<m.ycoord>> ;
  7085.       \    SIZE <<Height>>,<<Width>>
  7086.    ELSE
  7087.       \    FROM <<m.xcoord>>, <<m.ycoord>> ;
  7088.       \    TO <<Height+m.xcoord-1>>,<<Width+m.ycoord-1>>
  7089.    ENDIF
  7090. ENDIF
  7091. SET DECIMALS TO 0
  7092. RETURN
  7093.  
  7094. **
  7095. ** Code Generating Documentation in Control and Format files.
  7096. **
  7097.  
  7098. *!*****************************************************************************
  7099. *!
  7100. *!      Procedure: HEADER
  7101. *!
  7102. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  7103. *!
  7104. *!*****************************************************************************
  7105. PROCEDURE HEADER
  7106. *)
  7107. *) HEADER - Generate application program's header.
  7108. *)
  7109. *) Description:
  7110. *) As a part of the application's header generate program name, name
  7111. *) of the author of the program, copyright notice, company name and
  7112. *) address, and the word 'Description:' which will be followed with
  7113. *) the application description generated by a separate procedure.
  7114. *)
  7115. IF LEN(_PRETEXT) <> 0
  7116.    \
  7117. ENDIF
  7118. \\*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7119. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7120. \*       <<m.g_verti1>> <<DATE()>>
  7121. \\<<PADC(UPPER(ALLTRIM(strippath(m.g_outfile))),IIF(SET("CENTURY")="ON",35,37))," ")>>
  7122. \\  <<TIME()>> <<m.g_verti2>>
  7123. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7124. \*       <<m.g_corn5>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn6>>
  7125. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7126. \*       <<m.g_verti1>> <<m.g_devauthor>>
  7127. \\<<SAFEREPL(" ",56-LEN(m.g_devauthor))>><<m.g_verti2>>
  7128. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7129. \*       <<m.g_verti1>>
  7130. \\ Copyright (c) <<YEAR(DATE())>>
  7131. IF LEN(ALLTRIM(m.g_devcompany)) <= 36
  7132.    \\ <<ALLTRIM(m.g_devcompany)>>
  7133.    \\<<SAFEREPL(" ",37-LEN(ALLTRIM(m.g_devcompany)))>>
  7134.    \\<<m.g_verti2>>
  7135. ELSE
  7136.    \\ <<SAFEREPL(" ",37)>><<m.g_verti2>>
  7137.    \*       <<m.g_verti1>> <<m.g_devcompany>>
  7138.    \\<<SAFEREPL(" ",56-LEN(m.g_devcompany))>><<m.g_verti2>>
  7139. ENDIF
  7140. \*       <<m.g_verti1>> <<m.g_devaddress>>
  7141. \\<<SAFEREPL(" ",56-LEN(m.g_devaddress))>><<m.g_verti2>>
  7142.  
  7143. \*       <<m.g_verti1>> <<ALLTRIM(m.g_devcity)>>, <<m.g_devstate>>
  7144. \\  <<ALLTRIM(m.g_devzip)>>
  7145. \\<<SAFEREPL(" ",50-(LEN(ALLTRIM(m.g_devcity)+ALLTRIM(m.g_devzip))))>>
  7146. \\<<m.g_verti2>>
  7147.  
  7148. IF !INLIST(ALLTRIM(UPPER(m.g_devctry)),"USA","COUNTRY") AND !EMPTY(m.g_devctry)
  7149.    \*       <<m.g_verti1>> <<ALLTRIM(m.g_devctry)>>
  7150.    \\<<SAFEREPL(" ",50-(LEN(ALLTRIM(m.g_devctry))))>>
  7151.    \\<<m.g_verti2>>
  7152. ENDIF
  7153.  
  7154. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7155. \*       <<m.g_verti1>> Description:
  7156. \\                                            <<m.g_verti2>>
  7157. \*       <<m.g_verti1>>
  7158. \\ This program was automatically generated by GENSCRN.
  7159. \\    <<m.g_verti2>>
  7160. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7161. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7162. \
  7163. RETURN
  7164.  
  7165. *!*****************************************************************************
  7166. *!
  7167. *!      Procedure: GENFUNCHEADER
  7168. *!
  7169. *!      Called by: VALICLAUSE         (procedure in GENSCRN.PRG)
  7170. *!               : WHENCLAUSE         (procedure in GENSCRN.PRG)
  7171. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7172. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7173. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7174. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  7175. *!
  7176. *!*****************************************************************************
  7177. PROCEDURE genfuncheader
  7178. *)
  7179. *) GENFUNCHEADER - Generate Comment for Function/Procedure.
  7180. *)
  7181. PARAMETER m.procname, m.from, m.readlevel, m.varname
  7182. m.g_snippcnt = m.g_snippcnt + 1
  7183. \
  7184. \*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7185. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7186. IF m.readlevel
  7187.    \*       <<m.g_verti1>>
  7188.    \\ <<UPPER(m.procname)>>           <<m.from>>
  7189.    \\<<SAFEREPL(" ",45-LEN(m.procname+m.from))>><<m.g_verti2>>
  7190. ELSE
  7191.    \*       <<m.g_verti1>>
  7192.    \\ <<UPPER(m.procname)>>           <<m.varname>> <<m.from>>
  7193.    \\<<SAFEREPL(" ",44-LEN(m.procname+m.varname+m.from))>><<m.g_verti2>>
  7194. ENDIF
  7195. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7196. \*       <<m.g_verti1>> Function Origin:
  7197. \\<<SAFEREPL(" ",40)>><<m.g_verti2>>
  7198. IF m.readlevel
  7199.    \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7200.    \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7201.    \*       <<m.g_verti1>> From Platform:
  7202.    \\       <<VersionCap(m.g_genvers, .F.)>>
  7203.    \\<<SAFEREPL(" ",35-LEN(VersionCap(m.g_genvers, .F.)))>>
  7204.    \\<<m.g_verti2>>
  7205.    \*       <<m.g_verti1>> From Screen:
  7206.    IF m.g_nscreens > 1 AND NOT m.g_multread
  7207.       \\         Multiple Screens
  7208.       \\<<SAFEREPL(" ",19)>><<m.g_verti2>>
  7209.    ELSE
  7210.       \\         <<basename(SYS(2014,DBF()))>>
  7211.       \\<<SAFEREPL(" ",35-LEN(basename(SYS(2014,DBF()))))>>
  7212.       \\<<m.g_verti2>>
  7213.    ENDIF
  7214.    \*       <<m.g_verti1>> Called By:           READ Statement
  7215.    \\<<SAFEREPL(" ",21)>><<m.g_verti2>>
  7216.    \*       <<m.g_verti1>> Snippet Number:
  7217.    \\      <<ALLTRIM(STR(m.g_snippcnt,2))>>
  7218.    \\<<SAFEREPL(" ",35-LEN(ALLTRIM(STR(m.g_snippcnt,2))))>><<m.g_verti2>>
  7219.    \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7220.    \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7221.    \*
  7222.    RETURN
  7223. ENDIF
  7224. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7225. \*       <<m.g_verti1>> From Platform:
  7226. \\       <<VersionCap(m.g_genvers, .F.)>>
  7227. \\<<SAFEREPL(" ",35-LEN(VersionCap(m.g_genvers, .F.)))>>
  7228. \\<<m.g_verti2>>
  7229. \*       <<m.g_verti1>> From Screen:
  7230. \\         <<basename(SYS(2014,DBF()))>>
  7231. \\,     Record Number:  <<STR(RECNO(),3)>>
  7232. \\<<SAFEREPL(" ",10-LEN(basename(SYS(2014,DBF())+STR(RECNO(),3))))>>
  7233. \\<<m.g_verti2>>
  7234. IF NOT EMPTY(m.varname)
  7235.    \*       <<m.g_verti1>> Variable:            <<m.varname>>
  7236.    \\<<SAFEREPL(" ",35-LEN(m.varname))>><<m.g_verti2>>
  7237. ENDIF
  7238. \*       <<m.g_verti1>> Called By:           <<m.from+" Clause">>
  7239. \\<<SAFEREPL(" ",35-LEN(m.from+" Clause"))>><<m.g_verti2>>
  7240. IF OBJECT(objtype) <> ""
  7241.    \*       <<m.g_verti1>> Object Type:
  7242.    \\         <<Object(Objtype)>>
  7243.    \\<<SAFEREPL(" ",35-LEN(Object(Objtype)))>><<m.g_verti2>>
  7244. ENDIF
  7245. \*       <<m.g_verti1>> Snippet Number:
  7246. \\      <<ALLTRIM(STR(m.g_snippcnt,3))>>
  7247. \\<<SAFEREPL(" ",35-LEN(ALLTRIM(STR(m.g_snippcnt,3))))>><<m.g_verti2>>
  7248. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7249. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7250. \*
  7251. RETURN
  7252.  
  7253. *!*****************************************************************************
  7254. *!
  7255. *!      Procedure: COMMENTBLOCK
  7256. *!
  7257. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  7258. *!               : PUTPROCHEAD        (procedure in GENSCRN.PRG)
  7259. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  7260. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  7261. *!               : GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  7262. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  7263. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  7264. *!               : PLACEREAD          (procedure in GENSCRN.PRG)
  7265. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  7266. *!
  7267. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  7268. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  7269. *!
  7270. *!*****************************************************************************
  7271. PROCEDURE commentblock
  7272. *)
  7273. *) COMMENTBLOCK - Generate a comment block.
  7274. *)
  7275. PARAMETER m.dbalias, m.string
  7276. PRIVATE m.msg
  7277. IF !EMPTY(basename(m.dbalias))
  7278.    m.msg = basename(m.dbalias)+"/"+versioncap(m.g_genvers, .F.)+m.string
  7279. ELSE
  7280.    m.msg = versioncap(m.g_genvers, .F.)+m.string
  7281. ENDIF
  7282. \
  7283. \*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7284. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7285. \*       <<m.g_verti1>>
  7286. \\ <<PADC(m.msg,55," ")>>
  7287. \\ <<m.g_verti2>>
  7288. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7289. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7290. \*
  7291. \
  7292.  
  7293. *!*****************************************************************************
  7294. *!
  7295. *!      Procedure: PROCCOMMENTBLOCK
  7296. *!
  7297. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  7298. *!
  7299. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  7300. *!
  7301. *!*****************************************************************************
  7302. PROCEDURE proccommentblock
  7303. *)
  7304. *) PROCCOMMENTBLOCK - Generate a procedure comment block.
  7305. *)
  7306. PARAMETER m.dbalias, m.string
  7307. PRIVATE m.msg
  7308. m.msg = basename(m.dbalias)+m.string
  7309. \
  7310. \*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7311. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7312. \*       <<m.g_verti1>>
  7313. \\ <<PADC(m.msg,55," ")>>
  7314. \\ <<m.g_verti2>>
  7315. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7316. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7317. \*
  7318. \
  7319. RETURN
  7320.  
  7321. *!*****************************************************************************
  7322. *!
  7323. *!      Procedure: GENCOMMENT
  7324. *!
  7325. *!      Called by: GENVALIDBODY       (procedure in GENSCRN.PRG)
  7326. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7327. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7328. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7329. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7330. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  7331. *!
  7332. *!*****************************************************************************
  7333. PROCEDURE gencomment
  7334. *)
  7335. *) GENCOMMENT - Generate a comment.
  7336. *)
  7337. PARAMETER m.msg
  7338. \*
  7339. \* <<m.msg>>
  7340. \*
  7341.  
  7342. *!*****************************************************************************
  7343. *!
  7344. *!      Procedure: SAFEREPL
  7345. *!
  7346. *!*****************************************************************************
  7347. FUNCTION saferepl
  7348. * REPLICATE shell
  7349. PARAMETER m.strg, m.num
  7350. RETURN REPLICATE(m.strg, max(m.num, 0))
  7351.  
  7352. **
  7353. ** General Supporting Routines
  7354. **
  7355.  
  7356. *!*****************************************************************************
  7357. *!
  7358. *!       Function: BASENAME
  7359. *!
  7360. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  7361. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  7362. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7363. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7364. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7365. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7366. *!               : GENRELSTMTS        (procedure in GENSCRN.PRG)
  7367. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  7368. *!               : PROCCOMMENTBLOCK   (procedure in GENSCRN.PRG)
  7369. *!
  7370. *!          Calls: STRIPPATH()        (function  in GENSCRN.PRG)
  7371. *!               : STRIPEXT()         (function  in GENSCRN.PRG)
  7372. *!
  7373. *!*****************************************************************************
  7374. FUNCTION basename
  7375. PARAMETER m.filename
  7376. RETURN strippath(stripext(m.filename))
  7377.  
  7378. *!*****************************************************************************
  7379. *!
  7380. *!       Function: STRIPEXT
  7381. *!
  7382. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  7383. *!               : BASENAME()         (function  in GENSCRN.PRG)
  7384. *!
  7385. *!*****************************************************************************
  7386. FUNCTION stripext
  7387. *)
  7388. *) STRIPEXT - Strip the extension from a file name.
  7389. *)
  7390. *) Description:
  7391. *) Use the algorithm employed by FoxPRO itself to strip a
  7392. *) file of an extension (if any): Find the rightmost dot in
  7393. *) the filename.  If this dot occurs to the right of a "\"
  7394. *) or ":", then treat everything from the dot rightward
  7395. *) as an extension.  Of course, if we found no dot,
  7396. *) we just hand back the filename unchanged.
  7397. *)
  7398. *) Parameters:
  7399. *) filename - character string representing a file name
  7400. *)
  7401. *) Return value:
  7402. *) The string "filename" with any extension removed
  7403. *)
  7404. PARAMETER m.filename
  7405. PRIVATE m.dotpos, m.terminator
  7406. m.dotpos = RAT(".", m.filename)
  7407. m.terminator = MAX(RAT("\", m.filename), RAT(":", m.filename))
  7408. IF m.dotpos > m.terminator
  7409.    m.filename = LEFT(m.filename, m.dotpos-1)
  7410. ENDIF
  7411. RETURN m.filename
  7412.  
  7413. *!*****************************************************************************
  7414. *!
  7415. *!       Function: STRIPPATH
  7416. *!
  7417. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  7418. *!               : BASENAME()         (function  in GENSCRN.PRG)
  7419. *!
  7420. *!*****************************************************************************
  7421. FUNCTION strippath
  7422. *)
  7423. *) STRIPPATH - Strip the path from a file name.
  7424. *)
  7425. *) Description:
  7426. *) Find positions of backslash in the name of the file.  If there is one
  7427. *) take everything to the right of its position and make it the new file
  7428. *) name.  If there is no slash look for colon.  Again if found, take
  7429. *) everything to the right of it as the new name.  If neither slash
  7430. *) nor colon are found then return the name unchanged.
  7431. *)
  7432. *) Parameters:
  7433. *) filename - character string representing a file name
  7434. *)
  7435. *) Return value:
  7436. *) The string "filename" with any path removed
  7437. *)
  7438. PARAMETER m.filename
  7439. PRIVATE m.slashpos, m.namelen, m.colonpos
  7440. m.slashpos = RAT("\", m.filename)
  7441. IF m.slashpos > 0
  7442.    m.namelen  = LEN(m.filename) - m.slashpos
  7443.    m.filename = RIGHT(m.filename, m.namelen)
  7444. ELSE
  7445.    m.colonpos = RAT(":", m.filename)
  7446.    IF m.colonpos > 0
  7447.       m.namelen  = LEN(m.filename) - m.colonpos
  7448.       m.filename = RIGHT(m.filename, m.namelen)
  7449.    ENDIF
  7450. ENDIF
  7451. RETURN m.filename
  7452.  
  7453. *!*****************************************************************************
  7454. *!
  7455. *!       Function: STRIPCR
  7456. *!
  7457. *!*****************************************************************************
  7458. FUNCTION stripcr
  7459. *)
  7460. *) STRIPCR - Strip off terminating carriage returns and line feeds
  7461. *)
  7462. PARAMETER m.strg
  7463. * Don't use a CHRTRAN since it's remotely possible that the CR or LF might
  7464. * be in a user's quoted string.
  7465. strg = ALLTRIM(strg)
  7466. i = LEN(strg)
  7467. DO WHILE i >= 0 AND INLIST(SUBSTR(strg,i,1),CHR(13),CHR(10))
  7468.    i = i - 1
  7469. ENDDO
  7470. RETURN LEFT(strg,i)
  7471.  
  7472. *!*****************************************************************************
  7473. *!
  7474. *!       Function: ADDBS
  7475. *!
  7476. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7477. *!
  7478. *!*****************************************************************************
  7479. FUNCTION addbs
  7480. *)
  7481. *) ADDBS - Add a backslash unless there is one already there.
  7482. *)
  7483. PARAMETER m.pathname
  7484. PRIVATE m.separator
  7485. m.separator = IIF(_MAC,":","\")
  7486. m.pathname = ALLTRIM(UPPER(m.pathname))
  7487. IF !(RIGHT(m.pathname,1) $ '\:') AND !EMPTY(m.pathname)
  7488.    m.pathname = m.pathname + m.separator
  7489. ENDIF
  7490. RETURN m.pathname
  7491.  
  7492. *!*****************************************************************************
  7493. *!
  7494. *!       Function: JUSTFNAME
  7495. *!
  7496. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7497. *!
  7498. *!*****************************************************************************
  7499. FUNCTION justfname
  7500. *)
  7501. *) JUSTFNAME - Return just the filename (i.e., no path) from "filname"
  7502. *)
  7503. PARAMETERS m.filname
  7504. IF RAT('\',m.filname) > 0
  7505.    m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
  7506. ENDIF
  7507. IF AT(':',m.filname) > 0
  7508.    m.filname = SUBSTR(m.filname,AT(':',m.filname)+1,255)
  7509. ENDIF
  7510. RETURN ALLTRIM(UPPER(m.filname))
  7511.  
  7512. *!*****************************************************************************
  7513. *!
  7514. *!       Function: JUSTSTEM
  7515. *!
  7516. *!*****************************************************************************
  7517. FUNCTION juststem
  7518. * Return just the stem name from "filname"
  7519. PARAMETERS m.filname
  7520. IF RAT('\',m.filname) > 0
  7521.    m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
  7522. ENDIF
  7523. IF RAT(':',m.filname) > 0
  7524.    m.filname = SUBSTR(m.filname,RAT(':',m.filname)+1,255)
  7525. ENDIF
  7526. IF AT('.',m.filname) > 0
  7527.    m.filname = SUBSTR(m.filname,1,AT('.',m.filname)-1)
  7528. ENDIF
  7529. RETURN ALLTRIM(UPPER(m.filname))
  7530.  
  7531. *!*****************************************************************************
  7532. *!
  7533. *!       Function: JUSTPATH
  7534. *!
  7535. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7536. *!
  7537. *!*****************************************************************************
  7538. FUNCTION justpath
  7539. *)
  7540. *) JUSTPATH - Returns just the pathname.
  7541. *)
  7542. PARAMETERS m.filname
  7543. m.filname = ALLTRIM(UPPER(m.filname))
  7544. IF '\' $ m.filname
  7545.    m.filname = SUBSTR(m.filname,1,RAT('\',m.filname))
  7546.    IF RIGHT(m.filname,1) = '\' AND LEN(m.filname) > 1 ;
  7547.             AND SUBSTR(m.filname,LEN(m.filname)-1,1) <> ':'
  7548.          filname = SUBSTR(m.filname,1,LEN(m.filname)-1)
  7549.    ENDIF
  7550.    RETURN m.filname
  7551. ELSE
  7552.    RETURN ''
  7553. ENDIF
  7554.  
  7555.  
  7556. *!*****************************************************************************
  7557. *!
  7558. *!       Function: JUSTEXT
  7559. *!
  7560. *!*****************************************************************************
  7561. FUNCTION justext
  7562. * Return just the extension from "filname"
  7563. PARAMETERS m.filname
  7564. PRIVATE m.ext
  7565. filname = justfname(m.filname)   && prevents problems with ..\ paths
  7566. m.ext = ""
  7567. IF AT('.',m.filname) > 0
  7568.    m.ext = SUBSTR(m.filname,AT('.',m.filname)+1,3)
  7569. ENDIF
  7570. RETURN UPPER(m.ext)
  7571.  
  7572. *!*****************************************************************************
  7573. *!
  7574. *!       Function: FORCEEXT
  7575. *!
  7576. *!          Calls: JUSTPATH()         (function  in GENSCRN.PRG)
  7577. *!               : JUSTFNAME()        (function  in GENSCRN.PRG)
  7578. *!               : ADDBS()            (function  in GENSCRN.PRG)
  7579. *!
  7580. *!*****************************************************************************
  7581. FUNCTION forceext
  7582. *)
  7583. *) FORCEEXT - Force filename to have a particular extension.
  7584. *)
  7585. PARAMETERS m.filname,m.ext
  7586. PRIVATE m.ext
  7587. IF SUBSTR(m.ext,1,1) = "."
  7588.    m.ext = SUBSTR(m.ext,2,3)
  7589. ENDIF
  7590.  
  7591. m.pname = justpath(m.filname)
  7592. m.filname = justfname(UPPER(ALLTRIM(m.filname)))
  7593. IF AT('.',m.filname) > 0
  7594.    m.filname = SUBSTR(m.filname,1,AT('.',m.filname)-1) + '.' + m.ext
  7595. ELSE
  7596.    m.filname = m.filname + '.' + m.ext
  7597. ENDIF
  7598. RETURN addbs(m.pname) + m.filname
  7599.  
  7600. *!*****************************************************************************
  7601. *!
  7602. *!       Function: UNIQUEWIN
  7603. *!
  7604. *!      Called by: GENWINDEFI         (procedure in GENSCRN.PRG)
  7605. *!
  7606. *!*****************************************************************************
  7607. FUNCTION uniquewin
  7608. *)
  7609. *) UNIQUEWIN - Check if a window name is unique.
  7610. *)
  7611. PARAMETER m.windowname, m.windcnt, m.arry
  7612. EXTERNAL ARRAY arry
  7613. PRIVATE m.found, m.i, m.first, m.middle
  7614. m.found  = .F.
  7615. m.first  = 1
  7616. m.last   = m.windcnt
  7617. m.middle = 0
  7618.  
  7619. IF EMPTY(arry[1,1])
  7620.    RETURN 1
  7621. ENDIF
  7622. DO WHILE (m.last >= m.first) AND NOT m.found
  7623.    m.middle = INT((m.first+m.last) / 2)
  7624.    DO CASE
  7625.    CASE m.windowname < arry[m.middle,1]
  7626.       m.last = m.middle - 1
  7627.    CASE m.windowname > arry[m.middle,1]
  7628.       m.first = m.middle + 1
  7629.    OTHERWISE
  7630.       m.found = .T.
  7631.    ENDCASE
  7632. ENDDO
  7633. IF m.found
  7634.    RETURN 0
  7635. ELSE
  7636.    RETURN m.first
  7637. ENDIF
  7638. RETURN 
  7639.  
  7640. *!*****************************************************************************
  7641. *!
  7642. *!      Procedure: ADDTOCTRL
  7643. *!
  7644. *!      Called by: ELEMRANGE          (procedure in GENSCRN.PRG)
  7645. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  7646. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  7647. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  7648. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  7649. *!
  7650. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  7651. *!               : GENFUNCHEADER      (procedure in GENSCRN.PRG)
  7652. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  7653. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  7654. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  7655. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  7656. *!
  7657. *!*****************************************************************************
  7658. PROCEDURE addtoctrl
  7659. *)
  7660. *) ADDTOCTRL - Generate clause code for object level cluses.
  7661. *)
  7662. PARAMETER m.procname, m.from, m.memo, m.varname
  7663. PRIVATE m.linecnt, m.count, m.textline, m.genfunction, m.notcomnt, m.at, ;
  7664.    m.thispretext, m.in_dec, m.platnum, m.wnamelen, m.upline, m.thisplat
  7665.  
  7666. m.thisplat = IIF(TYPE("platform") <> "U",platform,"DOS")
  7667. m.platnum = getplatnum(m.thisplat)
  7668.  
  7669. * Write this clause to the temporary file
  7670. _TEXT = m.g_tmphandle
  7671. m.thispretext = _PRETEXT
  7672. _PRETEXT = ""
  7673.  
  7674. m.genfunction = .F.
  7675. m.notcomnt = 0
  7676. m.linecnt = MEMLINES(m.memo)
  7677. _MLINE = 0
  7678. DO genfuncheader WITH m.procname, m.from, .F., ALLTRIM(m.varname)
  7679. FOR m.count = 1 TO m.linecnt
  7680.    m.textline = MLINE(m.memo, 1, _MLINE)
  7681.    DO killcr WITH m.textline
  7682.    m.upline = UPPER(LTRIM(CHRTRAN(m.textline,chr(9),' ')))
  7683.    IF oktogenerate(@upline, @notcomnt)
  7684.       IF m.notcomnt > 0 AND NOT m.genfunction
  7685.          \FUNCTION <<m.procname>>     &&  <<m.varname>> <<m.from>>
  7686.          in_dec = SET("DECIMALS")
  7687.          SET DECIMALS TO 0
  7688.          \#REGION <<INT(m.g_screen)>>
  7689.          SET DECIMALS TO in_dec
  7690.          m.genfunction = .T.
  7691.       ENDIF
  7692.  
  7693.       IF NOT EMPTY(g_wnames[m.g_screen, m.platnum])
  7694.          m.at = atwname(g_wnames[m.g_screen, m.platnum], m.textline)
  7695.          IF m.at <> 0 AND !iscomment(@textline)
  7696.             m.wnamelen = LEN(g_wnames[m.g_screen, m.platnum])
  7697.             \<<STUFF(m.textline, m.at, m.wnamelen,g_screens[m.g_screen,2])>>
  7698.          ELSE
  7699.             IF !geninsertcode(@upline,m.g_screen, .F., m.thisplat)
  7700.                \<<m.textline>>
  7701.             ENDIF
  7702.          ENDIF
  7703.       ELSE
  7704.          IF !geninsertcode(@upline,m.g_screen, .F., m.thisplat)
  7705.             \<<m.textline>>
  7706.          ENDIF
  7707.       ENDIF
  7708.    ENDIF
  7709. ENDFOR
  7710. IF m.notcomnt = 0
  7711.    \FUNCTION <<m.procname>>     &&  <<m.varname>> <<m.from>>
  7712. ENDIF
  7713. _TEXT = m.g_orghandle
  7714. _PRETEXT = m.thispretext
  7715. RETURN 
  7716.  
  7717. *!*****************************************************************************
  7718. *!
  7719. *!       Function: OKTOGENERATE
  7720. *!
  7721. *!      Called by: ADDTOCTRL          (procedure in GENSCRN.PRG)
  7722. *!
  7723. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  7724. *!               : MATCH()            (function  in GENSCRN.PRG)
  7725. *!
  7726. *!*****************************************************************************
  7727. FUNCTION oktogenerate
  7728. *)
  7729. *) OKTOGENERATE - Ok to generate this line?
  7730. *)
  7731. *) Description:
  7732. *) Check if the code segment provided by the user for the object level
  7733. *) VALID, MESSAGE, and WHEN clauses does not contain 'FUNCTION',
  7734. *) 'PROCEDURE' or 'PARAMETER' statements as its first non-comment
  7735. *) statements.  Further, do not output #NAME directives. This is done on line by
  7736. *) line basis.
  7737. *)
  7738. *) "notcomnt" needs to be passed by reference, and is changed in this module
  7739. *) m.statement must already be in upper case and trimmed.  It may be passed by reference.
  7740. PARAMETER m.statement, m.notcomnt
  7741.  
  7742. PRIVATE m.asterisk, m.ampersand, m.isnote, m.name, m.word1
  7743. IF EMPTY(m.statement)
  7744.    RETURN .T.
  7745. ENDIF
  7746.  
  7747. DO CASE
  7748. CASE AT("*", m.statement) = 1 ;
  7749.       OR AT(m.g_dblampersand, m.statement) = 1 ;
  7750.       OR AT("NOTE", m.statement) = 1
  7751.    RETURN .T.
  7752. OTHERWISE
  7753.    * OK, it's not a comment
  7754.    m.notcomnt = m.notcomnt + 1
  7755.    * Make a quick test to see if we may exclude this line
  7756.    IF AT(LEFT(statement,1),"PF#") > 0
  7757.       * Postpone the expensive wordnum and match functions as long as possible
  7758.       word1 = CHRTRAN(wordnum(statement,1),';','')
  7759.       DO CASE
  7760.       CASE match(word1,"PROCEDURE") OR match(word1,"FUNCTION") OR match(word1,"PARAMETERS")
  7761.          *
  7762.          * If the first non-comment line is a FUNCTION, PROCEDURE, or
  7763.          * a PARAMETER statement then do not generate it.
  7764.          *
  7765.          IF m.notcomnt = 1
  7766.             RETURN .F.
  7767.          ENDIF
  7768.       CASE LEFT(statement,5) == "#NAME"   && Don't ever emit a #NAME directive
  7769.          RETURN .F.
  7770.       ENDCASE
  7771.    ENDIF
  7772. ENDCASE
  7773. RETURN .T.
  7774.  
  7775. *!*****************************************************************************
  7776. *!
  7777. *!       Function: OBJECT
  7778. *!
  7779. *!*****************************************************************************
  7780. FUNCTION OBJECT
  7781. *)
  7782. *) OBJECT - Return name of an object.
  7783. *)
  7784. PARAMETER m.objecttype
  7785. PRIVATE m.objname
  7786. DO CASE
  7787. CASE m.objecttype = 11
  7788.    m.objname = "List"
  7789. CASE m.objecttype = 12
  7790.    m.objname = "Push Button"
  7791. CASE m.objecttype = 13
  7792.    m.objname = "Radio Button"
  7793. CASE m.objecttype = 14
  7794.    m.objname = "Check Box"
  7795. CASE m.objecttype = 15
  7796.    m.objname = "Field"
  7797. CASE m.objecttype = 16
  7798.    m.objname = "Popup"
  7799. OTHERWISE
  7800.    m.objname = ""
  7801. ENDCASE
  7802. RETURN m.objname
  7803.  
  7804. *!*****************************************************************************
  7805. *!
  7806. *!      Procedure: COMBINE
  7807. *!
  7808. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7809. *!
  7810. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  7811. *!
  7812. *!*****************************************************************************
  7813. PROCEDURE combine
  7814. *)
  7815. *) COMBINE - Combine the original and the temp files.
  7816. *)
  7817. PRIVATE m.size, m.top, m.end, m.status, m.chunk
  7818.  
  7819. IF m.g_graphic
  7820.    SET MESSAGE TO 'Merging Files'
  7821. ENDIF
  7822. m.size = FSEEK(m.g_tmphandle,0,2)
  7823. m.top  = FSEEK(m.g_tmphandle,0)
  7824.  
  7825. DO WHILE .T.
  7826.    m.chunk = IIF(m.size>65000, 65000, m.size)
  7827.    m.end   = FSEEK(m.g_orghandle,0,2)
  7828.    m.status = FWRITE(m.g_orghandle,FREAD(m.g_tmphandle,m.chunk))
  7829.    IF m.status = 0 AND m.size > 0
  7830.       DO errorhandler WITH "Unsuccessful file merge...",;
  7831.          LINENO(), c_error_2
  7832.    ENDIF
  7833.    m.size = m.size - 65000
  7834.    IF m.size < 0
  7835.       EXIT
  7836.    ENDIF
  7837. ENDDO
  7838. IF m.g_graphic
  7839.    SET MESSAGE TO 'Generation Complete'
  7840. ELSE
  7841.    WAIT CLEAR
  7842. ENDIF
  7843. RETURN
  7844.  
  7845. **
  7846. ** Code Associated With Displaying of the Thermometer
  7847. **
  7848.  
  7849. *!*****************************************************************************
  7850. *!
  7851. *!      Procedure: ACTTHERM
  7852. *!
  7853. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7854. *!
  7855. *!*****************************************************************************
  7856. PROCEDURE acttherm
  7857. *)
  7858. *) ACTTHERM(<text>) - Activate thermometer.
  7859. *)
  7860. *) Activates thermometer.  Update the thermometer with UPDTHERM().
  7861. *) Thermometer window is named "thermometer."  Be sure to RELEASE
  7862. *) this window when done with thermometer.  Creates the global
  7863. *) m.g_thermwidth.
  7864. *)
  7865. PARAMETER m.text
  7866. PRIVATE m.prompt
  7867.  
  7868. IF m.g_graphic
  7869.    m.prompt = LOWER(m.g_outfile)
  7870.     m.prompt = thermfname(m.prompt)
  7871.  
  7872.    DO CASE
  7873.    CASE _WINDOWS
  7874.       DEFINE WINDOW thermomete ;
  7875.          AT  INT((SROW() - (( 5.615 * ;
  7876.          FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7877.          FONTMETRIC(1, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2), ;
  7878.          INT((SCOL() - (( 63.833 * ;
  7879.          FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7880.          FONTMETRIC(6, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2) ;
  7881.          SIZE 5.615,63.833 ;
  7882.          FONT m.g_dlgface, m.g_dlgsize ;
  7883.          STYLE m.g_dlgstyle ;
  7884.          NOFLOAT ;
  7885.          NOCLOSE ;
  7886.          NONE ;
  7887.          COLOR RGB(0, 0, 0, 192, 192, 192)
  7888.       MOVE WINDOW thermomete CENTER
  7889.       ACTIVATE WINDOW thermomete NOSHOW
  7890.  
  7891.       @ 0.5,3 SAY m.text FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle
  7892.       @ 1.5,3 SAY m.prompt FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle
  7893.       @ 0.000,0.000 TO 0.000,63.833 ;
  7894.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7895.       @ 0.000,0.000 TO 5.615,0.000 ;
  7896.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7897.       @ 0.385,0.667 TO 5.231,0.667 ;
  7898.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7899.       @ 0.308,0.667 TO 0.308,63.167 ;
  7900.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7901.       @ 0.385,63.000 TO 5.308,63.000 ;
  7902.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7903.       @ 5.231,0.667 TO 5.231,63.167 ;
  7904.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7905.       @ 5.538,0.000 TO 5.538,63.833 ;
  7906.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7907.       @ 0.000,63.667 TO 5.615,63.667 ;
  7908.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7909.       @ 3.000,3.333 TO 4.231,3.333 ;
  7910.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7911.       @ 3.000,60.333 TO 4.308,60.333 ;
  7912.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7913.       @ 3.000,3.333 TO 3.000,60.333 ;
  7914.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7915.       @ 4.231,3.333 TO 4.231,60.333 ;
  7916.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7917.       m.g_thermwidth = 56.269
  7918.    CASE _MAC
  7919.       DEFINE WINDOW thermomete ;
  7920.          AT  INT((SROW() - (( 5.62 * ;
  7921.          FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7922.          FONTMETRIC(1, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2), ;
  7923.          INT((SCOL() - (( 63.83 * ;
  7924.          FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7925.          FONTMETRIC(6, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2) ;
  7926.          SIZE 5.62,63.83 ;
  7927.          FONT m.g_dlgface, m.g_dlgsize ;
  7928.          STYLE m.g_dlgstyle ;
  7929.          NOFLOAT ;
  7930.          NOCLOSE ;
  7931.             NONE ;
  7932.          COLOR RGB(0, 0, 0, 192, 192, 192)
  7933.       MOVE WINDOW thermomete CENTER
  7934.       ACTIVATE WINDOW thermomete NOSHOW
  7935.  
  7936.       IF ISCOLOR()
  7937.          @ 0.000,0.000 TO 5.62,63.83 PATTERN 1;
  7938.              COLOR RGB(192, 192, 192, 192, 192, 192)
  7939.           @ 0.000,0.000 TO 0.000,63.83 ;
  7940.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7941.           @ 0.000,0.000 TO 5.62,0.000 ;
  7942.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7943.           @ 0.385,0.67 TO 5.23,0.67 ;
  7944.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7945.           @ 0.31,0.67 TO 0.31,63.17 ;
  7946.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7947.           @ 0.385,63.000 TO 5.31,63.000 ;
  7948.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7949.           @ 5.23,0.67 TO 5.23,63.17 ;
  7950.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7951.           @ 5.54,0.000 TO 5.54,63.83 ;
  7952.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7953.           @ 0.000,63.67 TO 5.62,63.67 ;
  7954.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7955.           @ 3.000,3.33 TO 4.23,3.33 ;
  7956.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7957.           @ 3.000,60.33 TO 4.31,60.33 ;
  7958.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7959.           @ 3.000,3.33 TO 3.000,60.33 ;
  7960.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7961.           @ 4.23,3.33 TO 4.23,60.33 ;
  7962.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7963.       ELSE
  7964.          @ 0.000, 0.000 TO 5.62, 63.830  PEN 2
  7965.           @ 0.230, 0.500 TO 5.39, 63.333  PEN 1
  7966.        ENDIF
  7967.       @ 0.5,3 SAY m.text FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle+"T" ;
  7968.          COLOR RGB(0,0,0,192,192,192)
  7969.       @ 1.5,3 SAY m.prompt FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle+"T" ;
  7970.          COLOR RGB(0,0,0,192,192,192)
  7971.  
  7972.       m.g_thermwidth = 56.27
  7973.         IF !ISCOLOR()
  7974.             @ 3.000,3.33 TO 4.23,m.g_thermwidth + 3.33 
  7975.         ENDIF
  7976.    ENDCASE
  7977.    SHOW WINDOW thermomete TOP
  7978. ELSE
  7979.    m.prompt = SUBSTR(SYS(2014,m.g_outfile),1,48)+;
  7980.       IIF(LEN(m.g_outfile)>48,"...","")
  7981.  
  7982.    DEFINE WINDOW thermomete;
  7983.       FROM INT((SROW()-6)/2), INT((SCOL()-57)/2) ;
  7984.       TO INT((SROW()-6)/2) + 6, INT((SCOL()-57)/2) + 57;
  7985.       DOUBLE COLOR SCHEME 5
  7986.    ACTIVATE WINDOW thermomete NOSHOW
  7987.  
  7988.    m.g_thermwidth = 50
  7989.    @ 0,3 SAY m.text
  7990.    @ 1,3 SAY UPPER(m.prompt)
  7991.    @ 2,1 TO 4,m.g_thermwidth+4 &g_boxstrg
  7992.  
  7993.    SHOW WINDOW thermomete TOP
  7994. ENDIF
  7995. RETURN
  7996.  
  7997. *!*****************************************************************************
  7998. *!
  7999. *!      Procedure: UPDTHERM
  8000. *!
  8001. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  8002. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8003. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  8004. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8005. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8006. *!
  8007. *!*****************************************************************************
  8008. PROCEDURE updtherm
  8009. *)
  8010. *) UPDTHERM(<percent>) - Update thermometer.
  8011. *)
  8012. PARAMETER m.percent
  8013. PRIVATE m.nblocks, m.percent
  8014.  
  8015. ACTIVATE WINDOW thermomete
  8016.  
  8017. * Map to the number of platforms we are generating for
  8018. m.percent = MIN(INT(m.percent / m.g_numplatforms) ,100)
  8019.  
  8020. m.nblocks = (m.percent/100) * (m.g_thermwidth)
  8021. DO CASE
  8022. CASE _WINDOWS
  8023.    @ 3.000,3.333 TO 4.231,m.nblocks + 3.333 ;
  8024.       PATTERN 1 COLOR RGB(128, 128, 128, 128, 128, 128)
  8025. CASE _MAC
  8026.    *@ 3.000,3.33 TO 4.23,m.nblocks + 3.33 ;
  8027.    *   PATTERN 1 COLOR RGB(0, 0, 0, 220, 140, 120)
  8028.    @ 3.000,3.33 TO 4.23,m.nblocks + 3.33 ;
  8029.       PATTERN 1 COLOR RGB(0, 0, 128, 0, 0, 128)
  8030. OTHERWISE
  8031.    @ 3,3 SAY REPLICATE("█",m.nblocks)
  8032. ENDCASE
  8033. RETURN
  8034.  
  8035. *!*****************************************************************************
  8036. *!
  8037. *!      Procedure: DEACTTHERMO
  8038. *!
  8039. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  8040. *!
  8041. *!*****************************************************************************
  8042. PROCEDURE deactthermo
  8043. *)
  8044. *) DEACTTHERMO - Deactivate and Release thermometer window.
  8045. *)
  8046. IF WEXIST("thermomete")
  8047.    RELEASE WINDOW thermomete
  8048. ENDIF
  8049. RETURN
  8050.  
  8051. *!*****************************************************************************
  8052. *!
  8053. *!      Procedure: THERMADJ
  8054. *!
  8055. *!*****************************************************************************
  8056. FUNCTION thermadj
  8057. * Map the local thermometer from local (this platform) to global (all platforms)
  8058. * When all platforms have been accounted for, we want to show m.finish percent.
  8059. PARAMETERS m.pnum, m.current, m.finish
  8060. =assert(m.current <= m.finish,"Thermometer error!  Current > finish.")
  8061. =assert(BETWEEN(m.finish,0,100),"Thermometer error! Finish out of range.")
  8062. RETURN (m.finish * (m.pnum - 1)) + m.current
  8063.  
  8064.  
  8065. *!*****************************************************************************
  8066. *!
  8067. *!      Procedure: THERMFNAME
  8068. *!
  8069. *!*****************************************************************************
  8070. FUNCTION thermfname
  8071. PARAMETER m.fname
  8072. PRIVATE m.addelipse, m.g_pathsep, m.g_thermfface, m.g_thermfsize, m.g_thermfstyle
  8073.  
  8074. #define c_space 50
  8075. IF _MAC
  8076.     m.g_thermfface = "Geneva"
  8077.     m.g_thermfsize = 10
  8078.     m.g_thermfstyle = "B"
  8079. ELSE
  8080.     m.g_thermfface = "MS Sans Serif"
  8081.     m.g_thermfsize = 8
  8082.     m.g_thermfstyle = "B"
  8083. ENDIF
  8084.  
  8085. * Translate the filename into Mac native format
  8086. IF _MAC
  8087.     m.g_pathsep = ":"
  8088.     m.fname = SYS(2027, m.fname)
  8089. ELSE
  8090.     m.g_pathsep = "\"    
  8091. ENDIF
  8092.  
  8093. IF TXTWIDTH(m.fname,m.g_thermfface,m.g_thermfsize,m.g_thermfstyle) > c_space
  8094.     * Make it fit in c_space
  8095.     m.fname = partialfname(m.fname, c_space - 1)
  8096.     m.addelipse = .F.
  8097.     DO WHILE TXTWIDTH(m.fname+'...',m.g_thermfface,m.g_thermfsize,m.g_thermfstyle) > c_space
  8098.         m.fname = LEFT(m.fname, LEN(m.fname) - 1)
  8099.         m.addelipse = .T.
  8100.     ENDDO
  8101.     IF m.addelipse
  8102.         m.fname = m.fname + "..."
  8103.    ENDIF
  8104. ENDIF
  8105. RETURN m.fname
  8106.  
  8107.  
  8108.  
  8109. *!*****************************************************************************
  8110. *!
  8111. *!      Procedure: PARTIALFNAME
  8112. *!
  8113. *!*****************************************************************************
  8114. FUNCTION partialfname    
  8115. PARAMETER m.filname, m.fillen
  8116. * Return a filname no longer than m.fillen characters.  Take some chars
  8117. * out of the middle if necessary.  No matter what m.fillen is, this function
  8118. * always returns at least the file stem and extension.
  8119. PRIVATE m.bname, m.elipse, m.remain
  8120. m.elipse = "..." + m.g_pathsep
  8121. IF _MAC
  8122.     m.bname = SUBSTR(m.filname, RAT(":",m.filname)+1)
  8123. ELSE
  8124.     m.bname = justfname(m.filname)
  8125. ENDIF
  8126. DO CASE
  8127. CASE LEN(m.filname) <= m.fillen 
  8128.    m.retstr = m.filname
  8129. CASE LEN(m.bname) + LEN(m.elipse) >= m.fillen
  8130.    m.retstr = m.bname
  8131. OTHERWISE
  8132.    m.remain = MAX(m.fillen - LEN(m.bname) - LEN(m.elipse), 0)
  8133.    IF _MAC
  8134.        m.retstr = LEFT(SUBSTR(m.filname,1,RAT(":",m.filname)-1),m.remain) ;
  8135.             +m.elipse+m.bname
  8136.    ELSE
  8137.          m.retstr = LEFT(justpath(m.filname),m.remain)+m.elipse+m.bname
  8138.    ENDIF
  8139. ENDCASE
  8140. RETURN m.retstr
  8141.  
  8142. **
  8143. ** Error Handling Code
  8144. **
  8145.  
  8146. *!*****************************************************************************
  8147. *!
  8148. *!      Procedure: ERRORHANDLER
  8149. *!
  8150. *!      Called by: GENSCRN.PRG
  8151. *!               : OPENPROJDBF()      (function  in GENSCRN.PRG)
  8152. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  8153. *!               : CHECKPARAM()       (function  in GENSCRN.PRG)
  8154. *!               : PREPFILE           (procedure in GENSCRN.PRG)
  8155. *!               : CLOSEFILE          (procedure in GENSCRN.PRG)
  8156. *!               : GETPLATFORM()      (function  in GENSCRN.PRG)
  8157. *!               : REFRESHPREFS       (procedure in GENSCRN.PRG)
  8158. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8159. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8160. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  8161. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  8162. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  8163. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  8164. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  8165. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  8166. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  8167. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  8168. *!               : COMBINE            (procedure in GENSCRN.PRG)
  8169. *!
  8170. *!          Calls: CLEANUP            (procedure in GENSCRN.PRG)
  8171. *!               : ERRLOG             (procedure in GENSCRN.PRG)
  8172. *!               : ERRSHOW            (procedure in GENSCRN.PRG)
  8173. *!               : CLOSEFILE          (procedure in GENSCRN.PRG)
  8174. *!
  8175. *!*****************************************************************************
  8176. PROCEDURE errorhandler
  8177. *)
  8178. *) ERRORHANDLER - Error Processing Center.
  8179. *)
  8180. PARAMETERS m.msg, m.linenum, m.errcode
  8181. IF ERROR() = 22   && too many memory variables--just bomb out as fast as we can
  8182.    ON ERROR
  8183.    DO cleanup
  8184.    CANCEL
  8185. ENDIF
  8186.  
  8187. DO CASE
  8188. CASE errcode == "Minor"
  8189.    DO errlog WITH m.msg, m.linenum
  8190.    m.g_status = 1
  8191. CASE errcode == "Serious"
  8192.    DO errlog  WITH m.msg, m.linenum
  8193.    DO errshow WITH m.msg, m.linenum
  8194.    m.g_status = 2
  8195.    ON ERROR
  8196. CASE errcode == "Fatal"
  8197.    ON ERROR
  8198.    IF m.g_havehand = .T.
  8199.       DO errlog WITH m.msg, m.linenum
  8200.       DO closefile WITH m.g_orghandle
  8201.       DO closefile WITH m.g_tmphandle
  8202.    ENDIF
  8203.    DO errshow WITH m.msg, m.linenum
  8204.    IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  8205.       RELEASE WINDOW thermometer
  8206.    ENDIF
  8207.    DO cleanup
  8208.    CANCEL
  8209. ENDCASE
  8210. RETURN 
  8211.  
  8212. *!*****************************************************************************
  8213. *!
  8214. *!      Procedure: ESCHANDLER
  8215. *!
  8216. *!      Called by: BUILDENABLE        (procedure in GENSCRN.PRG)
  8217. *!
  8218. *!          Calls: BUILDDISABLE       (procedure in GENSCRN.PRG)
  8219. *!               : CLEANUP            (procedure in GENSCRN.PRG)
  8220. *!
  8221. *!*****************************************************************************
  8222. PROCEDURE eschandler
  8223. *)
  8224. *) ESCHANDLER - Escape handler.
  8225. *)
  8226. ON ERROR
  8227. WAIT WINDOW "Generation process stopped." NOWAIT
  8228. DO builddisable
  8229. IF m.g_havehand
  8230.    ERASE (m.g_outfile)
  8231.    ERASE (m.g_tmpfile)
  8232. ENDIF
  8233. IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  8234.    RELEASE WINDOW thermometer
  8235. ENDIF
  8236. DO cleanup
  8237. CANCEL
  8238.  
  8239. *!*****************************************************************************
  8240. *!
  8241. *!      Procedure: ERRLOG
  8242. *!
  8243. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  8244. *!
  8245. *!          Calls: OPENERRFILE        (procedure in GENSCRN.PRG)
  8246. *!
  8247. *!*****************************************************************************
  8248. PROCEDURE errlog
  8249. *)
  8250. *) ERRLOG - Save an error message in the error log file.
  8251. *)
  8252. PARAMETER m.msg, m.linenum
  8253. DO openerrfile
  8254.  
  8255. SET CONSOLE OFF
  8256. \\GENERATOR: <<ALLTRIM(m.msg)>>
  8257. IF NOT EMPTY(m.linenum)
  8258.    \\ LINE NUMBER: <<m.linenum>>
  8259. ENDIF
  8260. \
  8261. = FCLOSE(_TEXT)
  8262. _TEXT = m.g_orghandle
  8263. RETURN 
  8264.  
  8265. *!*****************************************************************************
  8266. *!
  8267. *!      Procedure: ERRSHOW
  8268. *!
  8269. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  8270. *!               : OPENERRFILE        (procedure in GENSCRN.PRG)
  8271. *!
  8272. *!*****************************************************************************
  8273. PROCEDURE errshow
  8274. *)
  8275. *) ERRSHOW - Show error in an alert box on the screen.
  8276. *)
  8277. PARAMETER m.msg, m.lineno
  8278. PRIVATE m.curcursor
  8279.  
  8280. IF m.g_graphic
  8281.     IF _MAC
  8282.        DEFINE WINDOW ALERT ;
  8283.           AT  INT((SROW() - (( 6.615 * ;
  8284.           FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8285.           FONTMETRIC(1, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2), ;
  8286.           INT((SCOL() - (( 63.833 * ;
  8287.           FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8288.           FONTMETRIC(6, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2) ;
  8289.           SIZE 6.615,63.833 ;
  8290.           FONT m.g_dlgface, m.g_dlgsize ;
  8291.           STYLE m.g_dlgstyle ;
  8292.           NOCLOSE ;
  8293.           DOUBLE ;
  8294.           TITLE "Genscrn Error" ;
  8295.           COLOR RGB(0, 0, 0, 255, 255, 255)
  8296.     ELSE
  8297.        DEFINE WINDOW ALERT ;
  8298.           AT  INT((SROW() - (( 6.615 * ;
  8299.           FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8300.           FONTMETRIC(1, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2), ;
  8301.           INT((SCOL() - (( 63.833 * ;
  8302.           FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8303.           FONTMETRIC(6, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2) ;
  8304.           SIZE 6.615,63.833 ;
  8305.           FONT m.g_dlgface, m.g_dlgsize ;
  8306.           STYLE m.g_dlgstyle ;
  8307.           NOCLOSE ;
  8308.           DOUBLE ;
  8309.           TITLE "Genscrn Error" ;
  8310.           COLOR RGB(0, 0, 0, 255, 255, 255)
  8311.    ENDIF
  8312.    MOVE WINDOW ALERT CENTER
  8313.    ACTIVATE WINDOW ALERT NOSHOW
  8314.  
  8315.    m.dispmsg = m.msg
  8316.    IF TXTWIDTH(m.dispmsg) > WCOLS()
  8317.       * Make sure it isn't too long.
  8318.       DO WHILE TXTWIDTH(m.dispmsg+'...') > WCOLS()
  8319.          m.dispmsg = LEFT(m.dispmsg,LEN(m.dispmsg)-1)
  8320.       ENDDO
  8321.       IF m.msg <> m.dispmsg    && Has display message been shortened?
  8322.          m.dispmsg = m.dispmsg + '...'
  8323.       ENDIF
  8324.    ENDIF
  8325.  
  8326.    @ 1,MAX((WCOLS()-TXTWIDTH( m.dispmsg ))/2,1) SAY m.dispmsg
  8327.  
  8328.    m.msg = "Genscrn Line Number: "+STR(m.lineno, 4)
  8329.    @ 2,(WCOLS()-TXTWIDTH( m.msg ))/2 SAY m.msg
  8330.  
  8331.    IF TYPE("m.g_screen") <> "U" AND m.g_screen <> 0
  8332.       m.msg = "Generating from: "+LOWER(g_screens[m.g_screen,1])
  8333.       @ 3,MAX((WCOLS()-TXTWIDTH( m.msg ))/2,1) SAY m.msg
  8334.    ENDIF
  8335.  
  8336.    m.msg = "Press any key to cleanup and exit..."
  8337.    @ 4,(WCOLS()-TXTWIDTH( m.msg ))/2 SAY m.msg
  8338.  
  8339.    SHOW WINDOW ALERT
  8340. ELSE
  8341.    DEFINE WINDOW ALERT;
  8342.       FROM INT((SROW()-7)/2), INT((SCOL()-50)/2) TO INT((SROW()-7)/2) + 6, INT((SCOL()-50)/2) + 50 ;
  8343.       FLOAT NOGROW NOCLOSE NOZOOM SHADOW DOUBLE;
  8344.       COLOR SCHEME 7
  8345.  
  8346.    ACTIVATE WINDOW ALERT
  8347.  
  8348.    @ 0,0 CLEAR
  8349.    @ 1,0 SAY PADC(SUBSTR(m.msg,1,44)+;
  8350.       IIF(LEN(m.msg)>44,"...",""), WCOLS())
  8351.    @ 2,0 SAY PADC("Line Number: "+STR(m.lineno, 4), WCOLS())
  8352.  
  8353.    IF TYPE("m.g_screen") <> "U" AND m.g_screen <> 0
  8354.       m.msg = "Working on screen: "+LOWER(g_screens[m.g_screen])
  8355.       @ 3,0 SAY PADC(m.msg,WCOLS())
  8356.    ENDIF
  8357.  
  8358.    @ 4,0 SAY PADC("Press any key to cleanup and exit...", WCOLS())
  8359. ENDIF
  8360.  
  8361. m.curcursor = SET( "CURSOR" )
  8362. SET CURSOR OFF
  8363.  
  8364. WAIT ""
  8365.  
  8366. RELEASE WINDOW ALERT
  8367. SET CURSOR &curcursor
  8368.  
  8369. RELEASE WINDOW ALERT
  8370. RETURN 
  8371.  
  8372. *!*****************************************************************************
  8373. *!
  8374. *!      Procedure: OPENERRFILE
  8375. *!
  8376. *!      Called by: ERRLOG             (procedure in GENSCRN.PRG)
  8377. *!
  8378. *!          Calls: ERRSHOW            (procedure in GENSCRN.PRG)
  8379. *!
  8380. *!*****************************************************************************
  8381. PROCEDURE openerrfile
  8382. *)
  8383. *) OPENERRFILE - Open error file.
  8384. *)
  8385. PRIVATE m.errfile, m.errhandle
  8386. m.errfile   = m.g_errlog+".ERR"
  8387. m.errhandle = FOPEN(m.errfile,2)
  8388. IF m.errhandle < 0
  8389.    m.errhandle = FCREATE(m.errfile)
  8390.    IF m.errhandle < 0
  8391.       DO errshow WITH ".ERR could not be opened...", LINENO()
  8392.       m.g_status = 2
  8393.       IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  8394.          RELEASE WINDOW thermometer
  8395.       ENDIF
  8396.       ON ERROR
  8397.       RETURN TO MASTER
  8398.    ENDIF
  8399. ELSE
  8400.    = FSEEK(m.errhandle,0,2)
  8401. ENDIF
  8402. IF SET("TEXTMERGE") = "OFF"
  8403.    SET TEXTMERGE ON
  8404. ENDIF
  8405. _TEXT = m.errhandle
  8406.  
  8407. *!*****************************************************************************
  8408. *!
  8409. *!      Procedure: PUSHINDENT
  8410. *!
  8411. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8412. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  8413. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  8414. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  8415. *!
  8416. *!*****************************************************************************
  8417. PROCEDURE pushindent
  8418. *)
  8419. *) PUSHINDENT - Add another indentation level
  8420. *)
  8421. _PRETEXT = CHR(9) + _PRETEXT
  8422. RETURN 
  8423.  
  8424. *!*****************************************************************************
  8425. *!
  8426. *!      Procedure: POPINDENT
  8427. *!
  8428. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8429. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  8430. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  8431. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  8432. *!
  8433. *!*****************************************************************************
  8434. PROCEDURE popindent
  8435. *)
  8436. *) POPINDENT - Remove one indentation level
  8437. *)
  8438. IF LEFT(_PRETEXT,1) = CHR(9)
  8439.    _PRETEXT = SUBSTR(_PRETEXT,2)
  8440. ENDIF
  8441. RETURN 
  8442.  
  8443. *!*****************************************************************************
  8444. *!
  8445. *!      Procedure: COUNTPLATFORMS
  8446. *!
  8447. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8448. *!
  8449. *!*****************************************************************************
  8450. FUNCTION countplatforms
  8451. *)
  8452. *) COUNTPLATFORMS - Count the number of platforms in this SCX that are in common across
  8453. *)                    all the SCXs in this screen set.
  8454. *)
  8455. PRIVATE m.cnt, m.i
  8456. IF TYPE("g_platforms") <> "U"
  8457.    m.cnt = 0
  8458.    FOR m.i = 1 TO ALEN(g_platforms)
  8459.       IF !EMPTY(g_platforms[m.i])
  8460.          m.cnt = m.cnt + 1
  8461.       ENDIF
  8462.    ENDFOR
  8463.    RETURN m.cnt
  8464. ENDIF
  8465. RETURN 0
  8466.  
  8467. *!*****************************************************************************
  8468. *!
  8469. *!      Function: LOOKUPPLATFORM
  8470. *!
  8471. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8472. *!
  8473. *!*****************************************************************************
  8474. FUNCTION lookupplatform
  8475. *)
  8476. *) LOOKUPPLATFORM - Return the n-th platform name
  8477. *)
  8478. PARAMETER m.n
  8479. IF TYPE("g_platforms") <> "U" AND ALEN(g_platforms) >= m.n ;
  8480.       AND m.n > 0 AND TYPE("g_platforms[m.n]") = "C"
  8481.    RETURN UPPER(g_platforms[m.n])
  8482. ENDIF
  8483. RETURN ""
  8484.  
  8485. *!*****************************************************************************
  8486. *!
  8487. *!      Function: HASRECORDS
  8488. *!
  8489. *!*****************************************************************************
  8490. FUNCTION hasrecords
  8491. *)
  8492. *) HASRECORDS - Return .T. if plat records are in the screen.
  8493. *)
  8494. PARAMETER m.plat
  8495. IF TYPE("g_platforms") = "U"
  8496.    RETURN IIF(m.plat = "DOS",.T.,.F.)
  8497. ELSE
  8498.    RETURN IIF(ASCAN(g_platforms,m.plat) > 0,.T.,.F.)
  8499. ENDIF
  8500. RETURN 
  8501.  
  8502. *!*****************************************************************************
  8503. *!
  8504. *!       Function: GETPARAM
  8505. *!
  8506. *!      Called by: CHECKPARAM()       (function  in GENSCRN.PRG)
  8507. *!
  8508. *!          Calls: ISCOMMENT()        (function  in GENSCRN.PRG)
  8509. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  8510. *!               : MATCH()            (function  in GENSCRN.PRG)
  8511. *!
  8512. *!*****************************************************************************
  8513. FUNCTION getparam
  8514. *)
  8515. *) GETPARAM - Return the PARAMETER statement from a setup snippet, if one is there
  8516. *)
  8517. PARAMETER m.snipname
  8518. PRIVATE m.i, m.thisparam, m.numlines, m.thisline, m.word1, m.contin
  8519.  
  8520. * Do a quick check to see if we need to search further.
  8521. IF ATC("PARA",&snipname) = 0
  8522.    RETURN ""
  8523. ENDIF
  8524.  
  8525. m.numlines = MEMLINES(&snipname)
  8526. _MLINE = 0
  8527. m.i = 1
  8528. DO WHILE m.i <= m.numlines
  8529.    m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  8530.    DO killcr WITH m.thisline
  8531.    
  8532.    * Drop any double-ampersand comment
  8533.    IF AT(m.g_dblampersand,m.thisline) > 0
  8534.       m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  8535.    ENDIF
  8536.    
  8537.    IF !EMPTY(m.thisline) AND !iscomment(@thisline)
  8538.       * See if the first non-blank, non-comment, non-directive, non-EXTERNAL
  8539.       * line is a #SECTION 1
  8540.       DO CASE
  8541.       CASE LEFT(m.thisline,5) = "#SECT" AND AT('1',m.thisline) <> 0
  8542.          * Read until we find a #SECTION 2, the end of the snippet or a
  8543.          * PARAMETER statement.
  8544.          DO WHILE m.i <= m.numlines
  8545.             m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  8546.             DO killcr WITH m.thisline
  8547.             
  8548.             * Drop any double-ampersand comment
  8549.             IF AT(m.g_dblampersand,m.thisline) > 0
  8550.                m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  8551.             ENDIF
  8552.             
  8553.             m.word1 = wordnum(CHRTRAN(m.thisline,CHR(9)+';',' '),1)
  8554.             DO CASE
  8555.             CASE match(m.word1,"PARAMETERS")
  8556.             
  8557.                * Replace tabs with spaces
  8558.                m.thisline = LTRIM(CHRTRAN(m.thisline,CHR(9)," "))
  8559.  
  8560.                * Process continuation lines.  Replace tabs in incoming lines with spaces.
  8561.                DO WHILE RIGHT(RTRIM(m.thisline),1) = ';'
  8562.                   m.thisline = m.thisline + ' '+ CHR(13)+CHR(10)+CHR(9)
  8563.                   m.contin = MLINE(&snipname, 1, _MLINE)
  8564.                   DO killcr WITH m.contin
  8565.                   m.contin = CHRTRAN(LTRIM(m.contin),CHR(9)," ")
  8566.                   m.thisline = m.thisline + UPPER(m.contin)
  8567.                ENDDO
  8568.                
  8569.                * Clean up the parameters so that minor differences in
  8570.                * spacing don't cause the comparisons to fail.
  8571.  
  8572.                * Take the parameters but not the PARAMETER keyword itself
  8573.                m.thisparam = SUBSTR(m.thisline,AT(' ',m.thisline)+1)
  8574.                DO WHILE INLIST(LEFT(m.thisparam,1),CHR(10),CHR(13),CHR(9),' ')
  8575.                   m.thisparam = SUBSTR(m.thisparam,2)
  8576.                ENDDO
  8577.  
  8578.                * Force single spacing in the param string
  8579.                DO WHILE AT('  ',m.thisparam) > 0
  8580.                   m.thisparam = STRTRAN(m.thisparam,'  ',' ')
  8581.                ENDDO
  8582.  
  8583.                * Drop "m." designations so that they don't make the variables look different
  8584.                m.thisparam = STRTRAN(m.thisparam,'m.','')
  8585.                m.thisparam = STRTRAN(m.thisparam,'m->','')
  8586.                
  8587.                RETURN LOWER(m.thisparam)
  8588.             CASE LEFT(m.thisline,5) = "#SECT" AND AT('2',m.thisline) <> 0
  8589.                * No parameter statement, since we found #SECTION 2 first
  8590.                RETURN ""
  8591.             ENDCASE
  8592.             m.i = m.i + 1
  8593.          ENDDO
  8594.       CASE LEFT(m.thisline,1) = "#"   && some other directive
  8595.          * Do nothing.  Get next line.
  8596.       CASE match(wordnum(m.thisline,1),"EXTERNAL")
  8597.          * Ignore it.  This doesn't disqualify a later statement from being a PARAMETER
  8598.          * statement.
  8599.       OTHERWISE
  8600.          * no #SECTION 1, so no parameters
  8601.          RETURN ""
  8602.       ENDCASE
  8603.    ENDIF
  8604.    m.i = m.i + 1
  8605. ENDDO
  8606. RETURN ""
  8607.  
  8608.  
  8609. *!*****************************************************************************
  8610. *!
  8611. *!       Function: MATCH
  8612. *!
  8613. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8614. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  8615. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  8616. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  8617. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8618. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  8619. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  8620. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  8621. *!
  8622. *!*****************************************************************************
  8623. FUNCTION match
  8624. *)
  8625. *) MATCH - Returns TRUE is candidate is a valid 4-or-more-character abbreviation of keyword
  8626. *)
  8627. PARAMETER m.candidate, m.keyword
  8628. PRIVATE m.in_exact, m.retlog
  8629.  
  8630. m.in_exact = SET("EXACT")
  8631. SET EXACT OFF
  8632. DO CASE
  8633. CASE EMPTY(m.candidate)
  8634.    m.retlog = EMPTY(m.keyword)
  8635. CASE LEN(m.candidate) < 4
  8636.    m.retlog = IIF(m.candidate == m.keyword,.T.,.F.)
  8637. OTHERWISE
  8638.    m.retlog = IIF(m.keyword = m.candidate,.T.,.F.)
  8639. ENDCASE
  8640. IF m.in_exact != "OFF"
  8641.    SET EXACT ON
  8642. ENDIF
  8643.  
  8644. RETURN m.retlog
  8645.  
  8646. *!*****************************************************************************
  8647. *!
  8648. *!       Function: WORDNUM
  8649. *!
  8650. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8651. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  8652. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  8653. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  8654. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8655. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  8656. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  8657. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  8658. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  8659. *!
  8660. *!*****************************************************************************
  8661. FUNCTION wordnum
  8662. *)
  8663. *) WORDNUM - Returns w_num-th word from string strg
  8664. *)
  8665. PARAMETERS m.strg,m.w_num
  8666. PRIVATE strg,s1,w_num,ret_str
  8667.  
  8668. m.s1 = ALLTRIM(m.strg)
  8669.  
  8670. * Replace tabs with spaces
  8671. m.s1 = CHRTRAN(m.s1,CHR(9)," ")
  8672.  
  8673. * Reduce multiple spaces to a single space
  8674. DO WHILE AT('  ',m.s1) > 0
  8675.    m.s1 = STRTRAN(m.s1,'  ',' ')
  8676. ENDDO
  8677.  
  8678. ret_str = ""
  8679. DO CASE
  8680. CASE m.w_num > 1
  8681.    DO CASE
  8682.    CASE AT(" ",m.s1,m.w_num-1) = 0   && No word w_num.  Past end of string.
  8683.       m.ret_str = ""
  8684.    CASE AT(" ",m.s1,m.w_num) = 0     && Word w_num is last word in string.
  8685.       m.ret_str = SUBSTR(m.s1,AT(" ",m.s1,m.w_num-1)+1,255)
  8686.    OTHERWISE                         && Word w_num is in the middle.
  8687.       m.strt_pos = AT(" ",m.s1,m.w_num-1)
  8688.       m.ret_str  = SUBSTR(m.s1,strt_pos,AT(" ",m.s1,m.w_num)+1 - strt_pos)
  8689.    ENDCASE
  8690. CASE m.w_num = 1
  8691.    IF AT(" ",m.s1) > 0               && Get first word.
  8692.       m.ret_str = SUBSTR(m.s1,1,AT(" ",m.s1)-1)
  8693.    ELSE                              && There is only one word.  Get it.
  8694.       m.ret_str = m.s1
  8695.    ENDIF
  8696. ENDCASE
  8697. RETURN ALLTRIM(m.ret_str)
  8698.  
  8699.  
  8700. *!*****************************************************************************
  8701. *!
  8702. *!       Function: GETCNAME
  8703. *!
  8704. *!      Called by: SETCLAUSEFLAGS     (procedure in GENSCRN.PRG)
  8705. *!               : ORCLAUSEFLAGS      (procedure in GENSCRN.PRG)
  8706. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  8707. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  8708. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  8709. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  8710. *!
  8711. *!*****************************************************************************
  8712. FUNCTION getcname
  8713. *) GETCNAME - Generates a name for a clause.  Will take name from a
  8714. *)              generator directive stored in a snippet if present,
  8715. *)              or generates a generic name otherwise.  The name is
  8716. *)              designated by a #NAME name directive
  8717. *)
  8718. PARAMETERS m.snippet
  8719. PRIVATE dirname
  8720. IF ATC("#NAME",m.snippet) > 0
  8721.    m.dirname = MLINE(m.snippet, ATCLINE('#NAME',m.snippet))
  8722.    DO killcr WITH m.dirname
  8723.    m.dirname = UPPER(ALLTRIM(SUBSTR(m.dirname,AT(' ',m.dirname)+1)))
  8724.    IF !EMPTY(m.dirname)
  8725.       RETURN m.dirname
  8726.    ENDIF
  8727. ENDIF
  8728. RETURN LOWER(SYS(2015))
  8729.  
  8730. *!*****************************************************************************
  8731. *!
  8732. *!      Procedure: NOTEAREA
  8733. *!
  8734. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  8735. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  8736. *!
  8737. *!*****************************************************************************
  8738. PROCEDURE notearea
  8739. *)
  8740. *) NOTEAREA - Note that we are using this area so that we can clean up at exit
  8741. *)
  8742. g_areas[m.g_areacount] = SELECT()
  8743. m.g_areacount = m.g_areacount + 1
  8744. RETURN
  8745.  
  8746. *!*****************************************************************************
  8747. *!
  8748. *!      Procedure: CLEARAREAS
  8749. *!
  8750. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  8751. *!
  8752. *!*****************************************************************************
  8753. PROCEDURE clearareas
  8754. *)
  8755. *) CLEARAREAS - Clear the ones we opened.
  8756. *)
  8757. FOR i = 1 TO m.g_areacount
  8758.    SELECT g_areas[m.i]
  8759.    USE
  8760. ENDFOR
  8761. RETURN
  8762.  
  8763. *!*****************************************************************************
  8764. *!
  8765. *!      Procedure: INITTICK
  8766. *!
  8767. *!      Called by: GENSCRN.PRG
  8768. *!
  8769. *!*****************************************************************************
  8770. PROCEDURE inittick
  8771. *)
  8772. *) INITTICK, TICK, and TOCK - Profiling functions
  8773. *)
  8774. IF TYPE("ticktock") = "U"
  8775.    PUBLIC ticktock[10]
  8776. ENDIF
  8777. ticktock = 0
  8778. RETURN 
  8779.  
  8780. *!*****************************************************************************
  8781. *!
  8782. *!       Function: TICK
  8783. *!
  8784. *!      Called by: GENSCRN.PRG
  8785. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8786. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8787. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  8788. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  8789. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8790. *!
  8791. *!*****************************************************************************
  8792. FUNCTION tick
  8793. *)
  8794. *) INITTICK, TICK, and TOCK - Profiling functions
  8795. *)
  8796. PARAMETER m.bucket
  8797. ticktock[bucket] = ticktock[bucket] - SECONDS()
  8798. RETURN 
  8799.  
  8800. *!*****************************************************************************
  8801. *!
  8802. *!       Function: TOCK
  8803. *!
  8804. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  8805. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8806. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8807. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  8808. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  8809. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8810. *!
  8811. *!*****************************************************************************
  8812. FUNCTION tock
  8813. *)
  8814. *) INITTICK, TICK, and TOCK - Profiling functions
  8815. *)
  8816. PARAMETER m.bucket
  8817. ticktock[bucket] = ticktock[bucket] + SECONDS()
  8818. RETURN 
  8819.  
  8820. *!*****************************************************************************
  8821. *!
  8822. *!      Procedure: PUTMSG
  8823. *!
  8824. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8825. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8826. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8827. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8828. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8829. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8830. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8831. *!
  8832. *!*****************************************************************************
  8833. PROCEDURE putmsg
  8834. *)
  8835. *) Display a status message on the status bar at the bottom of the screen
  8836. *)
  8837. PARAMETER m.msg
  8838. IF m.g_graphic
  8839.    SET MESSAGE TO msg
  8840. ENDIF
  8841.  
  8842. *!*****************************************************************************
  8843. *!
  8844. *!       Function: VERSIONCAP
  8845. *!
  8846. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8847. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8848. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8849. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8850. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8851. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  8852. *!
  8853. *!*****************************************************************************
  8854. FUNCTION versioncap
  8855. *)
  8856. *) VERSIONCAP - Return platform name suitable for display
  8857. *)
  8858. PARAMETER m.strg, m.dual
  8859. DO CASE
  8860. CASE m.strg = "DOS"
  8861.    m.retstrg = "MS-DOS"
  8862.     IF m.dual
  8863.        m.retstrg = m.retstrg + " and UNIX"
  8864.     ENDIF
  8865. CASE m.strg = "WINDOWS"
  8866.    m.retstrg = "Windows"
  8867.     IF m.dual
  8868.        m.retstrg = m.retstrg + " and Macintosh"
  8869.     ENDIF
  8870. CASE m.strg = "MAC"
  8871.    m.retstrg = "Macintosh"
  8872.     IF m.dual
  8873.        m.retstrg = m.retstrg + " and Windows"
  8874.     ENDIF
  8875. CASE m.strg = "UNIX"
  8876.    m.retstrg = "UNIX"
  8877.     IF m.dual
  8878.        m.retstrg = m.retstrg + " and MS-DOS"
  8879.     ENDIF
  8880. OTHERWISE
  8881.    m.retstrg = m.strg
  8882. ENDCASE
  8883. RETURN m.retstrg
  8884.  
  8885. *!*****************************************************************************
  8886. *!
  8887. *!       Function: MULTIPLAT
  8888. *!
  8889. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8890. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8891. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8892. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8893. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8894. *!
  8895. *!*****************************************************************************
  8896. FUNCTION multiplat
  8897. *)
  8898. *) MULTIPLAT - Returns TRUE if we are generating for multiple platforms
  8899. *)
  8900. RETURN IIF(m.g_allplatforms AND m.g_numplatforms > 1, .T. , .F.)
  8901.  
  8902. *!*****************************************************************************
  8903. *!
  8904. *!      Procedure: SEEKHEADER
  8905. *!
  8906. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  8907. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8908. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8909. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8910. *!               : GENRELATIONS       (procedure in GENSCRN.PRG)
  8911. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8912. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  8913. *!
  8914. *!*****************************************************************************
  8915. PROCEDURE seekheader
  8916. *)
  8917. *) SEEKHEADER - Find the header for this screen/platform
  8918. *)
  8919. PARAMETER m.i
  8920. IF g_screens[m.i,6]
  8921.    GO TOP
  8922. ELSE
  8923.    LOCATE FOR platform = g_screens[m.i,7] AND objtype = c_otscreen
  8924. ENDIF
  8925. RETURN 
  8926.  
  8927. *!*****************************************************************************
  8928. *!
  8929. *!       Function: GETPLATNAME
  8930. *!
  8931. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  8932. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8933. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8934. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8935. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  8936. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  8937. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  8938. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  8939. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  8940. *!
  8941. *!*****************************************************************************
  8942. FUNCTION getplatname
  8943. *)
  8944. *) GETPLATNAME - Return the platform for a screen
  8945. *)
  8946. PARAMETER m.plnum
  8947. IF g_screens[m.plnum,6]
  8948.    RETURN "DOS"
  8949. ELSE
  8950.    RETURN platform
  8951. ENDIF
  8952. RETURN 
  8953.  
  8954.  
  8955. *!*****************************************************************************
  8956. *!
  8957. *!      Procedure: INSERTFILE
  8958. *!
  8959. *!      Called by: GENINSERTCODE      (procedure in GENSCRN.PRG)
  8960. *!
  8961. *!          Calls: WRITECODE          (procedure in GENSCRN.PRG)
  8962. *!
  8963. *!*****************************************************************************
  8964. PROCEDURE insertfile
  8965. PARAMETER m.incfn, m.scrnno, m.insetup, m.platname
  8966. PRIVATE m.oldals, m.insdbfname, m.oldmline, m.fptname
  8967.  
  8968. * Search for the file in the current directory, along the FoxPro path, and along
  8969. * the DOS path.
  8970. IF !FILE(m.incfn)
  8971.    DO CASE
  8972.    CASE FILE(FULLPATH(m.incfn))
  8973.       m.incfn = FULLPATH(m.incfn)
  8974.    CASE FILE(FULLPATH(m.incfn,1))
  8975.       m.incfn = FULLPATH(m.incfn,1)
  8976.    ENDCASE
  8977. ENDIF
  8978.  
  8979. IF FILE((m.incfn))
  8980.    m.oldals = ALIAS()
  8981.    m.insdbfname = SYS(3)+".DBF"
  8982.    m.oldmline = _MLINE
  8983.  
  8984.    * The following lines create a temporary file with a single memo field
  8985.    * and appends the inserted file into the memo field. Effectively creating
  8986.    * a code snippet. This allows the standard procedure for generating code
  8987.    * snippets to be call to process the inserted file. This in turn allows
  8988.    * the include file to contain generator directives.
  8989.    CREATE TABLE (m.insdbfname) (inscode m)
  8990.    APPEND BLANK
  8991.    APPEND MEMO inscode FROM (m.incfn)
  8992.  
  8993.    \** Start of inserted file <<m.incfn>> <<REPLICATE(m.g_horiz,32)+"start">>
  8994.  
  8995.    * Make a recursive call to the standard snippet generation procedure
  8996.    DO writecode WITH inscode, m.platname, 1, 0, m.scrnno, m.insetup
  8997.  
  8998.    \** End of inserted file <<m.incfn>> <<REPLICATE(m.g_horiz,36)+"end">>
  8999.    \
  9000.  
  9001.    USE
  9002.    DELETE FILE (m.insdbfname)
  9003.    m.fptname = forceext(m.insdbfname,"FPT")
  9004.    IF FILE(m.fptname)
  9005.       DELETE FILE (m.fptname)
  9006.    ENDIF
  9007.    
  9008.    SELECT (m.oldals)
  9009.    _MLINE=oldmline
  9010. ELSE
  9011.    \*
  9012.    \* Inserted file <<m.incfn>> not found!
  9013.    \*
  9014. ENDIF
  9015. RETURN
  9016.  
  9017. *!*****************************************************************************
  9018. *!
  9019. *!      Function: VERSNUM
  9020. *!
  9021. *!*****************************************************************************
  9022. FUNCTION versnum
  9023. * Return string corresponding to FoxPro version number
  9024. RETURN wordnum(vers(),2)
  9025.  
  9026.  
  9027. *!*****************************************************************************
  9028. *!
  9029. *!      Function: SHOWSTAT
  9030. *!
  9031. *!*****************************************************************************
  9032. PROCEDURE showstat
  9033. PARAMETER m.strg
  9034. WAIT WINDOW m.strg NOWAIT
  9035. RETURN 
  9036.  
  9037. *!*****************************************************************************
  9038. *!
  9039. *!      Function: KILLCR
  9040. *!
  9041. *!*****************************************************************************
  9042. PROCEDURE killcr
  9043. PARAMETER m.strg
  9044. IF _MAC
  9045.    m.strg = CHRTRAN(m.strg,CHR(13)+CHR(10),"")
  9046. ENDIF
  9047. RETURN 
  9048.  
  9049. *!*****************************************************************************
  9050. *!
  9051. *!      Function: ASSERT
  9052. *!
  9053. *!*****************************************************************************
  9054. FUNCTION assert
  9055. PARAMETER m.bool, m.strg
  9056. IF !m.bool
  9057.    WAIT WINDOW m.strg
  9058. ENDIF
  9059.  
  9060. *!*****************************************************************************
  9061. *!
  9062. *!      Function: BITMAPSTR
  9063. *!
  9064. *!*****************************************************************************
  9065. FUNCTION bitmapstr
  9066. * Return a string of bitmap file extensions, suitable for LOCFILE, etc.
  9067. PARAMETER whichone
  9068. DO CASE
  9069. CASE whichone = c_all AND _MAC
  9070.    RETURN '"'+m.g_picext+"|"+m.g_bmpext+"|"+m.g_icnext+"|"+m.g_icoext+'"'
  9071. CASE whichone = c_all AND !_MAC
  9072.    RETURN '"'+m.g_bmpext+"|"+m.g_icoext+"|"+m.g_picext+"|"+m.g_icnext+'"'
  9073. OTHERWISE
  9074.    RETURN '"'+IIF(_MAC,m.g_picext,m.g_bmpext)+'"'
  9075. ENDCASE
  9076.  
  9077. *!*****************************************************************************
  9078. *!
  9079. *!      Function: ICONSTR
  9080. *!
  9081. *!*****************************************************************************
  9082. FUNCTION iconstr
  9083. DO CASE
  9084. CASE _MAC
  9085.     RETURN m.g_icnext
  9086. OTHERWISE
  9087.     RETURN m.g_icoext
  9088. ENDCASE
  9089.  
  9090. *!*****************************************************************************
  9091. *!
  9092. *!      Function: STYLE2NUM
  9093. *!
  9094. *!*****************************************************************************
  9095. FUNCTION style2num
  9096. * Translate a font style string to its equivalent numerical representation
  9097. PARAMETER m.strg
  9098. PRIVATE m.i, m.num
  9099. m.num = 0
  9100. m.strg= UPPER(ALLTRIM(m.strg))
  9101. FOR m.i = 1 TO LEN(m.strg)
  9102.    DO CASE
  9103.    CASE SUBSTR(m.strg,i,1) = "B"      && bold
  9104.       m.num = m.num + 1
  9105.    CASE SUBSTR(m.strg,i,1) = "I"         && italic
  9106.       m.num = m.num + 2
  9107.    CASE SUBSTR(m.strg,i,1) = "U"      && underlined
  9108.       m.num = m.num + 4
  9109.    CASE SUBSTR(m.strg,i,1) = "O"      && outline
  9110.       m.num = m.num + 8
  9111.    CASE SUBSTR(m.strg,i,1) = "S"      && shadow
  9112.       m.num = m.num + 16
  9113.    CASE SUBSTR(m.strg,i,1) = "C"         && condensed
  9114.       m.num = m.num + 32
  9115.    CASE SUBSTR(m.strg,i,1) = "E"      && extended
  9116.       m.num = m.num + 64
  9117.    CASE SUBSTR(m.strg,i,1) = "-"      && strikeout
  9118.       m.num = m.num + 128
  9119.    ENDCASE
  9120. ENDFOR
  9121. RETURN m.num
  9122.  
  9123. *!*****************************************************************************
  9124. *!
  9125. *!      Function: NUM2STYLE
  9126. *!
  9127. *!*****************************************************************************
  9128. FUNCTION num2style
  9129. * Translate a font style number to its equivalent string representation
  9130. PARAMETER m.num
  9131. PRIVATE m.i, m.strg, m.pow, m.stylechars, m.outstrg
  9132. m.strg = ""
  9133. * These are the style characters.  Their position in the string matches the bit 
  9134. * position in the num byte.
  9135. m.stylechars = "BIUOSCE-"
  9136.  
  9137. * Look at each of the bits in the num byte
  9138. FOR m.i = 8 TO 1 STEP -1
  9139.    m.pow = ROUND(2^(i-1),0)  
  9140.     IF m.num >= m.pow
  9141.        m.strg = m.strg + SUBSTR(stylechars,m.i,1)
  9142.     ENDIF
  9143.     m.num = m.num % m.pow
  9144. ENDFOR
  9145.  
  9146. * Now reverse the string so that style codes appear in the traditional order
  9147. m.outstrg = ""
  9148. FOR m.i = 1 TO LEN(m.strg)
  9149.    m.outstrg = m.outstrg + SUBSTR(m.strg,LEN(m.strg)+1-m.i,1)
  9150. ENDFOR
  9151. RETURN m.outstrg
  9152.  
  9153.  
  9154. FUNCTION ctrlclause
  9155. PARAMETER m.pictstrg
  9156. * Return the control portion of a picture string
  9157. m.pictstrg = LTRIM(m.pictstrg)
  9158. m.spos = AT(' ',m.pictstrg)
  9159. IF m.spos > 1
  9160.     IF INLIST(LEFT(m.pictstrg,1),'"',"'")
  9161.        m.pictstrg = STRTRAN(m.pictstrg,LEFT(m.pictstrg,1),"")
  9162.     ENDIF
  9163.    RETURN ALLTRIM(LEFT(m.pictstrg,m.spos - 1))
  9164. ELSE
  9165.    RETURN m.pictstrg
  9166. ENDIF
  9167.  
  9168.  
  9169. *: EOF: GENSCRN.PRG
  9170.