home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a093 / 3.ddi / GENSCRN.PR_ / GENSCRN.bin
Encoding:
Text File  |  1993-01-17  |  270.6 KB  |  8,615 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. *:  Procs & Fncts: INITTICK
  10. *:               : TICK()
  11. *:               : ERRORHANDLER
  12. *:               : SETALL
  13. *:               : OPENPROJDBF()
  14. *:               : PREPSCREENS()
  15. *:               : PREPPLATFORM
  16. *:               : BUILD
  17. *:               : CLEANUP
  18. *:               : CLEANSCRN
  19. *:               : BUILDENABLE
  20. *:               : BUILDDISABLE
  21. *:               : PREPPARAMS
  22. *:               : CLEANPARAM()
  23. *:               : CHECKPARAM()
  24. *:               : PREPFILE
  25. *:               : CLOSEFILE
  26. *:               : NEWWINDOWS()
  27. *:               : NEWDBFS()
  28. *:               : NEWREADCLAUSES
  29. *:               : GETPLATFORM()
  30. *:               : PREPWNAMES
  31. *:               : SCREENUSED()
  32. *:               : ILLEGALNAME()
  33. *:               : GETWITHLIST
  34. *:               : REFRESHPREFS
  35. *:               : SUBDEVINFO()
  36. *:               : DISPATCHBUILD
  37. *:               : BUILDCTRL
  38. *:               : GENSETENVIRON
  39. *:               : GENCLNENVIRON
  40. *:               : GENCLEANUP
  41. *:               : GENPROCEDURES
  42. *:               : PROCSMATCH()
  43. *:               : ISGENPLAT()
  44. *:               : PUTPROCHEAD
  45. *:               : EXTRACTPROCS
  46. *:               : EMITPROC
  47. *:               : EMITBRACKET
  48. *:               : PUTPROC
  49. *:               : GETPROCNUM()
  50. *:               : HASCONFLICT()
  51. *:               : GETFIRSTPROC()
  52. *:               : SCANPROC
  53. *:               : UPDPROCARRAY
  54. *:               : ADDPROCNAME
  55. *:               : GETPLATNUM()
  56. *:               : GENPARAMETER
  57. *:               : GENSECT1
  58. *:               : GENSECT2
  59. *:               : COUNTDIRECTIVES()
  60. *:               : NOTEDIRECTIVES
  61. *:               : FINDSECTION()
  62. *:               : WRITECODE
  63. *:               : WRITELINE
  64. *:               : GENINSERTCODE
  65. *:               : ISPARAMETER()
  66. *:               : ATWNAME()
  67. *:               : ISCOMMENT()
  68. *:               : GENCLAUSECODE
  69. *:               : VALICLAUSE
  70. *:               : GENVALIDBODY
  71. *:               : WHENCLAUSE
  72. *:               : GENWHENBODY
  73. *:               : ACTICLAUSE
  74. *:               : DEATCLAUSE
  75. *:               : SHOWCLAUSE
  76. *:               : PLACESAYS
  77. *:               : GENCLOSEDBFS
  78. *:               : GENOPENDBFS
  79. *:               : UNIQUEDBF()
  80. *:               : GENUSESTMTS
  81. *:               : FINDRELPATH()
  82. *:               : GENORDER
  83. *:               : GENINDEXES()
  84. *:               : GENRELATIONS
  85. *:               : GENRELSTMTS
  86. *:               : BUILDFMT
  87. *:               : ANYWINDOWS
  88. *:               : GENACTISTMTS
  89. *:               : PLACEREAD
  90. *:               : ANYMODAL
  91. *:               : ANYLOCK
  92. *:               : GENWITHCLAUSE
  93. *:               : DOPLACECLAUSE
  94. *:               : FINDREADCLAUSES
  95. *:               : SETCLAUSEFLAGS
  96. *:               : ORCLAUSEFLAGS
  97. *:               : GENREADCLAUSES
  98. *:               : GENCLAUSE
  99. *:               : GENGIVENREAD
  100. *:               : GENDIRECTIVE
  101. *:               : SKIPWHITESPACE()
  102. *:               : DEFPOPUPS
  103. *:               : GENPOPDEFI
  104. *:               : RELPOPUPS
  105. *:               : DEFWINDOWS
  106. *:               : GENDESKTOP
  107. *:               : GENWINDEFI
  108. *:               : GETARRANGE
  109. *:               : GENBOXES
  110. *:               : GENLINES
  111. *:               : GENTEXT
  112. *:               : GENFIELDS
  113. *:               : GENINVBUT
  114. *:               : GENTXTRGN
  115. *:               : GENPUSH
  116. *:               : GENRADBUT
  117. *:               : GENCHKBOX
  118. *:               : GENLIST
  119. *:               : GENPICTURE
  120. *:               : GENSPINNER
  121. *:               : FROMPOPUP
  122. *:               : GENPOPUP
  123. *:               : ELEMRANGE
  124. *:               : GENACTWINDOW
  125. *:               : GENDEFAULT
  126. *:               : ANYBITMAPCTRL
  127. *:               : CHOPPICTURE
  128. *:               : ANYDISABLED
  129. *:               : ANYPICTURE
  130. *:               : ANYSCROLL
  131. *:               : ANYTAB
  132. *:               : ANYFONT
  133. *:               : ANYSTYLE
  134. *:               : ANYPATTERN
  135. *:               : ANYSCHEME
  136. *:               : ANYPEN
  137. *:               : ANYVALID
  138. *:               : ANYTITLEORFOOTER
  139. *:               : ANYWHEN
  140. *:               : ANYMESSAGE
  141. *:               : ANYERROR
  142. *:               : ANYFILL
  143. *:               : ANYWINDOWCHARS
  144. *:               : ANYBORDER
  145. *:               : ANYWALLPAPER
  146. *:               : ANYICON
  147. *:               : WINDOWFROMTO
  148. *:               : HEADER
  149. *:               : GENFUNCHEADER
  150. *:               : COMMENTBLOCK
  151. *:               : PROCCOMMENTBLOCK
  152. *:               : GENCOMMENT
  153. *:               : BASENAME()
  154. *:               : STRIPEXT()
  155. *:               : STRIPPATH()
  156. *:               : STRIPCR()
  157. *:               : ADDBS()
  158. *:               : JUSTFNAME()
  159. *:               : JUSTPATH()
  160. *:               : FORCEEXT()
  161. *:               : WHATSTYLE()
  162. *:               : UNIQUEWIN()
  163. *:               : ADDTOCTRL
  164. *:               : OKTOGENERATE()
  165. *:               : OBJECT()
  166. *:               : COMBINE
  167. *:               : ACTTHERM
  168. *:               : UPDTHERM
  169. *:               : DEACTTHERMO
  170. *:               : ESCHANDLER
  171. *:               : ERRLOG
  172. *:               : ERRSHOW
  173. *:               : OPENERRFILE
  174. *:               : PUSHINDENT
  175. *:               : POPINDENT
  176. *:               : COUNTPLATFORMS
  177. *:               : LOOKUPPLATFORM
  178. *:               : GETPARAM()
  179. *:               : MATCH()
  180. *:               : WORDNUM()
  181. *:               : GETCNAME()
  182. *:               : NOTEAREA
  183. *:               : CLEARAREAS
  184. *:               : TOCK()
  185. *:               : PUTMSG
  186. *:               : VERSIONCAP()
  187. *:               : MULTIPLAT()
  188. *:               : SEEKHEADER
  189. *:               : GETPLATNAME()
  190. *:               : INSERTFILE
  191. *:
  192. *:          Calls: INITTICK           (procedure in GENSCRN.PRG)
  193. *:               : TICK()             (function  in GENSCRN.PRG)
  194. *:               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  195. *:               : SETALL             (procedure in GENSCRN.PRG)
  196. *:               : OPENPROJDBF()      (function  in GENSCRN.PRG)
  197. *:               : PREPSCREENS()      (function  in GENSCRN.PRG)
  198. *:               : PREPPLATFORM       (procedure in GENSCRN.PRG)
  199. *:               : BUILD              (procedure in GENSCRN.PRG)
  200. *:               : CLEANUP            (procedure in GENSCRN.PRG)
  201. *:
  202. *:      Documented              FoxDoc version 3.00a
  203. *:*****************************************************************************
  204. *
  205. * GENSCRN - Screen Code Generator.
  206. *
  207. * Copyright (c) 1990 - 1993 Microsoft Corp.
  208. * One Microsoft Way
  209. * Redmond, WA 98502
  210. *
  211. * Description:
  212. * This program generates code for objects designed and built with
  213. * FoxPro screen builder.
  214. *
  215. * Notes:
  216. * In this program, for clarity/readability reasons, we use variable
  217. * names that are longer than 10 characters.  Note, however, that only
  218. * the first 10 characters are significant.
  219. *
  220. PARAMETER m.projdbf, m.recno
  221. PRIVATE ALL
  222.  
  223. IF SET("TALK") = "ON"
  224.    SET TALK OFF
  225.    m.talkset = "ON"
  226. ELSE
  227.    m.talkset = "OFF"
  228. ENDIF
  229.  
  230. m.escape = SET("ESCAPE")
  231. ON ESCAPE
  232. SET ESCAPE OFF
  233. m.trbetween = SET("TRBET")
  234. SET TRBET OFF
  235. m.comp = SET("COMPATIBLE")
  236. SET COMPATIBLE FOXPLUS
  237. mdevice = SET("DEVICE")
  238. SET DEVICE TO SCREEN
  239.  
  240. *
  241. * Declare Global Constants
  242. *
  243. #DEFINE c_otscreen         1
  244. #DEFINE c_otworkarea       2
  245. #DEFINE c_otindex          3
  246. #DEFINE c_otrel               4
  247. #DEFINE c_ottext           5
  248. #DEFINE c_otline           6
  249. #DEFINE c_otbox            7
  250. #DEFINE c_otlist          11
  251. #DEFINE c_ottxtbut        12
  252. #DEFINE c_otradbut        13
  253. #DEFINE c_otchkbox        14
  254. #DEFINE c_otfield         15
  255. #DEFINE c_otpopup         16
  256. #DEFINE c_otpicture       17
  257. #DEFINE c_otinvbut        20
  258. #DEFINE c_otspinner       22
  259.  
  260. #DEFINE c_authorlen       45
  261. #DEFINE c_complen         45
  262. #DEFINE c_addrlen         45
  263. #DEFINE c_citylen         20
  264. #DEFINE c_statlen          5
  265. #DEFINE c_ziplen          10
  266. #DEFINE c_countrylen      40
  267.  
  268. #DEFINE c_sgsay            0
  269. #DEFINE c_sgget            1
  270. #DEFINE c_sgedit           2
  271. #DEFINE c_sgfrom           3
  272. #DEFINE c_sgbox            4
  273. #DEFINE c_sgboxd           5
  274. #DEFINE c_sgboxp           6
  275. #DEFINE c_sgboxc           7
  276.  
  277. * Determines whether SHOW snippets are checked for suspicious SHOW GETS statements
  278. #DEFINE c_checkshow        1
  279.  
  280. #DEFINE c_maxwinds        25
  281. #DEFINE c_maxpops         25
  282. #DEFINE c_maxscreens       5
  283. #DEFINE c_maxplatforms     4
  284. #DEFINE c_20scxflds          57
  285. #DEFINE c_scxflds         79
  286. #DEFINE c_pjxflds         31
  287. #DEFINE c_pjx20flds       33
  288.  
  289. #DEFINE c_esc            CHR(27)
  290. #DEFINE c_null            CHR(0)
  291. #DEFINE c_cret            CHR(13)
  292. #DEFINE c_under            "_"
  293. #DEFINE c_single        "┌─┐│┘─└│"
  294. #DEFINE c_double        "╔═╗║╝═╚║"
  295. #DEFINE c_panel            "████████"
  296. #DEFINE c_fromone        1
  297. #DEFINE c_untilend        0
  298.  
  299. #DEFINE c_error_1        "Minor"
  300. #DEFINE c_error_2        "Serious"
  301. #DEFINE c_error_3        "Fatal"
  302.  
  303. #DEFINE c_dlgface        "MS Sans Serif"
  304. #DEFINE c_dlgsize        8.000
  305. #DEFINE c_dlgstyle        "B"
  306.  
  307. #DEFINE c_genexpr    0
  308. #DEFINE c_gencode    1
  309. #DEFINE c_genboth    -1
  310. m.g_genparams = PARAMETERS()
  311. DO inittick
  312. *
  313. * Declare Variables
  314. *
  315. STORE "" TO m.cursor, m.consol, m.bell, m.exact, ;
  316.    m.safety, m.fixed, m.print, m.delimiters, m.unique, mudfparms, ;
  317.    m.fields, mfieldsto, m.mdecpoint, m.origpretext
  318. STORE 0 TO m.deci, m.memowidth
  319.  
  320. m.g_closefiles = .F.           && Generate code to close files?
  321. m.g_current    = ""            && current DBF
  322. m.g_defasch1   = 0               && Default color scheme 1
  323. m.g_defasch2   = 0               && Default color scheme 2
  324. m.g_defwin     = .F.           && Generate code to define windows?
  325. m.g_errlog     = ""               && Path + name of .ERR file
  326. m.g_homedir    = ""               && Application Home Directory
  327. m.g_idxfile    = 'idxfile.idx' && Index file
  328. m.g_itse       = c_null           && Designating character from #ITSEXPRESSION
  329. m.g_lastwindow = ""            && Name of last window defined
  330. m.g_keyno      = 0
  331. m.g_havehand = .F.
  332. m.g_redefi     = .F.           && Don't redefine windows
  333. m.g_screen     = 0             && Screen currently being generated.  Also used in error messages.
  334. m.g_nscreens   = 0             && Number of screens
  335. m.g_nwindows   = 0             && Number of unique windows in this platform
  336. m.g_multreads  = .F.           && Multiple reads?
  337. m.g_openfiles  = .F.           && Generate code to open files?
  338. m.g_orghandle  = -1            && File handle for ctrl file
  339. m.g_outfile    = ""            && Output file name
  340. m.g_projalias  = ""            && Project database alias
  341. m.g_projpath   = ""
  342. m.g_rddir      = .F.           && Is there a #READCLAUSES directive?
  343. m.g_windclauses= ""            && #WCLAUSES parameters for DEFINE WINDOW
  344. m.g_rddirno    = 0             && Number of 1st screen with #READ directive
  345. m.g_readcycle  = .F.           && READ CYCLE?
  346. m.g_readlock   = .F.           && READ LOCK/NOLOCK?
  347. m.g_readmodal  = .F.           && READ MODAL?
  348. m.g_readborder = .F.           && READ BORDER?
  349. m.g_relwin     = .F.           && Generate code to release windows?
  350. m.g_moddesktop = .F.
  351. m.g_snippcnt   = 0             && Count of snippets
  352. m.g_somepops   = .F.           && Any Generated popups?
  353. m.g_status     = 0
  354. m.g_thermwidth = 0             && Thermometer width
  355. m.g_tmpfile    = SYS(3)+".tmp" && Temporary file
  356. m.g_tmphandle  = -1            && File handle for tmp file
  357. m.g_windows    = .F.           && Any windows in screen files?
  358. m.g_withlist   = ""
  359. m.g_workarea   = 0
  360. m.g_genvers       = ""            && version we are generating for
  361. m.g_thisvers   = ""            && version we are running under now
  362. m.g_graphic    = .F.
  363. m.g_isfirstproc= .T.           && is this the first procedure emitted?
  364. m.g_procsmatch = .F.           && are cleanup snippets for all platforms identical
  365. m.g_noread     = .F.           && omit the read statement?
  366. m.g_noreadplain= .F.           && omit the read statement and the SET TALK TO.. statements?
  367.  
  368. m.g_boxstrg = ['─','─','│','│','┌','┐','└','┘','─','─','│','│','┌','┐','└','┘']
  369.  
  370. m.g_validtype  = ""
  371. m.g_validname  = ""
  372. m.g_whentype   = ""
  373. m.g_whenname   = ""
  374. m.g_actitype   = ""
  375. m.g_actiname   = ""
  376. m.g_deattype   = ""
  377. m.g_deatname   = ""
  378. m.g_showtype   = ""
  379. m.g_showname   = ""
  380. m.g_showexpr   = ""
  381.  
  382. m.g_sect1start = 0
  383. m.g_sect2start = 0
  384.  
  385. m.g_devauthor  = PADR("Author's Name",45," ")
  386. m.g_devcompany = PADR("Company Name",45, " ")
  387. m.g_devaddress = PADR("Address",45," ")
  388. m.g_devcity    = PADR("City",20," ")
  389. m.g_devstate   = "  "
  390. m.g_devzip     = PADR("Zip",10," ")
  391. m.g_devctry    = PADR("Country",40, " ")
  392.  
  393. m.g_allplatforms = .T.            && generate for all platforms in the SCX?
  394. m.g_numplatforms = 1              && number of platforms we are generating for
  395. m.g_parameter    = ""             && the parameter statement for this SPR
  396. m.g_areacount    = 1              && index into g_areas to count workareas we use
  397. m.g_dblampersand = CHR(38) + CHR(38)   && used in some tight loops.  Concatenate just once here.
  398.  
  399. DO CASE
  400. CASE AT("WINDOWS", UPPER(VERSION())) <> 0
  401.    m.g_thisvers = "WINDOWS"
  402.    m.g_graphic  = .T.
  403. CASE AT("MAC", UPPER(VERSION())) <> 0
  404.    m.g_thisvers = "MAC"
  405.    m.g_graphic  = .T.
  406. CASE AT("UNIX", UPPER(VERSION())) <> 0
  407.    m.g_thisvers = "UNIX"
  408.    m.g_graphic  = .F.
  409. CASE AT("FOXPRO", UPPER(VERSION())) <> 0
  410.    m.g_thisvers = "DOS"
  411.    m.g_graphic  = .F.
  412. OTHERWISE
  413.    DO errorhandler WITH "Unknown FoxPro platform",LINENO(),c_error_3
  414. ENDCASE
  415.  
  416. STORE "" TO m.g_corn1, m.g_corn2, m.g_corn3, m.g_corn4, m.g_corn5, ;
  417.    m.g_corn6, m.g_verti2
  418. STORE "*" TO  m.g_horiz, m.g_verti1
  419.  
  420. * This array stores the names of the DBFs in the environment for this platform
  421. DIMENSION g_dbfs[1]
  422. g_dbfs = ""
  423.  
  424. * If you add arrays that are based on C_MAXSCREENS, remember to check PrepScreens().
  425. * You'll probably need to add the array name there so that if the number of screens
  426. * exceeds C_MAXSCREENS, your array gets expanded too.
  427.  
  428. *    generated popup names associated with scollable lists.
  429. *
  430. *    g_popups[*,1] - screen basename
  431. *    g_popups[*,2] - record number
  432. *    g_popups[*,3] - generated popup name
  433. *
  434. DIMENSION g_popups[C_MAXPOPS,3]
  435. g_popups = ""
  436.  
  437. *     screen file name array definition
  438. *
  439. *     g_screens[*,1] - screen fully qualified name
  440. *     g_screens[*,2] - window name if any
  441. *     g_screens[*,3] - recno in proj dbf
  442. *    g_screens[*,4] - initially opened?
  443. *    g_screens[*,5] - alias
  444. *    g_screens[*,6] - 2.0 screen file?
  445. *    g_screens[*,7] - Platform to generate from
  446. *
  447. DIMENSION g_screens[C_MAXSCREENS,7]
  448. g_screens = ""
  449.  
  450. * Array to store window stack.
  451. * g_wndows[*,1]  - Window name
  452. * g_wndows[*,2]  - Window sequence
  453. DIMENSION g_wndows[C_MAXWINDS,2]
  454. g_wndows = ""
  455.  
  456. * Store the substitution string for window names
  457. DIMENSION g_wnames[C_MAXSCREENS, C_MAXPLATFORMS]
  458. g_wnames = ""
  459.  
  460. * g_platforms holds a list of platforms in common among all screens
  461. DIMENSION g_platforms[C_MAXSCREENS]
  462. g_platforms = ""
  463.  
  464. * g_platprocs is a parallel array to g_platforms.  It holds the name
  465. * of the procedure to contain the setup snippet and all the @SAYs 
  466. * and @GETs for the corresponding platform.
  467. DIMENSION g_platproc[C_MAXSCREENS]
  468. g_platproc = ""
  469.  
  470. * g_areas holds a list of areas we opened files in during this gen and that
  471. * we need to close on exit.
  472. DIMENSION g_areas[256]
  473. g_areas = 0
  474.  
  475. * g_firstproc holds the line number of the first PROCEDURE or FUNCTION in
  476. * the cleanup snippet of each screen.
  477. DIMENSION g_firstproc[C_MAXSCREENS]
  478. g_firstproc = 0
  479.  
  480. DIMENSION g_platlist[C_MAXPLATFORMS]
  481. g_platlist[1] = "DOS"
  482. g_platlist[2] = "WINDOWS"
  483. g_platlist[3] = "MAC"
  484. g_platlist[4] = "UNIX"
  485.  
  486. DIMENSION g_procs[1,C_MAXPLATFORMS+3]
  487. * First column is a procedure name
  488. * Second through n-th column is the line number in the cleanup snippet where
  489. *    a procedure with this name starts.
  490. * C_MAXPLATFORMS+2 column is a 1 if this procedure has been emitted.
  491. * C_MAXPLATFORMS+3 column holds the parameter statement, if any.
  492. * One row for each unique procedure name found in the cleanup snippet for any platform.
  493. g_procs = -1
  494. g_procs[1,1] = ""
  495. g_procs[1,C_MAXPLATFORMS+3] = ""
  496. g_procnames = 0   && the number we've found so far
  497.  
  498. ** formfeed
  499. **
  500. ** Main program
  501. **
  502.  
  503. m.onerror = ON("ERROR")
  504. ON ERROR DO errorhandler WITH MESSAGE(), LINENO(), c_error_3
  505.  
  506. IF m.g_genparams < 2
  507.    DO errorhandler WITH "Invalid number of parameters passed to"+;
  508.       " the generator",LINENO(),c_error_3
  509.    RETURN m.g_status
  510. ENDIF
  511.  
  512. DO setall
  513.  
  514. IF openprojdbf(m.projdbf, m.recno) AND prepscreens(m.g_thisvers) AND prepplatform()
  515.    DO BUILD
  516. ENDIF
  517.  
  518. DO cleanup
  519.  
  520. RETURN m.g_status
  521.  
  522. ** formfeed
  523. **
  524. ** Code Responsible for Genscrn's environment setting.
  525. **
  526.  
  527. *
  528. * SETALL - Create program's environment.
  529. *
  530. * Description:
  531. * Save the user's environment that is being modified by the GENSCRN,
  532. * then issue various SET commands.
  533. *
  534. *!*****************************************************************************
  535. *!
  536. *!      Procedure: SETALL
  537. *!
  538. *!      Called by: GENSCRN.PRG
  539. *!
  540. *!*****************************************************************************
  541. PROCEDURE setall
  542. CLEAR PROGRAM
  543. CLEAR GETS
  544.  
  545. m.g_workarea = SELECT()
  546. m.delimiters = SET('TEXTMERGE',1)
  547. SET TEXTMERGE DELIMITERS TO
  548. mudfparms = SET('UDFPARMS')
  549. SET UDFPARMS TO VALUE
  550.  
  551. m.mfieldsto = SET("FIELDS",1)
  552. m.fields = SET("FIELDS")
  553. m.memowidth = SET("MEMOWIDTH")
  554. SET MEMOWIDTH TO 256
  555. m.cursor = SET("CURSOR")
  556. SET CURSOR OFF
  557. m.consol = SET("CONSOLE")
  558. SET CONSOLE OFF
  559. m.bell = SET("BELL")
  560. SET BELL OFF
  561. m.exact = SET("EXACT")
  562. SET EXACT ON
  563. m.safety = SET("SAFETY")
  564. m.deci = SET("DECIMALS")
  565. SET DECIMALS TO 0
  566. m.mdecpoint = SET("POINT")
  567. SET POINT TO "."
  568. m.fixed = SET("FIXED")
  569. SET FIXED ON
  570. m.print = SET("PRINT")
  571. SET PRINT OFF
  572. m.unique = SET("UNIQUE")
  573. SET UNIQUE OFF
  574. m.origpretext = _PRETEXT
  575. _PRETEXT = ""
  576.  
  577. *
  578. * CLEANUP - Restore environment to pre-execution state.
  579. *
  580. * Description:
  581. * Put SET command settings back the way we found them.
  582. *
  583. *!*****************************************************************************
  584. *!
  585. *!      Procedure: CLEANUP
  586. *!
  587. *!      Called by: GENSCRN.PRG
  588. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  589. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  590. *!
  591. *!          Calls: CLEANSCRN          (procedure in GENSCRN.PRG)
  592. *!               : CLEARAREAS         (procedure in GENSCRN.PRG)
  593. *!               : TOCK()             (function  in GENSCRN.PRG)
  594. *!
  595. *!*****************************************************************************
  596. PROCEDURE cleanup
  597. PRIVATE m.i, m.delilen, m.ldelimi, m.rdelimi
  598. IF EMPTY(m.g_projalias)
  599.    RETURN
  600. ENDIF
  601. SELECT (m.g_projalias)
  602. USE
  603. DO cleanscrn
  604. DO clearareas  && clear the workareas we opened during this run
  605. SELECT (m.g_workarea)
  606.  
  607. DELETE FILE (m.g_tmpfile)
  608. DELETE FILE (m.g_idxfile)
  609.  
  610. m.delilen = LEN(m.delimiters)
  611. m.ldelimi = SUBSTR(m.delimiters,1,;
  612.    IIF(MOD(m.delilen,2)=0,m.delilen/2,CEILING(m.delilen/2)))
  613. m.rdelimi = SUBSTR(m.delimiters,;
  614.    IIF(MOD(m.delilen,2)=0,m.delilen/2+1,CEILING(m.delilen/2)+1))
  615. SET TEXTMERGE DELIMITERS TO m.ldelimi, m.rdelimi
  616.  
  617. SET FIELDS TO &mfieldsto
  618. IF m.fields = "ON"
  619.    SET FIELDS ON
  620. ELSE
  621.    SET FIELDS OFF
  622. ENDIF
  623. IF m.cursor = "ON"
  624.    SET CURSOR ON
  625. ELSE
  626.    SET CURSOR OFF
  627. ENDIF
  628. IF m.consol = "ON"
  629.    SET CONSOLE ON
  630. ELSE
  631.    SET CONSOLE OFF
  632. ENDIF
  633. IF m.escape = "ON"
  634.    SET ESCAPE ON
  635. ELSE
  636.    SET ESCAPE OFF
  637. ENDIF
  638. IF m.bell = "ON"
  639.    SET BELL ON
  640. ELSE
  641.    SET BELL OFF
  642. ENDIF
  643. IF m.exact = "ON"
  644.    SET EXACT ON
  645. ELSE
  646.    SET EXACT OFF
  647. ENDIF
  648. IF m.safety = "ON"
  649.    SET SAFETY ON
  650. ELSE
  651.    SET SAFETY OFF
  652. ENDIF
  653. IF m.comp = "ON"
  654.    SET COMPATIBLE ON
  655. ENDIF
  656. IF m.print = "ON"
  657.    SET PRINT ON
  658. ENDIF
  659. SET DECIMALS TO m.deci
  660. SET MEMOWIDTH TO m.memowidth
  661. SET DEVICE TO &mdevice
  662. SET UDFPARMS TO &mudfparms
  663. SET POINT TO "&mdecpoint"
  664. IF m.fixed = "OFF"
  665.    SET FIXED OFF
  666. ENDIF
  667. IF m.trbetween = "ON"
  668.    SET TRBET ON
  669. ENDIF
  670. IF m.talkset = "ON"
  671.    SET TALK ON
  672. ENDIF
  673. IF m.unique = "ON"
  674.    SET UNIQUE ON
  675. ENDIF
  676. SET MESSAGE TO
  677. _PRETEXT = m.origpretext
  678. * Leave this array if dbglevel is defined.  Used for profiling.
  679. IF TYPE("dbglevel") = "U"
  680.    RELEASE ticktock
  681. ENDIF
  682.  
  683. ON ERROR &onerror
  684.  
  685. *
  686. * CLEANSCRN - Clean up after each screen set generation, once per platform
  687. *
  688. *!*****************************************************************************
  689. *!
  690. *!      Procedure: CLEANSCRN
  691. *!
  692. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  693. *!
  694. *!*****************************************************************************
  695. PROCEDURE cleanscrn
  696. PRIVATE m.i
  697. FOR m.i = 1 TO m.g_nscreens
  698.    m.g_screen = i
  699.    IF NOT EMPTY(g_screens[m.i,4])
  700.       LOOP
  701.    ENDIF
  702.    IF USED(g_screens[m.i,5])
  703.       SELECT (g_screens[m.i,5])
  704.       USE
  705.    ENDIF
  706. ENDFOR
  707. m.g_screen = 0
  708.  
  709.  
  710. ** formfeed
  711. **
  712. ** Environment setting code in preparation for generation.
  713. **
  714.  
  715. *
  716. * BUILDENABLE - Enable code generation.
  717. *
  718. * Description:
  719. * Call prepfile to open output file(s).
  720. * If error(s) encountered in prepfile then exit, otherwise
  721. * SET TEXTMERGE ON
  722. *
  723. * Returns: .T. on success; .F. on failure
  724. *
  725. *!*****************************************************************************
  726. *!
  727. *!      Procedure: BUILDENABLE
  728. *!
  729. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  730. *!
  731. *!          Calls: PREPFILE           (procedure in GENSCRN.PRG)
  732. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  733. *!
  734. *!*****************************************************************************
  735. PROCEDURE buildenable
  736. DO prepfile WITH m.g_outfile, m.g_orghandle
  737. DO prepfile WITH m.g_tmpfile, m.g_tmphandle
  738.  
  739. SET TEXTMERGE ON
  740. ON ESCAPE DO eschandler
  741. SET ESCAPE ON
  742.  
  743. *
  744. * BUILDDISABLE - Disable code generation.
  745. *
  746. * Description:
  747. * Issue the command SET TEXTMERGE OFF.
  748. * Close the generated output file.
  749. * Close the temporary file.
  750. * If anything goes wrong display appropriate message to the user.
  751. *
  752. *!*****************************************************************************
  753. *!
  754. *!      Procedure: BUILDDISABLE
  755. *!
  756. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  757. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  758. *!
  759. *!          Calls: CLOSEFILE          (procedure in GENSCRN.PRG)
  760. *!
  761. *!*****************************************************************************
  762. PROCEDURE builddisable
  763. SET ESCAPE OFF
  764. ON ESCAPE
  765. SET TEXTMERGE OFF
  766. IF m.g_havehand
  767.    DO closefile WITH m.g_orghandle
  768.    DO closefile WITH m.g_tmphandle
  769. ENDIF
  770.  
  771. *
  772. * PREPPARAMS - Read through each of the platforms on screen 1
  773. *              and ensure that any parameter statements in #SECTION 1
  774. *              are identical.
  775. *
  776. *!*****************************************************************************
  777. *!
  778. *!      Procedure: PREPPARAMS
  779. *!
  780. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  781. *!
  782. *!          Calls: CHECKPARAM()       (function  in GENSCRN.PRG)
  783. *!
  784. *!*****************************************************************************
  785. PROCEDURE prepparams
  786. PRIVATE m.i, m.j, m.dbalias, m.thisparam
  787. m.g_screen = 1
  788. m.dbalias = g_screens[m.g_screen,5]
  789. SELECT (m.dbalias)
  790. DO CASE
  791. CASE g_screens[m.g_screen,6] OR !multiplat()
  792.    * DOS 2.0 screen or just one 2.5 platform being generated
  793.    GO TOP
  794.    RETURN checkparam(m.g_screen)
  795.  
  796. OTHERWISE
  797.    FOR m.j = 1 TO c_maxplatforms
  798.       LOCATE FOR ALLTRIM(UPPER(platform)) = g_platlist[m.j] AND objtype = c_otscreen
  799.       DO CASE
  800.       CASE !FOUND() OR EMPTY(setupcode)
  801.          LOOP
  802.       CASE !checkparam(m.g_screen)
  803.          RETURN .F.
  804.       ENDCASE
  805.    ENDFOR
  806. ENDCASE
  807. m.g_screen = 0
  808. RETURN .T.
  809.  
  810. *
  811. * CLEANPARAM - Clean up a parameter string so that it may be compared with another one.
  812. *              This function replaces tabs with spaces, capitalizes the string, merges
  813. *              forces single spacing, and strips out CR/LF characters.
  814. *
  815. *!*****************************************************************************
  816. *!
  817. *!       Function: CLEANPARAM
  818. *!
  819. *!      Called by: CHECKPARAM()       (function  in GENSCRN.PRG)
  820. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  821. *!
  822. *!*****************************************************************************
  823. FUNCTION cleanparam
  824. PARAMETER m.p, m.cp
  825. m.cp = UPPER(ALLTRIM(CHRTRAN(m.p,";"+CHR(13)+CHR(10),"")))   && drop CR/LF and continuation chars
  826. m.cp = CHRTRAN(m.cp,CHR(9),' ')   && tabs to spaces
  827. DO WHILE AT('  ',m.cp) > 0         && reduce multiple spaces to a single space
  828.    m.cp = STRTRAN(m.cp,'  ',' ')
  829. ENDDO
  830. DO WHILE AT(', ',m.cp) > 0         && drop spaces after commas
  831.    m.cp = STRTRAN(m.cp,', ',',')
  832. ENDDO
  833. RETURN m.cp
  834.  
  835. *
  836. * CHECKPARAM - See if this parameter statement matches others we have found. Generate
  837. *               an error message if it doesn't.  g_parameter is empty if we haven't
  838. *               seen any parameter statements yet, or it contains the variables in the
  839. *               parameter statement (but not the PARAMETERS keyword) if we have seen one
  840. *               before.
  841. *
  842. *!*****************************************************************************
  843. *!
  844. *!       Function: CHECKPARAM
  845. *!
  846. *!      Called by: PREPPARAMS         (procedure in GENSCRN.PRG)
  847. *!
  848. *!          Calls: GETPARAM()         (function  in GENSCRN.PRG)
  849. *!               : CLEANPARAM()       (function  in GENSCRN.PRG)
  850. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  851. *!
  852. *!*****************************************************************************
  853. FUNCTION checkparam
  854. PARAMETER m.i
  855. PRIVATE m.thisparam
  856. m.thisparam = getparam("setupcode")  && get parameter from setup snippet at current record position
  857.  
  858. IF !EMPTY(m.thisparam)
  859.    IF !EMPTY(m.g_parameter) AND !(cleanparam(m.thisparam) == cleanparam(m.g_parameter))
  860.       DO errorhandler WITH "DOS and Windows setup code has different parameters", ;
  861.          LINENO(), c_error_3
  862.       RETURN .F.
  863.    ELSE
  864.       g_parameter = m.thisparam
  865.    ENDIF
  866. ENDIF
  867. RETURN .T.
  868.  
  869. *
  870. * PREPPLATFORM - Create an array of platform names in the screen set.  Make sure that
  871. *                there is at least one common platform across all SCXs in the screen set.
  872. *                g_platforms comes out of this procedure containing the intersection of
  873. *                the set of platforms in each screen.  If there are no common platforms
  874. *                across all screens, it will be empty.
  875. *
  876. *!*****************************************************************************
  877. *!
  878. *!      Procedure: PREPPLATFORM
  879. *!
  880. *!      Called by: GENSCRN.PRG
  881. *!
  882. *!*****************************************************************************
  883. PROCEDURE prepplatform
  884. PRIVATE m.i, m.j, m.firstscrn, m.p_cur, m.tempplat, m.numtodel, m.in_area, ;
  885.    m.rcount
  886. IF m.g_nscreens <= 0
  887.    RETURN .F.
  888. ENDIF
  889.  
  890. DIMENSION t_platforms[ALEN(g_platforms)]
  891. m.in_area = SELECT()
  892. IF g_screens[1,6]         && First screen is a DOS 2.0 screen
  893.    g_platforms = ""
  894.    g_platforms[1] = "DOS"
  895. ELSE
  896.    IF _DOS
  897.       * Avoid selecting into an array to conserve memory
  898.       SELECT DISTINCT platform FROM (g_screens[1,1]) INTO CURSOR curstemp ;
  899.          ORDER BY platform
  900.       m.rcount = _TALLY
  901.       SELECT curstemp
  902.       DIMENSION g_platforms[m.rcount]
  903.       GOTO TOP
  904.       FOR m.i = 1 TO m.rcount
  905.          g_platforms[m.i] = curstemp->platform
  906.          SKIP
  907.       ENDFOR
  908.       USE                                             && get rid of the cursor
  909.    ELSE
  910.       SELECT DISTINCT platform FROM (g_screens[1,1]) INTO ARRAY g_platforms ;
  911.          ORDER BY platform
  912.    ENDIF
  913. ENDIF
  914.  
  915. m.numtodel = 0   && number of array elements to delete
  916. FOR m.i = 2 TO m.g_nscreens
  917.    m.g_screen = m.i
  918.    IF g_screens[m.i,6]   && DOS 2.0 screen
  919.       DIMENSION t_platforms[1]
  920.       t_platforms = ""
  921.       t_platforms[1] = "DOS"
  922.    ELSE
  923.       IF _DOS
  924.          * Avoid selecting into an array to conserve memory
  925.          SELECT DISTINCT platform FROM (g_screens[m.i,1]) INTO CURSOR curstemp ;
  926.             ORDER BY platform
  927.          m.rcount = _TALLY
  928.          SELECT curstemp
  929.          DIMENSION t_platforms[m.rcount]
  930.          GOTO TOP
  931.          FOR m.k = 1 TO m.rcount
  932.             t_platforms[m.k] = curstemp->platform
  933.             SKIP
  934.          ENDFOR
  935.          USE                                             && get rid of the cursor
  936.       ELSE
  937.          SELECT DISTINCT platform FROM (g_screens[m.i,1]) INTO ARRAY t_platforms ;
  938.             ORDER BY platform
  939.       ENDIF
  940.    ENDIF
  941.  
  942.    * Update g_platforms with the intersection of g_platforms
  943.    *  and t_platforms
  944.    m.j = 1
  945.    DO WHILE m.j < ALEN(g_platforms) -  m.numtodel
  946.       IF !INLIST(TYPE("g_platforms[m.j]"),"L","U") ;
  947.             AND ASCAN(t_platforms,g_platforms[m.j]) = 0
  948.          =ADEL(g_platforms,m.j)
  949.          m.numtodel = m.numtodel + 1
  950.       ELSE
  951.          m.j = m.j + 1
  952.       ENDIF
  953.    ENDDO
  954.  
  955. ENDFOR
  956. SELECT (m.in_area)
  957.  
  958. m.g_screen = 0
  959. * Shrink the unique platform array if necessary
  960. DIMENSION g_platforms[ALEN(g_platforms)-m.numtodel]
  961.  
  962. IF ALEN(g_platforms) <= 0 OR EMPTY(g_platforms[1])
  963.    WAIT WINDOW  "No common platforms in these screens.  Press any key."
  964.    CANCEL
  965. ELSE
  966.    FOR m.j = 1 TO ALEN(g_platforms)
  967.       g_platforms[m.j] = UPPER(ALLTRIM(g_platforms[m.j]))
  968.    ENDFOR
  969.  
  970.    * If the current platform is in the list of common platforms, put it at the top
  971.    m.p_cur = ASCAN(g_platforms, m.g_thisvers)
  972.    IF m.p_cur > 1
  973.       m.tempplat = g_platforms[1]
  974.       g_platforms[1] = g_platforms[m.p_cur]
  975.       g_platforms[m.p_cur] = m.tempplat
  976.    ENDIF
  977. ENDIF
  978. RETURN .T.
  979.  
  980. *
  981. * PREPFILE - Create and open the application output file.
  982. *
  983. * Description:
  984. * Create or open a file that will hold the generated application.
  985. * If error(s) encountered at any time issue an error message
  986. * and return .F.
  987. *
  988. *!*****************************************************************************
  989. *!
  990. *!      Procedure: PREPFILE
  991. *!
  992. *!      Called by: BUILDENABLE        (procedure in GENSCRN.PRG)
  993. *!
  994. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  995. *!
  996. *!*****************************************************************************
  997. PROCEDURE prepfile
  998. PARAMETER m.filename, m.ifp
  999. PRIVATE m.msg
  1000. m.ifp = FCREATE(m.filename)
  1001.  
  1002. IF (m.ifp = -1)
  1003.    m.msg = "Cannot open "+LOWER(m.filename)
  1004.    m.g_havehand = .F.
  1005.    DO errorhandler WITH m.msg, LINENO(), c_error_3
  1006. ELSE
  1007.    m.g_havehand = .T.
  1008. ENDIF
  1009.  
  1010. *
  1011. * CLOSEFILE - Close a low level file opened with FCREATE.
  1012. *
  1013. *!*****************************************************************************
  1014. *!
  1015. *!      Procedure: CLOSEFILE
  1016. *!
  1017. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1018. *!               : BUILDDISABLE       (procedure in GENSCRN.PRG)
  1019. *!
  1020. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1021. *!
  1022. *!*****************************************************************************
  1023. PROCEDURE closefile
  1024. PARAMETER m.ifp
  1025. IF (m.ifp > 0) AND !FCLOSE(m.ifp)
  1026.    DO errorhandler WITH "Unable to close the generated file",;
  1027.       LINENO(), c_error_2
  1028. ENDIF
  1029.  
  1030. *
  1031. * PREPSCREENS - Prepare screen file(s) for processing.
  1032. *
  1033. * Description:
  1034. * Called once per platform.
  1035. *
  1036. * Open PJX database, index it to find all screen files belonging
  1037. * to a screen set if part of a project.
  1038. *
  1039. * Open all screen file(s).  If screen file already opened, then
  1040. * select it.  Assign unique aliases to screen with name conflicts.
  1041. * If error is encountered while opening any of the screen files
  1042. * this program will be aborted.
  1043. *
  1044. *!*****************************************************************************
  1045. *!
  1046. *!       Function: PREPSCREENS
  1047. *!
  1048. *!      Called by: GENSCRN.PRG
  1049. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1050. *!
  1051. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  1052. *!               : SCREENUSED()       (function  in GENSCRN.PRG)
  1053. *!               : NOTEAREA           (procedure in GENSCRN.PRG)
  1054. *!               : GETPLATFORM()      (function  in GENSCRN.PRG)
  1055. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1056. *!               : PREPWNAMES         (procedure in GENSCRN.PRG)
  1057. *!
  1058. *!*****************************************************************************
  1059. FUNCTION prepscreens
  1060. PARAMETER m.gen_version
  1061.  
  1062. PRIVATE m.status, m.projdbf, m.saverec, m.dbname, m.dbalias
  1063. m.status = .T.
  1064.  
  1065. SELECT (m.g_projalias)
  1066. SET SAFETY OFF
  1067. INDEX ON STR(scrnorder) TO (m.g_idxfile) COMPACT
  1068. SET SAFETY ON
  1069. GO TOP
  1070. SCAN FOR NOT DELETED() AND setid = m.g_keyno AND TYPE = 's'
  1071.    m.saverec = RECNO()
  1072.    m.dbname  = FULLPATH(ALLTRIM(name), m.g_projpath)
  1073.    m.g_nscreens = m.g_nscreens + 1
  1074.  
  1075.    IF MOD(m.g_nscreens,5)=0
  1076.       DIMENSION g_screens[ALEN(g_screens,1)+5,7]
  1077.       DIMENSION g_wnames [ALEN(g_wnames)+5,C_MAXPLATFORMS]
  1078.       DIMENSION g_platforms [ALEN(g_platforms)+5]
  1079.       DIMENSION g_firstproc [ALEN(g_firstproc)+5]
  1080.    ENDIF
  1081.  
  1082.    m.dbalias = basename(m.dbname)
  1083.    IF screenused(m.dbalias, m.dbname)
  1084.       g_screens[m.g_nscreens,4] = .T.
  1085.    ELSE
  1086.       g_screens[m.g_nscreens,4] = .F.
  1087.       SELECT 0
  1088.       USE (m.dbname) AGAIN ALIAS (g_screens[m.g_nscreens,5])
  1089.       DO notearea
  1090.    ENDIF
  1091.  
  1092.    DO CASE
  1093.    CASE FCOUNT() = c_scxflds
  1094.       LOCATE FOR platform = m.gen_version
  1095.       IF FOUND()
  1096.          g_screens[m.g_nscreens,6] = .F.
  1097.          g_screens[m.g_nscreens,7] = platform
  1098.       ELSE
  1099.          g_screens[m.g_nscreens,6] = .F.
  1100.          g_screens[m.g_nscreens,7] = getplatform()
  1101.       ENDIF
  1102.    CASE FCOUNT() = c_20scxflds
  1103.       g_screens[m.g_nscreens,6] = .T.
  1104.       g_screens[m.g_nscreens,7] = "DOS"
  1105.    OTHERWISE
  1106.       DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1107.          c_error_2
  1108.       RETURN .F.
  1109.    ENDCASE
  1110.    g_screens[m.g_nscreens,1] = m.dbname
  1111.  
  1112.    IF NOT EMPTY(STYLE)
  1113.       IF EMPTY(name)
  1114.          g_screens[m.g_nscreens,2] = LOWER(SYS(2015))
  1115.       ELSE
  1116.          g_screens[m.g_nscreens,2] = ALLTRIM(LOWER(name))
  1117.       ENDIF
  1118.       DO prepwnames WITH m.g_nscreens
  1119.    ENDIF
  1120.  
  1121.    SELECT (m.g_projalias)
  1122.    GOTO RECORD m.saverec
  1123.    g_screens[m.g_nscreens,3] = m.saverec
  1124. ENDSCAN
  1125.  
  1126. RETURN m.status
  1127.  
  1128. *!*****************************************************************************
  1129. *!
  1130. *!       Function: NEWWINDOWS
  1131. *!
  1132. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1133. *!
  1134. *!*****************************************************************************
  1135. FUNCTION newwindows
  1136. * Initialize the windows name array and other window-related
  1137. * variables for each platform.
  1138. g_wndows = ""                  && array of window names
  1139. m.g_nwindows = 0               && number of windows
  1140. m.g_lastwindow = ""            && name of last window generated for this platform
  1141. RETURN
  1142.  
  1143. *
  1144. * NEWSCHEMES - Initialize the color schemes for each screen/platform
  1145. *
  1146. *!*****************************************************************************
  1147. *!
  1148. *!       Function: NEWSCHEMES
  1149. *!
  1150. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1151. *!
  1152. *!*****************************************************************************
  1153. FUNCTION newschemes
  1154. m.g_defasch  = 0
  1155. m.g_defasch2 = 0
  1156. RETURN
  1157.  
  1158. *
  1159. * NEWDBFS - Initialize the databases name array for each platform
  1160. *
  1161. *!*****************************************************************************
  1162. *!
  1163. *!       Function: NEWDBFS
  1164. *!
  1165. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1166. *!
  1167. *!*****************************************************************************
  1168. FUNCTION newdbfs
  1169. g_dbfs = ""
  1170. RETURN
  1171.  
  1172. *
  1173. * NEWREADCLAUSES - Initialize the variables that control which READ and WINDOW clauses are
  1174. *                    emitted.
  1175. *
  1176. *!*****************************************************************************
  1177. *!
  1178. *!      Procedure: NEWREADCLAUSES
  1179. *!
  1180. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1181. *!
  1182. *!*****************************************************************************
  1183. PROCEDURE newreadclauses
  1184. m.g_validtype  = ""
  1185. m.g_validname  = ""
  1186. m.g_whentype   = ""
  1187. m.g_whenname   = ""
  1188. m.g_actitype   = ""
  1189. m.g_actiname   = ""
  1190. m.g_deattype   = ""
  1191. m.g_deatname   = ""
  1192. m.g_showtype   = ""
  1193. m.g_showname   = ""
  1194. m.g_showexpr   = ""
  1195.  
  1196. *!*****************************************************************************
  1197. *!
  1198. *!      Procedure: NEWDIRECTIVES
  1199. *!
  1200. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1201. *!
  1202. *!*****************************************************************************
  1203. PROCEDURE newdirectives
  1204. m.g_windclauses= ""            && #WCLAUSES directive
  1205. m.g_rddir      = .F.           && Is there a #READCLAUSES directive?
  1206. m.g_rddirno    = 0             && Number of 1st screen with #READ directive
  1207.  
  1208. *
  1209. * GETPLATFORM - Find which Platform we are supposed to generate for.  If we are trying to
  1210. *               generate for Windows, but there are no windows records in the SCX, use
  1211. *               this function to determine which records to use.
  1212. *
  1213. *!*****************************************************************************
  1214. *!
  1215. *!       Function: GETPLATFORM
  1216. *!
  1217. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1218. *!
  1219. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1220. *!
  1221. *!*****************************************************************************
  1222. FUNCTION getplatform
  1223.  
  1224. IF m.g_genvers = 'WINDOWS' OR m.g_genvers = 'MAC'
  1225.    LOCATE FOR platform = IIF(m.g_genvers = 'WINDOWS', 'MAC', 'WINDOWS')
  1226.    IF FOUND()
  1227.       RETURN platform
  1228.    ELSE
  1229.       LOCATE FOR platform = 'DOS'
  1230.       IF FOUND()
  1231.          RETURN 'DOS'
  1232.       ELSE
  1233.          LOCATE FOR platform = 'UNIX'
  1234.          IF FOUND()
  1235.             RETURN 'UNIX'
  1236.          ELSE
  1237.             DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1238.                c_error_2
  1239.          ENDIF
  1240.       ENDIF
  1241.    ENDIF
  1242. ELSE
  1243.    LOCATE FOR platform = IIF(m.g_genvers = 'DOS', 'UNIX', 'DOS')
  1244.    IF FOUND()
  1245.       RETURN platform
  1246.    ELSE
  1247.       LOCATE FOR platform = 'WINDOWS'
  1248.       IF FOUND()
  1249.          RETURN 'DOS'
  1250.       ELSE
  1251.          LOCATE FOR platform = 'MAC'
  1252.          IF FOUND()
  1253.             RETURN 'UNIX'
  1254.          ELSE
  1255.             DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1256.                c_error_2
  1257.          ENDIF
  1258.       ENDIF
  1259.    ENDIF
  1260. ENDIF
  1261. RETURN ""
  1262.  
  1263.  
  1264. *
  1265. * PREPWNAMES - Store #WNAME directive strings.  They must be in the setup snippet.
  1266. *
  1267. *!*****************************************************************************
  1268. *!
  1269. *!      Procedure: PREPWNAMES
  1270. *!
  1271. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1272. *!
  1273. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  1274. *!               : SKIPWHITESPACE()   (function  in GENSCRN.PRG)
  1275. *!
  1276. *!*****************************************************************************
  1277. PROCEDURE prepwnames
  1278. PARAMETER m.scrnno
  1279. PRIVATE m.lineno, m.textline
  1280. m.lineno = ATCLINE('#WNAM',setupcode)
  1281. IF m.lineno > 0
  1282.    m.textline = MLINE(setupcode,m.lineno)
  1283.    IF g_screens[m.scrnno,6])   && DOS 2.0 screen
  1284.       IF ATC('#WNAM',m.textline) = 1
  1285.          g_wnames[m.scrnno, getplatnum("DOS")] = skipwhitespace(m.textline)
  1286.       ENDIF
  1287.    ELSE
  1288.       IF ATC('#WNAM',m.textline) = 1
  1289.          g_wnames[m.scrnno, getplatnum(platform)] = skipwhitespace(m.textline)
  1290.       ENDIF
  1291.    ENDIF
  1292. ENDIF
  1293. RETURN
  1294.  
  1295. *
  1296. * SCREENUSED - Check to see if screen file already opened.
  1297. *
  1298. *!*****************************************************************************
  1299. *!
  1300. *!       Function: SCREENUSED
  1301. *!
  1302. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1303. *!
  1304. *!          Calls: ILLEGALNAME()      (function  in GENSCRN.PRG)
  1305. *!
  1306. *!*****************************************************************************
  1307. FUNCTION screenused
  1308. PARAMETER m.dbalias, m.fulldbname
  1309. IF NOT USED(m.dbalias)
  1310.    IF illegalname(m.dbalias)
  1311.       g_screens[m.g_nscreens,5] = "S"+SUBSTR(LOWER(SYS(3)),2,8)
  1312.    ELSE
  1313.       g_screens[m.g_nscreens,5] = m.dbalias
  1314.    ENDIF
  1315.    RETURN .F.
  1316. ENDIF
  1317. SELECT (m.dbalias)
  1318. IF RAT(".SCX",DBF())<>0 AND m.fulldbname=DBF()
  1319.    g_screens[m.g_nscreens,5] = m.dbalias
  1320.    RETURN .T.
  1321. ELSE
  1322.    g_screens[m.g_nscreens,5] = "S"+SUBSTR(LOWER(SYS(3)),2,8)
  1323. ENDIF
  1324. RETURN .F.
  1325.  
  1326. *
  1327. * ILLEGALNAME - Check if default alias will be used when this
  1328. *               database is USEd. (i.e., 1st letter is not A-Z,
  1329. *                a-z or '_', or any one of ramaining letters is not
  1330. *                alphanumeric.)
  1331. *
  1332. *!*****************************************************************************
  1333. *!
  1334. *!       Function: ILLEGALNAME
  1335. *!
  1336. *!      Called by: SCREENUSED()       (function  in GENSCRN.PRG)
  1337. *!
  1338. *!*****************************************************************************
  1339. FUNCTION illegalname
  1340. PARAMETER m.dname
  1341. PRIVATE m.start, m.aschar, m.length
  1342. m.length = LEN(m.dname)
  1343. m.start  = 0
  1344. IF m.length = 1
  1345.    *
  1346.    * If length 1, then check if default alias can be used,
  1347.    * i.e., name is different than A-J and a-j.
  1348.    *
  1349.    m.aschar = ASC(m.dname)
  1350.    IF (m.aschar >= 65 AND m.aschar <= 74) OR ;
  1351.          (m.aschar >= 97 AND m.aschar <= 106)
  1352.       RETURN .T.
  1353.    ENDIF
  1354. ENDIF
  1355. DO WHILE m.start < m.length
  1356.    m.start  = m.start + 1
  1357.    m.aschar = ASC(SUBSTR(m.dname, m.start, 1))
  1358.    IF m.start<>1 AND (m.aschar >= 48 AND m.aschar <= 57)
  1359.       LOOP
  1360.    ENDIF
  1361.    IF NOT ((m.aschar >= 65 AND m.aschar <= 90) OR ;
  1362.          (m.aschar >= 97 AND m.aschar <= 122) OR m.aschar = 95)
  1363.       RETURN .T.
  1364.    ENDIF
  1365. ENDDO
  1366. RETURN .F.
  1367.  
  1368. *
  1369. * OPENPROJDBF - Prepare Project dbf for processing.
  1370. *
  1371. * Description:
  1372. * Check to see if projdbf has an appropriate number of fields.
  1373. * Find the screen set record.
  1374. * Extract information from the SETID record.
  1375. *
  1376. *!*****************************************************************************
  1377. *!
  1378. *!       Function: OPENPROJDBF
  1379. *!
  1380. *!      Called by: GENSCRN.PRG
  1381. *!
  1382. *!          Calls: NOTEAREA           (procedure in GENSCRN.PRG)
  1383. *!               : STRIPEXT()         (function  in GENSCRN.PRG)
  1384. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1385. *!               : REFRESHPREFS       (procedure in GENSCRN.PRG)
  1386. *!               : GETWITHLIST        (procedure in GENSCRN.PRG)
  1387. *!
  1388. *!*****************************************************************************
  1389. FUNCTION openprojdbf
  1390. PARAMETER m.projdbf, m.recno
  1391.  
  1392. SELECT 0
  1393. IF USED("projdbf")
  1394.    m.g_projalias = "P"+SUBSTR(LOWER(SYS(3)),2,8)
  1395. ELSE
  1396.    m.g_projalias = "projdbf"
  1397. ENDIF
  1398. USE (m.projdbf) ALIAS (m.g_projalias)
  1399. DO notearea
  1400. m.g_errlog = stripext(m.projdbf)
  1401. m.g_projpath = SUBSTR(m.projdbf,1,RAT("\",m.projdbf))
  1402.  
  1403. IF FCOUNT() <> c_pjxflds
  1404.    IF FCOUNT() = c_pjx20flds
  1405.       DO errorhandler WITH "Invalid 2.0 project file passed to GenScrn.",;
  1406.          LINENO(), c_error_2
  1407.    ELSE
  1408.       DO errorhandler WITH "Generator out of date.",;
  1409.          LINENO(), c_error_2
  1410.    ENDIF
  1411.    RETURN .F.
  1412. ENDIF
  1413.  
  1414. DO refreshprefs
  1415. GOTO m.recno
  1416. m.g_keyno        = setid
  1417. m.g_outfile      = ALLTRIM(SUBSTR(outfile,1,AT(c_null,outfile)-1))
  1418. m.g_outfile      = FULLPATH(m.g_outfile, m.g_projpath)
  1419. m.g_openfiles    = openfiles
  1420. m.g_closefiles   = closefiles
  1421. m.g_defwin       = defwinds
  1422. m.g_relwin       = relwinds
  1423. m.g_readcycle    = readcycle
  1424. m.g_readlock     = NOLOCK
  1425. m.g_readmodal    = MODAL
  1426. m.g_readborder   = nologo
  1427. m.g_multreads    = multreads
  1428. m.g_allplatforms = !savecode
  1429. DO getwithlist
  1430.  
  1431. *
  1432. * GETWITHLIST - Construct the list for READ level WITH clause.
  1433. *
  1434. *!*****************************************************************************
  1435. *!
  1436. *!      Procedure: GETWITHLIST
  1437. *!
  1438. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  1439. *!
  1440. *!*****************************************************************************
  1441. PROCEDURE getwithlist
  1442. PRIVATE m.start, m.cret, m.occurance, m.list
  1443. m.start = 1
  1444. m.occurance = 1
  1445. m.cret = AT(c_cret,assocwinds,m.occurance)
  1446. DO WHILE m.cret<>0
  1447.    m.list = ALLTRIM(SUBSTR(assocwinds,m.start,m.cret-m.start))
  1448.    m.g_withlist = m.g_withlist + ;
  1449.       IIF(EMPTY(m.g_withlist),"",", ") + m.list
  1450.    m.occurance = m.occurance + 1
  1451.    m.start = m.cret + 1
  1452.    m.cret = AT(c_cret,assocwinds,m.occurance)
  1453. ENDDO
  1454.  
  1455. *
  1456. * REFRESHPREFS - Refresh Documentation and Developer preferences.
  1457. *
  1458. * Description:
  1459. * Get the newest preferences for documentation style and developer
  1460. * data from the HEADER record.
  1461. *
  1462. *!*****************************************************************************
  1463. *!
  1464. *!      Procedure: REFRESHPREFS
  1465. *!
  1466. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  1467. *!
  1468. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1469. *!               : SUBDEVINFO()       (function  in GENSCRN.PRG)
  1470. *!
  1471. *!*****************************************************************************
  1472. PROCEDURE refreshprefs
  1473. PRIVATE m.start
  1474. LOCATE FOR TYPE = "H"
  1475. IF NOT FOUND ()
  1476.    DO errorhandler WITH "Missing header record in "+m.projdbf,;
  1477.       LINENO(), c_error_2
  1478.    RETURN
  1479. ENDIF
  1480.  
  1481. m.g_homedir = ALLTRIM(SUBSTR(homedir,1,AT(c_null,homedir)-1))
  1482. IF RIGHT(m.g_homedir,1) <> "\"
  1483.    m.g_homedir = m.g_homedir + "\"
  1484. ENDIF
  1485.  
  1486. m.start = 1
  1487. m.g_devauthor = subdevinfo(m.start,c_authorlen,m.g_devauthor)
  1488.  
  1489. m.start = m.start + c_authorlen + 1
  1490. m.g_devcompany = subdevinfo(m.start,c_complen,m.g_devcompany)
  1491.  
  1492. m.start = m.start + c_complen + 1
  1493. m.g_devaddress = subdevinfo(m.start,c_addrlen,m.g_devaddress)
  1494.  
  1495. m.start = m.start + c_addrlen + 1
  1496. m.g_devcity = subdevinfo(m.start,c_citylen,m.g_devcity)
  1497.  
  1498. m.start = m.start + c_citylen + 1
  1499. m.g_devstate = subdevinfo(m.start,c_statlen,m.g_devstate)
  1500.  
  1501. m.start = m.start + c_statlen + 1
  1502. m.g_devzip = subdevinfo(m.start,c_ziplen,m.g_devzip)
  1503.  
  1504. m.start = m.start + c_ziplen + 1
  1505. m.g_devctry = subdevinfo(m.start,c_countrylen,m.g_devctry)
  1506.  
  1507. IF cmntstyle = 0
  1508.    m.g_corn1 = "╓"
  1509.    m.g_corn2 = "╖"
  1510.    m.g_corn3 = "╙"
  1511.    m.g_corn4 = "╜"
  1512.    m.g_corn5 = "╟"
  1513.    m.g_corn6 = "╢"
  1514.    m.g_horiz = "─"
  1515.    m.g_verti1 = "║"
  1516.    m.g_verti2= "║"
  1517. ENDIF
  1518.  
  1519. *
  1520. * SUBDEVINFO - Extract strings from the DEVINFO memo field.
  1521. *
  1522. *!*****************************************************************************
  1523. *!
  1524. *!       Function: SUBDEVINFO
  1525. *!
  1526. *!      Called by: REFRESHPREFS       (procedure in GENSCRN.PRG)
  1527. *!
  1528. *!*****************************************************************************
  1529. FUNCTION subdevinfo
  1530. PARAMETER m.start, m.stop, m.default
  1531. PRIVATE m.string
  1532. m.string = SUBSTR(devinfo, m.start, m.stop+1)
  1533. m.string = SUBSTR(m.string, 1, AT(c_null,m.string)-1)
  1534. RETURN IIF(EMPTY(m.string), m.default, m.string)
  1535.  
  1536. **
  1537. ** High Level Controlling Structures in Format file generation.
  1538. **
  1539.  
  1540. *
  1541. * BUILD - Controlling procedure for building of a format file.
  1542. *
  1543. * Description:
  1544. * This procedure is a controlling procedure for the process of
  1545. * generating a screen file.  It enables building, activates the
  1546. * thermometer, calls BUILDCTRL and combines two output files,
  1547. * and finally disables building.
  1548. * This procedure also makes calls to UPDTHERM to
  1549. * update the thermometer display.
  1550. *
  1551. *!*****************************************************************************
  1552. *!
  1553. *!      Procedure: BUILD
  1554. *!
  1555. *!      Called by: GENSCRN.PRG
  1556. *!
  1557. *!          Calls: BUILDENABLE        (procedure in GENSCRN.PRG)
  1558. *!               : ACTTHERM           (procedure in GENSCRN.PRG)
  1559. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1560. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1561. *!               : COMBINE            (procedure in GENSCRN.PRG)
  1562. *!               : BUILDDISABLE       (procedure in GENSCRN.PRG)
  1563. *!               : DEACTTHERMO        (procedure in GENSCRN.PRG)
  1564. *!
  1565. *!*****************************************************************************
  1566. PROCEDURE BUILD
  1567.  
  1568. DO buildenable
  1569. DO acttherm WITH "Generating Screen Code..."
  1570. DO updtherm WITH 5
  1571.  
  1572. DO dispatchbuild
  1573.  
  1574. DO updtherm WITH  95 * m.g_numplatforms
  1575. DO combine
  1576. DO updtherm WITH 100 * m.g_numplatforms   && force thermometer to complete
  1577. DO builddisable
  1578.  
  1579. DO deactthermo
  1580.  
  1581. *
  1582. * DISPATCHBUILD - Determines which platforms are to be generated and
  1583. *                  calls BUILDCTRL for each one.
  1584. *
  1585. *!*****************************************************************************
  1586. *!
  1587. *!      Procedure: DISPATCHBUILD
  1588. *!
  1589. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  1590. *!
  1591. *!          Calls: COUNTPLATFORMS     (procedure in GENSCRN.PRG)
  1592. *!               : PREPPARAMS         (procedure in GENSCRN.PRG)
  1593. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  1594. *!               : SCANPROC           (procedure in GENSCRN.PRG)
  1595. *!               : GENPARAMETER       (procedure in GENSCRN.PRG)
  1596. *!               : LOOKUPPLATFORM     (procedure in GENSCRN.PRG)
  1597. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  1598. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  1599. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  1600. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1601. *!               : NEWWINDOWS()       (function  in GENSCRN.PRG)
  1602. *!               : NEWDBFS()          (function  in GENSCRN.PRG)
  1603. *!               : NEWREADCLAUSES     (procedure in GENSCRN.PRG)
  1604. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  1605. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  1606. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  1607. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1608. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  1609. *!
  1610. *!*****************************************************************************
  1611. PROCEDURE dispatchbuild
  1612. PRIVATE m.i, m.thisplat, m.j
  1613. m.g_numplatforms = countplatforms()
  1614.  
  1615. DO prepparams
  1616.  
  1617. _TEXT = m.g_orghandle
  1618. _PRETEXT = ""
  1619.  
  1620. DO CASE
  1621. CASE multiplat()
  1622.    * Emit code for all common platforms in the screen set and put CASE statements
  1623.    * around the code for each one.  The g_platforms array contains the list of
  1624.    * platforms to generate for.
  1625.  
  1626.    * If generating for multiple platforms, scan all cleanup snippets and assemble an
  1627.    * array of unique procedure names.  This process is designed to handle procedure name
  1628.    * collisions across platforms.
  1629.    DO scanproc
  1630.  
  1631.    DO header   && main heading at top of program
  1632.  
  1633.    * Special case when there are multiple platforms being sent to the
  1634.    * same SPR.  Since the SPR can only have a single parameter statement,
  1635.    * and since it has to appear before the CASE _platform code, put it
  1636.    * here.
  1637.    DO genparameter
  1638.  
  1639.    m.thisplat = "X"   && placeholder value
  1640.    m.i = 1
  1641.    DO WHILE !EMPTY(m.thisplat)
  1642.       m.thisplat = lookupplatform(m.i)
  1643.       IF !EMPTY(m.thisplat)
  1644.          DO putmsg WITH "Generating code for "+versioncap(m.thisplat)
  1645.       
  1646.          IF m.i = 1
  1647.             \DO CASE
  1648.          ELSE
  1649.             \
  1650.          ENDIF
  1651.          \CASE _<<m.thisplat>>
  1652.          \
  1653.          
  1654.          * Switch the platform to generate for
  1655.          m.g_genvers = m.thisplat
  1656.  
  1657.          * Update screen array entries for the new platform, unless it's the currently
  1658.          * executing platform, in which case we did this just above.
  1659.          IF !(m.thisplat == m.g_thisvers)
  1660.             * Start with a fresh set of screens.  Prepscreens() fills in the details.
  1661.             g_nscreens = 0
  1662.             IF !prepscreens(m.thisplat)
  1663.                DO errorhandler WITH "Error initializing screens for ";
  1664.                   +PROPER(m.thisplat)+".", LINENO(), c_error_3
  1665.                CANCEL
  1666.             ENDIF
  1667.             DO newwindows      && initialize the window array
  1668.             DO newdbfs         && initialize the DBF name array
  1669.             DO newreadclauses  && initialize the read clause variables
  1670.             DO newdirectives   && initialize the directives that change from platform to platform
  1671.             DO newschemes      && initialize the scheme variables
  1672.          ENDIF
  1673.  
  1674.          DO pushindent
  1675.          DO buildctrl WITH m.thisplat, m.i, .F.
  1676.          DO popindent
  1677.       ENDIF
  1678.       m.i = m.i + 1
  1679.    ENDDO
  1680.    \
  1681.    \ENDCASE
  1682.    \
  1683.    _TEXT = m.g_tmphandle
  1684.    m.thispretext = _PRETEXT
  1685.    _PRETEXT = ""
  1686.    DO updtherm WITH 70 * m.g_numplatforms
  1687.    DO genprocedures
  1688.    _TEXT = m.g_orghandle
  1689.    _PRETEXT = m.thispretext
  1690.  
  1691. OTHERWISE                         && just outputing one platform.
  1692.    * If we are generating for a platform other than the one we are running
  1693.    * on, run through prepscreens again to assign the right platform
  1694.    * name to each of these screens.
  1695.    IF (_DOS AND g_platforms[1] <> "DOS") ;
  1696.          OR (_WINDOWS AND g_platforms[1] <> "WINDOWS") ;
  1697.          OR (_MAC AND g_platforms[1] <> "MAC") ;
  1698.          OR (_UNIX AND g_platforms[1] <> "UNIX")
  1699.       g_nscreens = 0
  1700.       IF !prepscreens(g_platforms[1])
  1701.          DO errorhandler WITH "Error initializing screens for ";
  1702.             +PROPER(m.thisplat)+".", LINENO(), c_error_3
  1703.          CANCEL
  1704.       ENDIF
  1705.    ENDIF
  1706.  
  1707.    m.g_allplatforms = .F.
  1708.    m.g_numplatforms = 1
  1709.    m.g_genvers      = g_platforms[1]
  1710.  
  1711.    DO newwindows      && Initialize the array of window names
  1712.    DO newdbfs         && Initialize the array of DBF names
  1713.    DO newreadclauses  && Initialize the read clause variables for each platform
  1714.    DO newdirectives   && Initialize the directives that change from platform to platform
  1715.    DO newschemes      && initialize the scheme variables
  1716.  
  1717.    DO header
  1718.    DO buildctrl WITH g_platforms[1], 1, .T.
  1719.  
  1720.    DO updtherm WITH  70
  1721.    DO genprocedures
  1722. ENDCASE
  1723.  
  1724.  
  1725. **
  1726. ** Code Associated With Building of the Control Program.
  1727. **
  1728. *
  1729. * BUILDCTRL - Generate Format control file.
  1730. *
  1731. * Description:
  1732. * Buildctrl controls the generation process.  It invokes procedures
  1733. * which build the output program from a set of screens.
  1734. *
  1735. *!*****************************************************************************
  1736. *!
  1737. *!      Procedure: BUILDCTRL
  1738. *!
  1739. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1740. *!
  1741. *!          Calls: HEADER             (procedure in GENSCRN.PRG)
  1742. *!               : GENPARAMETER       (procedure in GENSCRN.PRG)
  1743. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  1744. *!               : GENSETENVIRON      (procedure in GENSCRN.PRG)
  1745. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  1746. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1747. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  1748. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  1749. *!               : DEFPOPUPS          (procedure in GENSCRN.PRG)
  1750. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  1751. *!               : GENCLNENVIRON      (procedure in GENSCRN.PRG)
  1752. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  1753. *!
  1754. *!*****************************************************************************
  1755. PROCEDURE buildctrl
  1756. PARAMETERS m.pltfrm, m.pnum, m.putparam, m.dbalias
  1757. PRIVATE m.i
  1758.  
  1759. IF m.putparam
  1760.    * Bracketed code is handled elsewhere.  We are only emitting the parameter
  1761.    * from this platform.  Go get it again to make sure we have the right one.
  1762.    * At this point, g_parameter could contain the parameter from any platform.
  1763.  
  1764.    * Open the database for the first screen since it's the only one we can generate
  1765.    * a parameter statement for.
  1766.    m.dbalias = g_screens[1,5]
  1767.    SELECT (m.dbalias)
  1768.    DO seekheader WITH 1
  1769.  
  1770.    m.g_parameter = getparam("setupcode")
  1771.  
  1772.    DO genparameter
  1773. ENDIF
  1774. DO gensect1                                && SECTION 1 setup code
  1775. DO gensetenviron                        && environment setup code
  1776. IF m.g_openfiles
  1777.    DO genopendbfs                        && USE ... INDEX ... statements
  1778.    DO updtherm WITH 15 * m.pnum    && and SET RELATIONS
  1779. ENDIF
  1780.  
  1781. DO defwindows                             && window definitions
  1782. DO gensect2                                && SECTION 2 setup code
  1783. DO defpopups                            && lists
  1784. DO updtherm WITH 35 * m.pnum
  1785.  
  1786. DO buildfmt WITH m.pnum            && @ ... SAY/GET statements
  1787.  
  1788. DO updtherm WITH 60 * m.pnum
  1789. IF m.g_windows AND m.g_relwin AND !m.g_noread
  1790.    * If the READ is omitted, don't produce the code to release the window.
  1791.    FOR m.i = 1 TO m.g_nwindows
  1792.       \RELEASE WINDOW <<g_wndows[m.i,1]>>
  1793.    ENDFOR
  1794. ENDIF
  1795.  
  1796. IF m.g_moddesktop AND m.g_relwin
  1797.    \MODIFY WINDOW SCREEN
  1798. ENDIF
  1799.  
  1800. DO genclnenviron                        && environment cleanup code
  1801. DO updtherm WITH 65 * m.pnum
  1802. DO gencleanup                       && cleanup code, but not procedures/functions
  1803.  
  1804. *
  1805. * GENSETENVIRON - Generate environment code for the .SPR
  1806. *
  1807. *!*****************************************************************************
  1808. *!
  1809. *!      Procedure: GENSETENVIRON
  1810. *!
  1811. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1812. *!
  1813. *!*****************************************************************************
  1814. PROCEDURE gensetenviron
  1815. IF !m.g_noreadplain
  1816.    \
  1817.    \#REGION 0
  1818.    \REGIONAL m.currarea, m.talkstat, m.compstat
  1819.    \
  1820.    \IF SET("TALK") = "ON"
  1821.    \    SET TALK OFF
  1822.    \    m.talkstat = "ON"
  1823.    \ELSE
  1824.    \    m.talkstat = "OFF"
  1825.    \ENDIF
  1826.    \m.compstat = SET("COMPATIBLE")
  1827.    \SET COMPATIBLE FOXPLUS
  1828.    
  1829.    IF m.g_readborder AND (INLIST(m.g_genvers,"WINDOWS","MAC"))
  1830.       \
  1831.       \m.rborder = SET("READBORDER")
  1832.       \SET READBORDER ON
  1833.    ENDIF
  1834. ENDIF   
  1835.  
  1836. IF m.g_closefiles
  1837.    \
  1838.    \m.currarea = SELECT()
  1839.    \
  1840. ENDIF
  1841.  
  1842. *
  1843. * GENCLNENVIRON - Generate environment code for the .SPR
  1844. *
  1845. *!*****************************************************************************
  1846. *!
  1847. *!      Procedure: GENCLNENVIRON
  1848. *!
  1849. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1850. *!
  1851. *!          Calls: GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  1852. *!               : RELPOPUPS          (procedure in GENSCRN.PRG)
  1853. *!
  1854. *!*****************************************************************************
  1855. PROCEDURE genclnenviron
  1856. IF m.g_closefiles
  1857.    DO genclosedbfs
  1858. ENDIF
  1859. IF m.g_somepops
  1860.    DO relpopups
  1861. ENDIF
  1862. IF !m.g_noreadplain
  1863.    \
  1864.    \#REGION 0
  1865.    IF m.g_readborder AND INLIST(m.g_genvers,"WINDOWS","MAC"))
  1866.       \
  1867.       \SET READBORDER &rborder
  1868.       \
  1869.    ENDIF
  1870.    \IF m.talkstat = "ON"
  1871.    \    SET TALK ON
  1872.    \ENDIF
  1873.    \IF m.compstat = "ON"
  1874.    \    SET COMPATIBLE ON
  1875.    \ENDIF
  1876.    \
  1877. ENDIF
  1878.  
  1879. *
  1880. * GENCLEANUP - Generate Cleanup Code.
  1881. *
  1882. *!*****************************************************************************
  1883. *!
  1884. *!      Procedure: GENCLEANUP
  1885. *!
  1886. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1887. *!
  1888. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  1889. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  1890. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  1891. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  1892. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  1893. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  1894. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  1895. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  1896. *!
  1897. *!*****************************************************************************
  1898. PROCEDURE gencleanup
  1899. PRIVATE m.i, m.dbalias, m.msg
  1900.  
  1901. IF m.g_graphic
  1902.    m.msg = 'Generating Cleanup Code'
  1903.    IF multiplat()
  1904.       m.msg = m.msg + " for "+versioncap(m.g_genvers)
  1905.    ENDIF
  1906.    DO putmsg WITH  m.msg
  1907. ENDIF
  1908.  
  1909. * Generate the actual cleanup code--the code that precedes procedures
  1910. * and function declarations.
  1911. FOR m.i = 1 TO m.g_nscreens
  1912.    m.g_screen = m.i
  1913.    m.dbalias = g_screens[m.i,5]
  1914.    SELECT (m.dbalias)
  1915.  
  1916.    DO seekheader WITH m.i
  1917.    IF EMPTY (proccode)
  1918.       g_firstproc[m.i] = 0
  1919.       LOOP
  1920.    ENDIF
  1921.  
  1922.    * Find the line number where the first procedure or function
  1923.    * declaration occurs
  1924.    g_firstproc[m.i] = getfirstproc("PROCCODE")
  1925.  
  1926.    IF g_firstproc[m.i] <> 1
  1927.       * Either there aren't any procedures/functions, or they
  1928.       * are below the actual cleanup code.  Emit the cleanup code.
  1929.       DO commentblock WITH g_screens[m.i,1], " Cleanup Code"
  1930.       \#REGION <<INT(m.i)>>
  1931.       DO writecode WITH proccode, getplatname(m.i), c_fromone, g_firstproc[m.i], m.i
  1932.    ENDIF
  1933. ENDFOR
  1934. m.g_screen = 0
  1935.  
  1936. RETURN
  1937.  
  1938. *
  1939. * GENPROCEDURES - Generate Procedures and Functions from cleanup code.
  1940. *
  1941. *!*****************************************************************************
  1942. *!
  1943. *!      Procedure: GENPROCEDURES
  1944. *!
  1945. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1946. *!
  1947. *!          Calls: PUTMSG             (procedure in GENSCRN.PRG)
  1948. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  1949. *!               : PUTPROCHEAD        (procedure in GENSCRN.PRG)
  1950. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  1951. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  1952. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  1953. *!               : ISGENPLAT()        (function  in GENSCRN.PRG)
  1954. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  1955. *!
  1956. *!*****************************************************************************
  1957. PROCEDURE genprocedures
  1958. PRIVATE m.i, m.dbalias
  1959. m.msg = 'Generating Procedures and Functions'
  1960. DO putmsg WITH m.msg
  1961.  
  1962. * Go back through each of the screens and output any procedures and
  1963. * functions that are in the cleanup snippet.
  1964. FOR m.i = 1 TO m.g_nscreens
  1965.    m.g_screen = m.i
  1966.    m.g_isfirstproc = .T.  && reset this for each screen
  1967.    m.dbalias = g_screens[m.i,5]
  1968.    SELECT (m.dbalias)
  1969.    DO seekheader WITH m.i
  1970.  
  1971.    DO CASE
  1972.    CASE g_screens[m.i,6]    && DOS 2.0 screen
  1973.       IF g_firstproc[m.i] > 0
  1974.          DO putprochead WITH m.i, g_screens[m.i,1]
  1975.          DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1976.       ENDIF
  1977.    CASE multiplat()
  1978.       * Multiple 2.5 platforms
  1979.       IF m.g_procsmatch   && all cleanup snippets in the file are the same
  1980.          * Get all the screen/platform headers from this screen file
  1981.          IF g_firstproc[m.i] > 0
  1982.             DO putprochead WITH m.i, g_screens[m.i,1]
  1983.             DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1984.          ENDIF
  1985.       ELSE
  1986.          * The are some differences.  Look for procedure name collisions among the
  1987.          * cleanup snippets in the platforms we are generating.
  1988.          SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  1989.             IF EMPTY(proccode)
  1990.                LOOP
  1991.             ENDIF
  1992.             DO putprochead WITH m.i, g_screens[m.i,1]
  1993.             DO extractprocs WITH m.i
  1994.          ENDSCAN
  1995.       ENDIF
  1996.    OTHERWISE  && just generating one 2.5 platform
  1997.       IF g_firstproc[m.i] > 0
  1998.          DO putprochead WITH m.i, g_screens[m.i,1]
  1999.          DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  2000.       ENDIF
  2001.    ENDCASE
  2002. ENDFOR
  2003. m.g_screen = 0
  2004. RETURN
  2005.  
  2006. *
  2007. * PROCSMATCH - Are the CRCs for the cleanup snippets the same for all platforms in the
  2008. *                current screen that are being generated?
  2009. *
  2010. *!*****************************************************************************
  2011. *!
  2012. *!       Function: PROCSMATCH
  2013. *!
  2014. *!      Called by: SCANPROC           (procedure in GENSCRN.PRG)
  2015. *!
  2016. *!          Calls: ISGENPLAT()        (function  in GENSCRN.PRG)
  2017. *!
  2018. *!*****************************************************************************
  2019. FUNCTION procsmatch
  2020. PRIVATE m.crccode, m.thiscode, m.in_rec
  2021.  
  2022. m.in_rec = IIF(!EOF(),RECNO(),1)
  2023. m.crccode = "0"
  2024. * Get the headers for all the platforms we are generating
  2025. SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  2026.    m.thiscode = ALLTRIM(SYS(2007,proccode))
  2027.    DO CASE
  2028.    CASE m.crccode = "0"
  2029.       m.crccode = m.thiscode
  2030.    CASE m.thiscode <> m.crccode AND m.crccode <> "0"
  2031.       RETURN .F.
  2032.    ENDCASE
  2033. ENDSCAN
  2034. GOTO m.in_rec
  2035. RETURN .T.
  2036.  
  2037. *
  2038. * ISGENPLAT - Is this platform one of the ones being generated?
  2039. *
  2040. *!*****************************************************************************
  2041. *!
  2042. *!       Function: ISGENPLAT
  2043. *!
  2044. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  2045. *!               : PROCSMATCH()       (function  in GENSCRN.PRG)
  2046. *!               : SCANPROC           (procedure in GENSCRN.PRG)
  2047. *!
  2048. *!*****************************************************************************
  2049. FUNCTION isgenplat
  2050. PARAMETER m.platname
  2051. RETURN IIF(ASCAN(g_platforms,ALLTRIM(UPPER(m.platname))) > 0, .T. , .F. )
  2052.  
  2053. *
  2054. * PUTPROCHEAD - Emit the procedure and function heading if we haven't done
  2055. *
  2056. *!*****************************************************************************
  2057. *!
  2058. *!      Procedure: PUTPROCHEAD
  2059. *!
  2060. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  2061. *!
  2062. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2063. *!
  2064. *!*****************************************************************************
  2065. PROCEDURE putprochead
  2066. PARAMETER m.scrnno, m.filname
  2067. IF m.g_isfirstproc
  2068.    \
  2069.    DO commentblock WITH g_screens[m.scrnno,1], " Supporting Procedures and Functions "
  2070.    \#REGION <<INT(m.scrnno)>>
  2071.    m.g_isfirstproc = .F.
  2072. ENDIF
  2073. RETURN
  2074.  
  2075. *
  2076. * EXTRACTPROCS - Output the procedures for the current platform in the current screen
  2077. *
  2078. *!*****************************************************************************
  2079. *!
  2080. *!      Procedure: EXTRACTPROCS
  2081. *!
  2082. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  2083. *!
  2084. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2085. *!               : MATCH()            (function  in GENSCRN.PRG)
  2086. *!               : GETPROCNUM()       (function  in GENSCRN.PRG)
  2087. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  2088. *!               : HASCONFLICT()      (function  in GENSCRN.PRG)
  2089. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2090. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  2091. *!               : PROCCOMMENTBLOCK   (procedure in GENSCRN.PRG)
  2092. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  2093. *!
  2094. *!*****************************************************************************
  2095. PROCEDURE extractprocs
  2096. * We only get here if we are emitting for multiple platforms and the cleanup snippets
  2097. * for all platforms are not identical.  We are positioned on a screen header record for
  2098. * the g_genvers platform.
  2099. PARAMETER m.scrnno
  2100.  
  2101. PRIVATE m.hascontin, m.iscontin, m.sniplen, m.i, m.thisline, m.pnum, m.word1, m.word2
  2102.  
  2103. _MLINE = 0
  2104. m.sniplen   = LEN(proccode)
  2105. m.numlines  = MEMLINES(proccode)
  2106. m.hascontin = .F.
  2107. DO WHILE _MLINE < m.sniplen
  2108.    m.thisline  = UPPER(ALLTRIM(MLINE(proccode,1, _MLINE)))
  2109.    m.iscontin  = m.hascontin
  2110.    m.hascontin = RIGHT(m.thisline,1) = ';'
  2111.    IF LEFT(m.thisline,1) $ "PF" AND !m.iscontin
  2112.       m.word1 = wordnum(m.thisline, 1)
  2113.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2114.          m.word2 = wordnum(m.thisline,2)
  2115.          * Does this procedure have a name conflict?
  2116.          m.pnum = getprocnum(m.word2)
  2117.          IF pnum > 0
  2118.             DO CASE
  2119.             CASE g_procs[m.pnum,C_MAXPLATFORMS+2]
  2120.                * This one has already been generated.  Skip past it now.
  2121.                DO emitproc WITH .F., m.thisline, m.sniplen, m.scrnno
  2122.                LOOP
  2123.             CASE hasconflict(pnum)
  2124.                * Name collision detected.  Output bracketed code for all platforms
  2125.                DO putmsg WITH "Generating code for procedure/function ";
  2126.                   +LOWER(g_procs[m.pnum,1])
  2127.                DO updtherm WITH (70 + (25/g_procnames) * m.pnum) * m.g_numplatforms
  2128.                DO proccommentblock WITH g_screens[m.scrnno,1], " "+PROPER(word1);
  2129.                   +" " + g_procs[m.pnum,1]
  2130.                DO emitbracket WITH m.pnum, m.scrnno
  2131.             OTHERWISE
  2132.                * This procedure has no name collision and has not been emitted yet.
  2133.                DO putmsg WITH "Generating code for procedure/function ";
  2134.                   +LOWER(g_procs[m.pnum,1])
  2135.                DO updtherm WITH (70 + (25/g_procnames) * m.pnum) * m.g_numplatforms
  2136.                DO proccommentblock WITH g_screens[m.scrnno,1], " "+PROPER(word1);
  2137.                   +" " + g_procs[m.pnum,1]
  2138.                DO emitproc WITH .T., m.thisline, m.sniplen, m.scrnno
  2139.             ENDCASE
  2140.             g_procs[pnum,C_MAXPLATFORMS+2] = .T.
  2141.          ENDIF
  2142.       ENDIF
  2143.    ENDIF
  2144. ENDDO
  2145. RETURN
  2146.  
  2147. *
  2148. * EMITPROC - Scan through the next procedure/function in the current cleanup snippet.
  2149. *            If dowrite is TRUE, emit the code as we go.  Otherwise, just skip over it
  2150. *            and advance _MLINE.
  2151. *
  2152. *!*****************************************************************************
  2153. *!
  2154. *!      Procedure: EMITPROC
  2155. *!
  2156. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2157. *!
  2158. *!          Calls: WRITELINE          (procedure in GENSCRN.PRG)
  2159. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  2160. *!               : MATCH()            (function  in GENSCRN.PRG)
  2161. *!
  2162. *!*****************************************************************************
  2163. PROCEDURE emitproc
  2164. * We are positioned on the PROCEDURE or FUNCTION line now and there isn't a name
  2165. * conflict.
  2166. PARAMETER m.dowrite, m.thisline, m.sniplen, m.scrnno
  2167. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  2168.    m.iscontin, m.hascontin
  2169. m.hascontin = .F.
  2170. m.done = .F.
  2171.  
  2172. * Write the PROCEDURE/FUNCTION statement
  2173. m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2174. IF m.dowrite    && actually emit the procedure?
  2175.    DO writeline WITH m.thisline, m.g_genvers, m.upline, m.scrnno
  2176. ENDIF
  2177.  
  2178. * Write the body of the procedure
  2179. DO WHILE !m.done AND _MLINE < m.sniplen
  2180.    m.lastmline = _MLINE          && note where this line started
  2181.  
  2182.    m.line = MLINE(proccode,1, _MLINE)
  2183.    m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2184.  
  2185.    m.iscontin = m.hascontin
  2186.    m.hascontin = RIGHT(m.upline,1) = ';'
  2187.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2188.       m.word1 = wordnum(m.upline, 1)
  2189.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2190.          done = .T.
  2191.          _MLINE = m.lastmline    && drop back one line and stop writing
  2192.          LOOP
  2193.       ENDIF
  2194.    ENDIF
  2195.  
  2196.    IF m.dowrite    && actually emit the procedure?
  2197.       DO writeline WITH m.line, m.g_genvers, m.upline, m.scrnno
  2198.    ENDIF
  2199.  
  2200. ENDDO
  2201. RETURN
  2202.  
  2203. *
  2204. * EMITBRACKET - Emit DO CASE/CASE _DOS brackets and call putproc to emit code for this procedure
  2205. *
  2206. *!*****************************************************************************
  2207. *!
  2208. *!      Procedure: EMITBRACKET
  2209. *!
  2210. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2211. *!
  2212. *!          Calls: PUSHINDENT         (procedure in GENSCRN.PRG)
  2213. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  2214. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  2215. *!
  2216. *!*****************************************************************************
  2217. PROCEDURE emitbracket
  2218. PARAMETER m.pnum, m.scrnno
  2219. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  2220.    m.iscontin, m.hascontin, m.i
  2221. m.hascontin = .F.
  2222. m.done = .F.
  2223. \
  2224. \PROCEDURE <<g_procs[m.pnum,1]>>
  2225. IF !EMPTY(g_procs[m.pnum,C_MAXPLATFORMS+3])
  2226.    \PARAMETERS <<g_procs[m.pnum,C_MAXPLATFORMS+3]>>
  2227. ENDIF
  2228. \DO CASE
  2229.  
  2230. * Peek ahead and get the parameter statement
  2231. FOR m.platnum = 1 TO c_maxplatforms
  2232.    IF g_procs[m.pnum,m.platnum+1] < 0
  2233.       * There was no procedure for this platform
  2234.       LOOP
  2235.    ENDIF
  2236.    \CASE <<"_"+g_platlist[m.platnum]>>
  2237.    DO pushindent
  2238.    DO putproc WITH m.platnum, m.pnum, m.scrnno
  2239.    DO popindent
  2240. ENDFOR
  2241. \ENDCASE
  2242. RETURN
  2243.  
  2244. *
  2245. * PUTPROC - Write actual code for procedure procnum in platform platnum
  2246. *
  2247. *!*****************************************************************************
  2248. *!
  2249. *!      Procedure: PUTPROC
  2250. *!
  2251. *!      Called by: EMITBRACKET        (procedure in GENSCRN.PRG)
  2252. *!
  2253. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2254. *!               : MATCH()            (function  in GENSCRN.PRG)
  2255. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2256. *!
  2257. *!*****************************************************************************
  2258. PROCEDURE putproc
  2259. PARAMETER m.platnum, m.procnum, m.scrnno
  2260. PRIVATE m.in_rec, m.oldmine, m.done, m.line, m.upline, m.iscontin, m.hascontin, ;
  2261.    m.word1, m.word2
  2262.  
  2263. m.in_rec    = RECNO()
  2264. * Store the _MLINE position in the original snippet
  2265. m.oldmline  = _MLINE
  2266. m.hascontin = .F.       && the previous line was not a continuation line.
  2267. LOCATE FOR platform = g_platlist[m.platnum] AND objtype = c_otscreen
  2268. IF FOUND()
  2269.    * go to the PROCEDURE/FUNCTION statement
  2270.    _MLINE = g_procs[m.procnum,m.platnum+1]
  2271.    * Skip the PROCEDURE line, since we've already output one.
  2272.    m.line = MLINE(proccode,1, _MLINE)
  2273.  
  2274.    * We are now positioned at the line following the procedure statement.
  2275.    * Write until the end of the snippet or the next procedure.
  2276.    m.done = .F.
  2277.    DO WHILE !m.done
  2278.       m.line = MLINE(proccode,1, _MLINE)
  2279.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2280.       m.iscontin = m.hascontin
  2281.       m.hascontin = RIGHT(m.upline,1) = ';'
  2282.       IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2283.          m.word1 = wordnum(m.upline, 1)
  2284.          IF RIGHT(m.word1,1) = ';'
  2285.             m.word1 = LEFT(m.word1,LEN(m.word1)-1)
  2286.          ENDIF
  2287.  
  2288.          DO CASE
  2289.          CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2290.             * Stop when we encounter the next snippet
  2291.             m.done = .T.
  2292.             LOOP
  2293.          CASE match(m.word1,"PARAMETERS")
  2294.             * Don't output it, but keep scanning for other code
  2295.             DO WHILE m.hascontin
  2296.                m.line = MLINE(proccode,1, _MLINE)
  2297.                m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2298.                m.hascontin = RIGHT(m.upline,1) = ';'
  2299.             ENDDO
  2300.             LOOP
  2301.          ENDCASE
  2302.       ENDIF
  2303.  
  2304.       DO writeline WITH m.line, g_platlist[m.platnum], m.upline, m.scrnno
  2305.  
  2306.       * Stop if we've run out of snippet
  2307.       IF _MLINE >= LEN(proccode)
  2308.          m.done = .T.
  2309.       ENDIF
  2310.    ENDDO
  2311. ENDIF
  2312.  
  2313. GOTO m.in_rec
  2314. * Restore the _MLINE position in the main snippet we are outputing
  2315. _MLINE = m.oldmline
  2316.  
  2317. *
  2318. * GETPROCNUM - Return the g_procs array position of the procedure named pname
  2319. *
  2320. *!*****************************************************************************
  2321. *!
  2322. *!       Function: GETPROCNUM
  2323. *!
  2324. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2325. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2326. *!
  2327. *!*****************************************************************************
  2328. FUNCTION getprocnum
  2329. PARAMETER m.pname
  2330. PRIVATE m.i
  2331. FOR m.i = 1 TO g_procnames
  2332.    IF g_procs[m.i,1] == m.pname
  2333.       RETURN m.i
  2334.    ENDIF
  2335. ENDFOR
  2336. RETURN  0
  2337.  
  2338. *
  2339. * HASCONFLICT - Is there a name collision for procedure number num?
  2340. *
  2341. *!*****************************************************************************
  2342. *!
  2343. *!       Function: HASCONFLICT
  2344. *!
  2345. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2346. *!
  2347. *!*****************************************************************************
  2348. FUNCTION hasconflict
  2349. PARAMETER m.num
  2350. PRIVATE m.i, m.cnt
  2351. m.cnt = 0
  2352. FOR m.i = 1 TO c_maxplatforms
  2353.    IF g_procs[m.num,m.i+1] > 0
  2354.       m.cnt = m.cnt +1
  2355.    ENDIF
  2356. ENDFOR
  2357. RETURN IIF(m.cnt > 1,.T.,.F.)
  2358.  
  2359.  
  2360. *
  2361. * GETFIRSTPROC - Find first PROCEDURE or FUNCTION statement in a cleanup
  2362. *                snippet and return the line number on which it occurs.
  2363. *
  2364. *!*****************************************************************************
  2365. *!
  2366. *!       Function: GETFIRSTPROC
  2367. *!
  2368. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  2369. *!
  2370. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2371. *!               : MATCH()            (function  in GENSCRN.PRG)
  2372. *!
  2373. *!*****************************************************************************
  2374. FUNCTION getfirstproc
  2375. PARAMETER m.snipname
  2376. PRIVATE proclineno, numlines, word1, first_space
  2377. _MLINE = 0
  2378. m.numlines = MEMLINES(&snipname)
  2379. FOR m.proclineno = 1 TO m.numlines
  2380.    m.line  = MLINE(&snipname, 1, _MLINE)
  2381.    m.line  = UPPER(LTRIM(m.line))
  2382.    m.word1 = wordnum(m.line,1)
  2383.    IF !EMPTY(m.word1) AND (match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION"))
  2384.       RETURN m.proclineno
  2385.    ENDIF
  2386. ENDFOR
  2387. RETURN 0
  2388.  
  2389. *
  2390. * SCANPROC - Find unique procedure names in cleanup snippets for all platforms
  2391. *
  2392. *!*****************************************************************************
  2393. *!
  2394. *!      Procedure: SCANPROC
  2395. *!
  2396. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  2397. *!
  2398. *!          Calls: PROCSMATCH()       (function  in GENSCRN.PRG)
  2399. *!               : ISGENPLAT()        (function  in GENSCRN.PRG)
  2400. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2401. *!
  2402. *!*****************************************************************************
  2403. PROCEDURE scanproc
  2404. PRIVATE m.in_rec
  2405. * See if all the cleanup snippets are the same.  If so, stop now.
  2406. m.g_procsmatch = procsmatch()
  2407. IF !m.g_procsmatch
  2408.    FOR m.g_screen = 1 TO m.g_nscreens
  2409.       m.dbalias = g_screens[m.g_screen,5]
  2410.       SELECT (m.dbalias)
  2411.  
  2412.       IF !g_screens[m.g_screen,6]      && not applicable for FoxPro 2.0 screens
  2413.          SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  2414.             DO updprocarray
  2415.          ENDSCAN
  2416.       ENDIF
  2417.    ENDFOR
  2418.    m.g_screen = 0
  2419. ENDIF
  2420. RETURN
  2421.  
  2422. *
  2423. * UPDPROCARRAY - Pick out the procedures names in the current cleanup snippet and call
  2424. *                  AddProcName to update the g_procs array.
  2425. *
  2426. *!*****************************************************************************
  2427. *!
  2428. *!      Procedure: UPDPROCARRAY
  2429. *!
  2430. *!      Called by: SCANPROC           (procedure in GENSCRN.PRG)
  2431. *!
  2432. *!          Calls: VERSIONCAP()       (function  in GENSCRN.PRG)
  2433. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2434. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  2435. *!               : MATCH()            (function  in GENSCRN.PRG)
  2436. *!               : ADDPROCNAME        (procedure in GENSCRN.PRG)
  2437. *!               : GETPROCNUM()       (function  in GENSCRN.PRG)
  2438. *!               : CLEANPARAM()       (function  in GENSCRN.PRG)
  2439. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  2440. *!
  2441. *!*****************************************************************************
  2442. PROCEDURE updprocarray
  2443. PRIVATE m.i, m.numlines, m.line, m.upline, m.word1, m.word2, m.iscontin, m.hascontin, ;
  2444.    m.lastmline, m.thisproc
  2445.  
  2446. DO putmsg WITH "Scanning cleanup snippet for ";
  2447.    +versioncap( IIF(TYPE("platform")<>"U",platform,"DOS") )
  2448.  
  2449. _MLINE = 0
  2450. m.numlines = MEMLINES(proccode)
  2451. m.hascontin = .F.
  2452. FOR m.i = 1 TO m.numlines
  2453.    m.lastmline = _MLINE                && note starting position of this line
  2454.    m.line      = MLINE(proccode,1, _MLINE)
  2455.    m.upline    = UPPER(ALLTRIM(m.line))
  2456.    m.iscontin  = m.hascontin
  2457.    m.hascontin = RIGHT(m.upline,1) = ';'
  2458.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2459.       m.word1 = CHRTRAN(wordnum(m.upline, 1),';','')
  2460.       DO CASE
  2461.       CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2462.          m.word2 = wordnum(m.upline,2)
  2463.          DO addprocname WITH m.word2, platform, m.i, m.lastmline
  2464.          m.lastproc = m.word2
  2465.       CASE match(m.word1,"PARAMETERS")
  2466.          * Associate this parameter statement with the last procedure or function
  2467.          m.thisproc = getprocnum(m.lastproc)
  2468.          IF m.thisproc > 0
  2469.             m.thisparam = ALLTRIM(SUBSTR(m.upline,AT(' ',m.upline)+1))
  2470.             * Deal with continued PARAMETER lines
  2471.             DO WHILE m.hascontin AND m.i <= m.numlines
  2472.                m.lastmline = _MLINE                && note the starting position of this line
  2473.                m.line   = MLINE(proccode,1, _MLINE)
  2474.                m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2475.                m.thisparam = ;
  2476.                   m.thisparam + CHR(13)+CHR(10) + m.line
  2477.                m.hascontin = RIGHT(m.upline,1) = ';'
  2478.                m.i = m.i + 1
  2479.             ENDDO
  2480.             * Make sure that this parameter matches any others we've seen for this function
  2481.             DO CASE
  2482.             CASE EMPTY(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2483.                * First occurrence, or one platform has a parameter statement and another doesn't
  2484.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  2485.             CASE cleanparam(m.thisparam) == cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2486.                * It matches--do nothing
  2487.             CASE cleanparam(m.thisparam) = cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2488.                * The new one is a superset of the existing one.  Use the longer one.
  2489.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  2490.             CASE cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3]) = cleanparam(m.thisparam)
  2491.                * The old one is a superset of the new one.  Keep the longer one.
  2492.             OTHERWISE
  2493.                DO errorhandler WITH "Different parameters for "+g_procs[m.thisproc,1],;
  2494.                   LINENO(),c_error_3
  2495.             ENDCASE
  2496.          ENDIF
  2497.       ENDCASE
  2498.    ENDIF
  2499. ENDFOR
  2500. RETURN
  2501.  
  2502. *
  2503. * ADDPROCNAME - Update g_procs with pname data
  2504. *
  2505. *!*****************************************************************************
  2506. *!
  2507. *!      Procedure: ADDPROCNAME
  2508. *!
  2509. *!      Called by: UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2510. *!
  2511. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2512. *!
  2513. *!*****************************************************************************
  2514. PROCEDURE addprocname
  2515. PARAMETER m.pname, m.platname, m.linenum, m.lastmline
  2516. PRIVATE m.rnum, m.platformcol, m.i, m.j
  2517. IF EMPTY(m.pname)
  2518.    RETURN
  2519. ENDIF
  2520.  
  2521. * Look up this name in the procedures array
  2522. m.rnum = 0
  2523. FOR m.i = 1 TO m.g_procnames
  2524.    IF g_procs[m.i,1] == m.pname
  2525.       m.rnum = m.i
  2526.       EXIT
  2527.    ENDIF
  2528. ENDFOR
  2529.  
  2530. IF m.rnum = 0
  2531.    * New name
  2532.    g_procnames = m.g_procnames + 1
  2533.    DIMENSION g_procs[m.g_procnames,C_MAXPLATFORMS+3]
  2534.    g_procs[m.g_procnames,1] = UPPER(ALLTRIM(m.pname))
  2535.    FOR m.j = 1 TO c_maxplatforms
  2536.       g_procs[m.g_procnames,m.j + 1] = -1
  2537.    ENDFOR
  2538.    g_procs[m.g_procnames,C_MAXPLATFORMS+2] = .F.   && not emitted yet
  2539.    g_procs[m.g_procnames,C_MAXPLATFORMS+3] = ""    && parameter statement
  2540.    m.rnum = m.g_procnames
  2541. ENDIF
  2542.  
  2543. m.platformcol = getplatnum(m.platname) + 1
  2544. IF m.platformcol > 1
  2545.    g_procs[m.rnum, m.platformcol] = m.lastmline
  2546. ENDIF
  2547. RETURN
  2548.  
  2549. *
  2550. * GETPLATNUM - Return the g_platlist array index given a platform name
  2551. *
  2552. *!*****************************************************************************
  2553. *!
  2554. *!       Function: GETPLATNUM
  2555. *!
  2556. *!      Called by: PREPWNAMES         (procedure in GENSCRN.PRG)
  2557. *!               : ADDPROCNAME        (procedure in GENSCRN.PRG)
  2558. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2559. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2560. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  2561. *!
  2562. *!*****************************************************************************
  2563. FUNCTION getplatnum
  2564. PARAMETER m.platname
  2565. PRIVATE m.i
  2566. FOR m.i = 1 TO c_maxplatforms
  2567.    IF g_platlist[m.i] == UPPER(ALLTRIM(m.platname))
  2568.       RETURN m.i
  2569.    ENDIF
  2570. ENDFOR
  2571. RETURN 0
  2572.  
  2573. *
  2574. * GENPARAMETER - Generate the PARAMETER statement
  2575. *
  2576. *!*****************************************************************************
  2577. *!
  2578. *!      Procedure: GENPARAMETER
  2579. *!
  2580. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  2581. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  2582. *!
  2583. *!*****************************************************************************
  2584. PROCEDURE genparameter
  2585. IF !EMPTY(m.g_parameter)
  2586.    \PARAMETERS <<m.g_parameter>>
  2587. ENDIF
  2588. RETURN
  2589.  
  2590. *
  2591. * GENSECT1 - Generate #SECTION 1 code for all screens.
  2592. *
  2593. *!*****************************************************************************
  2594. *!
  2595. *!      Procedure: GENSECT1
  2596. *!
  2597. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  2598. *!
  2599. *!          Calls: TICK()             (function  in GENSCRN.PRG)
  2600. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  2601. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  2602. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2603. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  2604. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  2605. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2606. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  2607. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2608. *!               : TOCK()             (function  in GENSCRN.PRG)
  2609. *!
  2610. *!*****************************************************************************
  2611. PROCEDURE gensect1
  2612. PRIVATE m.i, m.dbalias, m.string, m.loop, m.j, m.end, m.msg, m.thisline
  2613. m.msg =  'Generating Setup Code'
  2614. IF multiplat()
  2615.    m.msg = m.msg + " for "+versioncap(m.g_genvers)
  2616. ENDIF
  2617. DO putmsg WITH m.msg
  2618. m.string = " Setup Code - SECTION 1"
  2619.  
  2620. FOR m.i = 1 TO m.g_nscreens
  2621.    m.g_screen = m.i
  2622.  
  2623.    m.dbalias = g_screens[m.i,5]
  2624.    SELECT (m.dbalias)
  2625.    DO seekheader WITH m.i
  2626.    IF EMPTY (setupcode)
  2627.       LOOP
  2628.    ENDIF
  2629.  
  2630.    m.g_sect1start= c_fromone
  2631.    m.g_sect2start= c_untilend
  2632.    m.loop  = .F.
  2633.  
  2634.    IF ATCLINE("#SECT", setupcode) <> 0
  2635.       m.g_sect1start = findsection(1, setupcode)+1
  2636.       m.g_sect2start = findsection(2, setupcode)
  2637.    ENDIF
  2638.    
  2639.    DO notedirectives WITH (m.i)
  2640.  
  2641.    * See if there are nondirective statements in SECTION 1
  2642.    IF m.g_sect2start-m.g_sect1start <= 3
  2643.       IF m.g_sect2start = 0
  2644.          m.end = MEMLINES(setupcode)
  2645.       ELSE
  2646.          m.end = m.g_sect2start-1
  2647.       ENDIF
  2648.       m.loop = .T.
  2649.       m.j = m.g_sect1start
  2650.       DO WHILE m.j <= m.end
  2651.          m.thisline = MLINE(setupcode,m.j)
  2652.          IF AT('#',m.thisline) <> 1 OR AT('#INSE',m.thisline) = 1
  2653.             m.loop = .F.
  2654.             EXIT
  2655.          ENDIF
  2656.          m.j = m.j + 1
  2657.       ENDDO
  2658.    ENDIF
  2659.    IF m.loop
  2660.       LOOP
  2661.    ENDIF
  2662.    IF NOT (m.g_sect1start=1 OR (m.g_sect1start=m.g_sect2start) OR ;
  2663.          (m.g_sect2start<>0 AND m.g_sect1start>m.g_sect2start))
  2664.  
  2665.       DO commentblock WITH g_screens[m.i,1], m.string
  2666.       \#REGION <<INT(m.i)>>
  2667.       DO writecode WITH setupcode, getplatname(m.i), m.g_sect1start, m.g_sect2start, m.i, 'setup'
  2668.    ENDIF
  2669. ENDFOR
  2670. m.g_screen = 0
  2671.  
  2672. *
  2673. * GENSECT2 - Generate Setup code #SECTION 2.
  2674. *
  2675. *!*****************************************************************************
  2676. *!
  2677. *!      Procedure: GENSECT2
  2678. *!
  2679. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  2680. *!
  2681. *!          Calls: TICK()             (function  in GENSCRN.PRG)
  2682. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  2683. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  2684. *!               : NOTEDIRECTIVES     (procedure in GENSCRN.PRG)
  2685. *!               : COUNTDIRECTIVES()  (function  in GENSCRN.PRG)
  2686. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2687. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  2688. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2689. *!               : TOCK()             (function  in GENSCRN.PRG)
  2690. *!
  2691. *!*****************************************************************************
  2692. PROCEDURE gensect2
  2693. PRIVATE m.i, m.dbalias, m.string, m.endline, m.srtline, ;
  2694.    m.linecnt, m.lcnt, m.sect1, m.sect2
  2695. m.string = " Setup Code - SECTION 2"
  2696.  
  2697. FOR m.i = 1 TO m.g_nscreens
  2698.    m.g_screen = m.i
  2699.    m.dbalias = g_screens[m.i,5]
  2700.    SELECT (m.dbalias)
  2701.    DO seekheader WITH m.i
  2702.    IF EMPTY (setupcode)
  2703.       LOOP
  2704.    ENDIF
  2705.  
  2706.    m.g_sect1start= c_fromone
  2707.    m.g_sect2start= c_untilend
  2708.    m.loop  = .F.
  2709.  
  2710.    IF ATCLINE("#SECT", setupcode)<>0
  2711.       m.g_sect1start = findsection(1, setupcode)+1
  2712.       m.g_sect2start = findsection(2, setupcode)
  2713.    ENDIF
  2714.  
  2715.    m.sect1 = m.g_sect1start <> 0
  2716.    m.sect2 = m.g_sect2start <> 0
  2717.  
  2718.    DO notedirectives WITH (m.i)
  2719.    m.lcnt = countdirectives(m.sect1, m.sect2, m.i)
  2720.  
  2721.    IF m.g_sect2start = 0 AND m.g_sect1start > 1
  2722.       * No Section2 to emit
  2723.       LOOP
  2724.    ENDIF
  2725.  
  2726.    m.linecnt = MEMLINES(setupcode)
  2727.  
  2728.    IF m.linecnt > m.lcnt AND m.g_sect2start < m.linecnt
  2729.       DO commentblock WITH g_screens[m.i,1], m.string
  2730.       \#REGION <<INT(m.i)>>
  2731.       DO writecode WITH setupcode, getplatname(m.i), m.g_sect2start, c_untilend, m.i, 'setup'
  2732.    ENDIF
  2733. ENDFOR
  2734. m.g_screen = 0
  2735.  
  2736. *
  2737. * COUNTDIRECTIVES - Count directives in setup snippet.
  2738. *
  2739. *!*****************************************************************************
  2740. *!
  2741. *!       Function: COUNTDIRECTIVES
  2742. *!
  2743. *!      Called by: GENSECT2           (procedure in GENSCRN.PRG)
  2744. *!
  2745. *!*****************************************************************************
  2746. FUNCTION countdirectives
  2747. * This function counts the directives in setup.  It is used to figure out if there
  2748. * are any non-directive statements in the setup snippet.
  2749. PARAMETER m.sect1, m.sect2, m.scrnno
  2750. PRIVATE m.numlines, m.i, m.lcnt, m.thisline, m.upline
  2751. m.lcnt = 0
  2752. IF AT('#',setupcode) > 0
  2753.    * AT test is optimization to avoid processing the snippet when there are no directives
  2754.    m.numlines = MEMLINES(setupcode)
  2755.    _MLINE = 0
  2756.    FOR m.i = 1 TO m.numlines
  2757.       m.thisline = MLINE(setupcode, 1, _MLINE)
  2758.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2759.       IF LEFT(m.upline,1) = '#' AND !(LEFT(m.upline,5) = "#INSE")
  2760.          m.lcnt = m.lcnt + 1
  2761.       ENDIF
  2762.    ENDFOR
  2763. ENDIF
  2764. RETURN m.lcnt
  2765.  
  2766. *
  2767. * NOTEDIRECTIVES - Check for global directives such as #READCLAUSES, #NOREAD
  2768. *
  2769. *!*****************************************************************************
  2770. *!
  2771. *!      Procedure: NOTEDIRECTIVES
  2772. *!
  2773. *!      Called by: GENSECT2           (procedure in GENSCRN.PRG)
  2774. *!
  2775. *!*****************************************************************************
  2776. PROCEDURE notedirectives
  2777. * This function notes certain directives in the setup snippet and populates various
  2778. * global variables so that we don't have to keep going back to the snippet to find
  2779. * things.
  2780. PARAMETERS m.scrnno
  2781. PRIVATE m.numlines, m.i, m.thisline, m.upline
  2782. m.g_noread    = .F.
  2783. m.g_noreadplain = .F.
  2784. IF AT('#',setupcode) > 0
  2785.    * AT test is optimization to avoid processing the snippet when there are no directives
  2786.    m.numlines = MEMLINES(setupcode)
  2787.    _MLINE = 0
  2788.    FOR m.i = 1 TO m.numlines
  2789.       m.thisline = MLINE(setupcode, 1, _MLINE)
  2790.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2791.       IF LEFT(m.upline,1) = '#'
  2792.          DO CASE
  2793.          CASE LEFT(m.upline,5) = "#READ"   && #READCLAUSES - Additional READ clauses
  2794.             IF m.g_rddir = .F.
  2795.                m.g_rddir = .T.
  2796.                m.g_rddirno = m.scrnno
  2797.             ENDIF
  2798.          CASE LEFT(m.upline,5) = "#NORE"   && #NOREAD - omit the READ statement
  2799.             m.g_noread = .T.
  2800.             IF AT(m.g_dblampersand,m.upline) > 0
  2801.                m.upline = LEFT(m.upline,AT(m.g_dblampersand,m.upline)-1)
  2802.             ENDIF 
  2803.             m.g_noreadplain = IIF(ATC(' PLAI',m.upline) > 0,.T.,.F.)
  2804.             IF m.g_noreadplain
  2805.                 m.g_openfiles    = .F.
  2806.                     m.g_closefiles   = .F.
  2807.                     m.g_defwin       = .F.
  2808.                     m.g_relwin       = .F.
  2809.             ENDIF
  2810.          ENDCASE
  2811.       ENDIF
  2812.    ENDFOR
  2813. ENDIF
  2814.  
  2815. *
  2816. * FINDSECTION - Find #SECT... directive.
  2817. *
  2818. * Description:
  2819. * Locate and return the line on which the generator directive '#SECT'
  2820. * is located on.  If no valid directive found, return 0.
  2821. *
  2822. *!*****************************************************************************
  2823. *!
  2824. *!       Function: FINDSECTION
  2825. *!
  2826. *!      Called by: GENSECT1           (procedure in GENSCRN.PRG)
  2827. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  2828. *!
  2829. *!          Calls: TICK()             (function  in GENSCRN.PRG)
  2830. *!               : TOCK()             (function  in GENSCRN.PRG)
  2831. *!
  2832. *!*****************************************************************************
  2833. FUNCTION findsection
  2834. PARAMETER m.sectionid, m.memo
  2835. PRIVATE m.line, m.linecnt, m.textline
  2836. m.line    = ATCLINE("#SECT", m.memo)
  2837. m.linecnt = MEMLINE(m.memo)
  2838. DO WHILE m.line <= m.linecnt
  2839.    m.textline = LTRIM(MLINE(m.memo, m.line))
  2840.    IF ATC("#SECT", m.textline)=1
  2841.       IF m.sectionid = 1
  2842.          IF AT("1", m.textline)<>0
  2843.             m.sect1 = .T.
  2844.             RETURN m.line
  2845.          ELSE
  2846.             RETURN 0
  2847.          ENDIF
  2848.       ELSE
  2849.          IF AT("2", m.textline)<>0
  2850.             m.sect2 = .T.
  2851.             RETURN m.line
  2852.          ENDIF
  2853.       ENDIF
  2854.    ENDIF
  2855.    m.line = m.line + 1
  2856. ENDDO
  2857. RETURN 0
  2858.  
  2859. *
  2860. * WRITECODE - Write contents of a memo to a low level file.
  2861. *
  2862. * Description:
  2863. * Receive a memo field as a parameter and write its contents out
  2864. * to the currently opened low level file whose handle is stored
  2865. * in the system memory variable _TEXT.  Contents of the system
  2866. * memory variable _PRETEXT will affect the positioning of the
  2867. * generated text.
  2868. *
  2869. *!*****************************************************************************
  2870. *!
  2871. *!      Procedure: WRITECODE
  2872. *!
  2873. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  2874. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  2875. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  2876. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  2877. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  2878. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  2879. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  2880. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  2881. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  2882. *!               : INSERTFILE         (procedure in GENSCRN.PRG)
  2883. *!
  2884. *!          Calls: TICK()             (function  in GENSCRN.PRG)
  2885. *!               : GETPLATNUM()       (function  in GENSCRN.PRG)
  2886. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  2887. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  2888. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  2889. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  2890. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2891. *!               : TOCK()             (function  in GENSCRN.PRG)
  2892. *!
  2893. *!*****************************************************************************
  2894. PROCEDURE writecode
  2895. PARAMETER m.memo, m.platname, m.start, m.end, m.scrnno, m.insetup
  2896. PRIVATE m.linecnt, m.i, m.line, m.upline, m.expr, m.platnum, m.at
  2897.  
  2898. m.start = MAX(1,m.start)  && if zero, start at 1
  2899.  
  2900. IF m.end > m.start
  2901.    m.linecnt = m.end-1
  2902. ELSE
  2903.    m.linecnt = MEMLINES(m.memo)
  2904. ENDIF
  2905.  
  2906. m.platnum = getplatnum(m.platname)
  2907.  
  2908. IF NOT EMPTY(m.insetup)
  2909.    * First position _MLINE at the right spot
  2910.    _MLINE = 0
  2911.    FOR m.i = 1 TO m.start - 1
  2912.       m.line = MLINE(m.memo, 1, _MLINE)
  2913.    ENDFOR
  2914.    FOR m.i = m.start TO m.linecnt
  2915.       m.line = MLINE(m.memo, 1, _MLINE)
  2916.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2917.       IF !geninsertcode(@upline,m.scrnno, m.insetup, m.platname)
  2918.          m.isparam =  isparameter(@upline)
  2919.          DO CASE
  2920.          CASE m.isparam
  2921.             * Accumulate continuation line but don't output it.
  2922.             DO WHILE RIGHT(RTRIM(m.upline),1) = ';'
  2923.                m.line = MLINE(m.memo, 1, _MLINE)
  2924.                m.upline = m.upline + LTRIM(UPPER(m.line))
  2925.             ENDDO
  2926.          CASE AT('#',m.upline) <> 1 OR ;
  2927.                (AT('#READ', m.upline) <> 1 AND ;
  2928.                AT('#ITSE', m.upline) <> 1 AND ;
  2929.                AT('#WNAM', m.upline) <> 1 AND ;
  2930.                AT('#WCLA', m.upline) <> 1 AND ;
  2931.                AT('#REDE', m.upline) <> 1 AND ;
  2932.                AT('#NAME', m.upline) <> 1 AND ;
  2933.                AT('#NORE', m.upline) <> 1 AND ;
  2934.                AT('#SECT', m.upline) <> 1 AND ;
  2935.                AT('#TRAN', m.upline) <> 1 AND ;
  2936.                AT('#INSE', m.upline) <> 1)
  2937.             IF NOT EMPTY(g_wnames[m.scrnno,m.platnum])
  2938.                m.at = atwname(g_wnames[m.scrnno,m.platnum], m.line)
  2939.                IF m.at <> 0 AND !iscomment(@upline)
  2940.                   m.expr = STUFF(m.line, m.at, ;
  2941.                      LEN(g_wnames[m.scrnno,m.platnum]), ;
  2942.                      g_screens[m.scrnno,2])
  2943.                   \<<m.expr>>
  2944.                ELSE
  2945.                   \<<m.line>>
  2946.                ENDIF
  2947.             ELSE
  2948.                \<<m.line>>
  2949.             ENDIF
  2950.          ENDCASE
  2951.       ENDIF
  2952.    ENDFOR
  2953. ELSE   && not in setup
  2954.    * First position _MLINE at the right spot
  2955.    _MLINE = 0
  2956.    FOR m.i = 1 TO m.start - 1
  2957.       m.line = MLINE(m.memo, 1, _MLINE)
  2958.    ENDFOR
  2959.    FOR m.i = m.start TO m.linecnt
  2960.       m.line = MLINE(m.memo, 1, _MLINE)
  2961.       m.upline = UPPER(LTRIM(CHRTRAN(m.line,chr(9),' ')))
  2962.       DO writeline WITH m.line, m.platname, m.upline, m.scrnno
  2963.    ENDFOR
  2964. ENDIF
  2965. RETURN
  2966.  
  2967. *
  2968. * WRITELINE - Emit a single line
  2969. *
  2970. *!*****************************************************************************
  2971. *!
  2972. *!      Procedure: WRITELINE
  2973. *!
  2974. *!      Called by: EMITPROC           (procedure in GENSCRN.PRG)
  2975. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  2976. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2977. *!
  2978. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2979. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  2980. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  2981. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  2982. *!
  2983. *!*****************************************************************************
  2984. PROCEDURE writeline
  2985. PARAMETER m.line, m.platname, m.upline, m.scrnno
  2986.  
  2987. PRIVATE m.at, m.platnum, m.expr
  2988.  
  2989. IF g_screens[m.scrnno,6]   && DOS 2.0 screen
  2990.    m.platnum = getplatnum("DOS")
  2991. ELSE
  2992.    m.platnum = getplatnum(m.platname)
  2993. ENDIF
  2994.  
  2995. IF !geninsertcode(@upline, m.scrnno, .F., m.platname)   && by reference to save time
  2996.    IF !EMPTY(g_wnames[m.scrnno, m.platnum])
  2997.       m.at = atwname(g_wnames[m.scrnno, m.platnum], m.line)
  2998.       IF m.at <> 0 AND !iscomment(@upline)
  2999.          m.expr = STUFF(m.line, m.at, ;
  3000.             LEN(g_wnames[m.scrnno, m.platnum]), ;
  3001.             g_screens[m.scrnno,2])
  3002.          \<<m.expr>>
  3003.       ELSE
  3004.          IF !INLIST(LEFT(m.upline,2),"*!","*:") ;
  3005.                AND AT('#NAME', m.upline) <> 1
  3006.             \<<m.line>>
  3007.          ENDIF
  3008.       ENDIF
  3009.    ELSE
  3010.       IF !INLIST(LEFT(m.upline,2),"*!","*:") AND ATC('#NAME',m.upline) = 0
  3011.          \<<m.line>>
  3012.       ENDIF
  3013.    ENDIF
  3014. ENDIF
  3015. RETURN
  3016.  
  3017. *
  3018. * GENINSERTCODE - Emit code from the #insert file, if any
  3019. *
  3020. *!*****************************************************************************
  3021. *!
  3022. *!      Procedure: GENINSERTCODE
  3023. *!
  3024. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3025. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3026. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3027. *!
  3028. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  3029. *!               : INSERTFILE         (procedure in GENSCRN.PRG)
  3030. *!
  3031. *!*****************************************************************************
  3032. PROCEDURE geninsertcode
  3033. * Strg has to be trimmed before entering GenInsertCode.  It may be passed by reference.
  3034. PARAMETER m.strg, m.scrnno, m.insetup, m.platname
  3035. PRIVATE m.word1, m.filname
  3036. IF AT("#INSE",m.strg) = 1
  3037.    m.word1 = wordnum(m.strg,1)
  3038.    m.filname = SUBSTR(m.strg,LEN(m.word1)+1)
  3039.    m.filname = ALLTRIM(CHRTRAN(m.filname,CHR(9)," "))
  3040.    DO insertfile WITH m.filname, m.scrnno, m.insetup, m.platname
  3041.    RETURN .T.
  3042. ELSE
  3043.    RETURN .F.
  3044. ENDIF
  3045.  
  3046. *
  3047. * ISPARAMETER - Determine if strg is a PARAMETERS statement
  3048. *
  3049. *!*****************************************************************************
  3050. *!
  3051. *!       Function: ISPARAMETER
  3052. *!
  3053. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3054. *!
  3055. *!          Calls: MATCH()            (function  in GENSCRN.PRG)
  3056. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  3057. *!
  3058. *!*****************************************************************************
  3059. FUNCTION isparameter
  3060. PARAMETER m.strg
  3061. PRIVATE m.ispar
  3062. m.ispar = .F.
  3063. IF !EMPTY(strg) AND match(CHRTRAN(wordnum(strg,1),';',''),"PARAMETERS")
  3064.    m.ispar = .T.
  3065. ENDIF
  3066. RETURN m.ispar
  3067.  
  3068. *
  3069. * ATWNAME - Determine if valid m.string is in this line.
  3070. *
  3071. * Description:
  3072. * Make sure that if m.string is in fact the string we want to do
  3073. * the substitution on.
  3074. *
  3075. *!*****************************************************************************
  3076. *!
  3077. *!       Function: ATWNAME
  3078. *!
  3079. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3080. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3081. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3082. *!
  3083. *!*****************************************************************************
  3084. FUNCTION atwname
  3085. PARAMETER m.string, m.line
  3086. PRIVATE m.pos, m.before, m.after
  3087. m.pos = AT(m.string,m.line)
  3088. IF m.pos = 0
  3089.    RETURN 0
  3090. ENDIF
  3091. IF m.pos = 1
  3092.    m.pos = AT(m.string+" ",m.line)
  3093. ELSE
  3094.    IF m.pos = LEN(m.line) - LEN(m.string) + 1
  3095.       m.pos = AT(" "+m.string,m.line)
  3096.       m.pos = IIF(m.pos<>0, m.pos+1,m.pos)
  3097.    ELSE
  3098.       m.before = SUBSTR(m.line,m.pos-1,1)
  3099.  
  3100.       IF m.before = c_under OR ;
  3101.             (m.before >= '0' AND m.before <= '9') OR ;
  3102.             (m.before >= 'a' AND m.before <= 'z') OR ;
  3103.             (m.before >= 'A' AND m.before <= 'Z')
  3104.  
  3105.          RETURN 0
  3106.       ENDIF
  3107.       m.after = SUBSTR(m.line,m.pos+LEN(m.string),1)
  3108.  
  3109.       IF m.after = c_under OR ;
  3110.             (m.after >= '0' AND m.after <= '9') OR ;
  3111.             (m.after >= 'a' AND m.after <= 'z') OR ;
  3112.             (m.after >= 'A' AND m.after <= 'Z')
  3113.  
  3114.          RETURN 0
  3115.       ENDIF
  3116.    ENDIF
  3117. ENDIF
  3118. RETURN m.pos
  3119.  
  3120. *
  3121. * ISCOMMENT - Determine if textline is a comment line.
  3122. *
  3123. *!*****************************************************************************
  3124. *!
  3125. *!       Function: ISCOMMENT
  3126. *!
  3127. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3128. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3129. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3130. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  3131. *!
  3132. *!*****************************************************************************
  3133. FUNCTION iscomment
  3134. PARAMETER m.textline
  3135. PRIVATE m.asterisk, m.isnote, m.ampersand, m.statement
  3136. IF EMPTY(m.textline)
  3137.    RETURN .F.
  3138. ENDIF
  3139. m.statement = UPPER(LTRIM(m.textline))
  3140.  
  3141. m.asterisk  = AT("*", m.statement)
  3142. m.ampersand = AT(m.g_dblampersand, m.statement)
  3143. m.isnote    = AT("NOTE", m.statement)
  3144.  
  3145. DO CASE
  3146. CASE (m.asterisk = 1 OR m.ampersand = 1)
  3147.    RETURN .T.
  3148. CASE (m.isnote = 1 ;
  3149.       AND (LEN(m.statement) <= 4 OR SUBSTR(m.statement,5,1) = ' '))
  3150.    * Don't be fooled by something like "notebook = 7"
  3151.    RETURN .T.
  3152. ENDCASE
  3153. RETURN .F.
  3154.  
  3155. *
  3156. * GENCLAUSECODE - Generate code for all read-level clauses.
  3157. *
  3158. * Description:
  3159. * Generate functions containing the code from each screen's
  3160. * READ level valid, show, when, activate, and deactivate clauses.
  3161. *
  3162. *!*****************************************************************************
  3163. *!
  3164. *!      Procedure: GENCLAUSECODE
  3165. *!
  3166. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  3167. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  3168. *!
  3169. *!          Calls: VALICLAUSE         (procedure in GENSCRN.PRG)
  3170. *!               : WHENCLAUSE         (procedure in GENSCRN.PRG)
  3171. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  3172. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  3173. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  3174. *!
  3175. *!*****************************************************************************
  3176. PROCEDURE genclausecode
  3177. PARAMETER m.screenno
  3178. DO valiclause WITH m.screenno
  3179. DO whenclause WITH m.screenno
  3180. DO acticlause WITH m.screenno
  3181. DO deatclause WITH m.screenno
  3182. DO showclause WITH m.screenno
  3183.  
  3184. *
  3185. * VALICLAUSE - Generate Read level Valid clause function.
  3186. *
  3187. * Description:
  3188. * Generate the function containing the code segment(s) provided
  3189. * by the user for the read level VALID clause.
  3190. * If multiple reads have been chosen, then this procedure generates
  3191. * a function for a single screen.
  3192. * If single read has been chosen and there are multiple screens,
  3193. * we will concatenate valid clause code segments form all screens
  3194. * to form a single function.
  3195. *
  3196. *!*****************************************************************************
  3197. *!
  3198. *!      Procedure: VALICLAUSE
  3199. *!
  3200. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3201. *!
  3202. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3203. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  3204. *!
  3205. *!*****************************************************************************
  3206. PROCEDURE valiclause
  3207. PARAMETER m.screenno
  3208. PRIVATE m.i, m.dbalias, m.thispretext
  3209.  
  3210. IF m.g_validtype = "EXPR" OR EMPTY(m.g_validtype)
  3211.    RETURN
  3212. ENDIF
  3213. DO genfuncheader WITH m.g_validname, "Read Level Valid", .T.
  3214. \FUNCTION <<m.g_validname>>     && Read Level Valid
  3215.  
  3216. m.thispretext = _PRETEXT
  3217. _PRETEXT = ""
  3218. IF m.g_multreads
  3219.    DO genvalidbody WITH m.screenno
  3220. ELSE
  3221.    FOR m.i = 1 TO m.g_nscreens
  3222.       m.g_screen = m.i
  3223.       m.dbalias = g_screens[m.i,5]
  3224.       SELECT (m.dbalias)
  3225.       DO genvalidbody WITH m.i
  3226.    ENDFOR
  3227.    m.g_screen = 0
  3228. ENDIF
  3229. _PRETEXT = m.thispretext
  3230.  
  3231. *
  3232. * GENVALIDBODY - Put out contents of a valid memo field.
  3233. *
  3234. *!*****************************************************************************
  3235. *!
  3236. *!      Procedure: GENVALIDBODY
  3237. *!
  3238. *!      Called by: VALICLAUSE         (procedure in GENSCRN.PRG)
  3239. *!
  3240. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  3241. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3242. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3243. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3244. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3245. *!
  3246. *!*****************************************************************************
  3247. PROCEDURE genvalidbody
  3248. PARAMETER m.region
  3249. PRIVATE m.name, m.pos
  3250.  
  3251. IF g_screens[m.region, 6]
  3252.    LOCATE FOR objtype = c_otscreen
  3253. ELSE
  3254.    LOCATE FOR platform = g_screens[m.region, 7] AND objtype = c_otscreen
  3255. ENDIF
  3256. IF NOT FOUND()
  3257.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3258.       LINENO(), c_error_3
  3259.    RETURN
  3260. ENDIF
  3261. IF NOT EMPTY(VALID) AND validtype<>0
  3262.    IF NOT m.g_multread
  3263.       m.name  = basename(DBF())
  3264.       DO gencomment WITH "Valid Code from screen: "+m.name
  3265.    ENDIF
  3266.    \#REGION <<INT(m.region)>>
  3267.    DO writecode WITH VALID, getplatname(m.region), c_fromone, c_untilend, m.region
  3268. ENDIF
  3269.  
  3270. *
  3271. * WHENCLAUSE - Generate Read level When clause function.
  3272. *
  3273. * Description:
  3274. * Generate the function containing the code segment(s) provided
  3275. * by the user for the read level WHEN clause.
  3276. * If multiple reads have been chosen, then this procedure generates
  3277. * a function for a single screen (i.e., the one it has been called for).
  3278. * If single read has been chosen and there are multiple screens,
  3279. * we will concatenate when clause code segments from all screens
  3280. * to form a single function.
  3281. *
  3282. *!*****************************************************************************
  3283. *!
  3284. *!      Procedure: WHENCLAUSE
  3285. *!
  3286. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3287. *!
  3288. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3289. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  3290. *!
  3291. *!*****************************************************************************
  3292. PROCEDURE whenclause
  3293. PARAMETER m.screenno
  3294. PRIVATE m.i, m.dbalias, m.thispretext
  3295.  
  3296. IF m.g_whentype = "EXPR" OR EMPTY(m.g_whentype)
  3297.    RETURN
  3298. ENDIF
  3299. DO genfuncheader WITH m.g_whenname, "Read Level When", .T.
  3300. \FUNCTION <<m.g_whenname>>     && Read Level When
  3301.  
  3302. m.thispretext = _PRETEXT
  3303. _PRETEXT = ""
  3304. IF m.g_multreads
  3305.    DO genwhenbody WITH m.screenno
  3306. ELSE
  3307.    FOR m.i = 1 TO m.g_nscreens
  3308.       m.g_screen = m.i
  3309.       m.dbalias = g_screens[m.i,5]
  3310.       SELECT (m.dbalias)
  3311.       DO genwhenbody WITH m.i
  3312.    ENDFOR
  3313.    m.g_screen = 0
  3314. ENDIF
  3315. _PRETEXT = m.thispretext
  3316.  
  3317. *
  3318. * GENWHENBODY - Put out contents of when memo field.
  3319. *
  3320. *!*****************************************************************************
  3321. *!
  3322. *!      Procedure: GENWHENBODY
  3323. *!
  3324. *!      Called by: WHENCLAUSE         (procedure in GENSCRN.PRG)
  3325. *!
  3326. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  3327. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3328. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3329. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3330. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3331. *!
  3332. *!*****************************************************************************
  3333. PROCEDURE genwhenbody
  3334. PARAMETER m.region
  3335. PRIVATE m.name, m.pos
  3336.  
  3337. IF g_screens[m.region, 6]
  3338.    LOCATE FOR objtype = c_otscreen
  3339. ELSE
  3340.    LOCATE FOR platform = g_screens[m.region, 7] AND objtype = c_otscreen
  3341. ENDIF
  3342. IF NOT FOUND()
  3343.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3344.       LINENO(), c_error_3
  3345.    RETURN
  3346. ENDIF
  3347.  
  3348. IF NOT EMPTY(WHEN) AND whentype<>0
  3349.    IF NOT m.g_multread
  3350.       m.name = basename(DBF())
  3351.       DO gencomment WITH "When Code from screen: "+m.name
  3352.    ENDIF
  3353.    \#REGION <<INT(m.region)>>
  3354.    DO writecode WITH WHEN, getplatname(m.region), c_fromone, c_untilend, m.region
  3355. ENDIF
  3356.  
  3357. *
  3358. * ACTICLAUSE - Generate Read level Activate clause function.
  3359. *
  3360. * Description:
  3361. * Generate the function containing the code segment(s) provided
  3362. * by the user for the read level ACTIVATE clause.
  3363. * If multiple reads have been chosen, then this procedure generates
  3364. * a function for a single screen (i.e., the one it has been called for).
  3365. * If single read has been chosen and there are multiple screens,
  3366. * we will concatenate activate clause code segments from all screens
  3367. * to form a single function.  Each individual screen's code
  3368. * segment will be enclosed in "IF WOUTPUT('windowname')" statement.
  3369. * Desk top will be represented by a null character. The above
  3370. * mentioned is performed by the procedure genactibody.
  3371. *
  3372. *!*****************************************************************************
  3373. *!
  3374. *!      Procedure: ACTICLAUSE
  3375. *!
  3376. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3377. *!
  3378. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3379. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3380. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3381. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3382. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3383. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3384. *!
  3385. *!*****************************************************************************
  3386. PROCEDURE acticlause
  3387. PARAMETER m.screenno
  3388. PRIVATE m.i, m.name
  3389.  
  3390. IF m.g_actitype = "EXPR" OR EMPTY(m.g_actitype)
  3391.    RETURN
  3392. ENDIF
  3393. DO genfuncheader WITH m.g_actiname, "Read Level Activate", .T.
  3394. \FUNCTION <<m.g_actiname>>     && Read Level Activate
  3395.  
  3396. IF m.g_multreads
  3397.    IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3398.       \#REGION <<INT(m.screenno)>>
  3399.       DO writecode WITH ACTIVATE, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3400.    ENDIF
  3401. ELSE
  3402.    FOR m.i = 1 TO m.g_nscreens
  3403.       m.g_screen = m.i
  3404.       m.dbalias = g_screens[m.i,5]
  3405.       SELECT (m.dbalias)
  3406.       IF g_screens[m.i, 6]
  3407.          LOCATE FOR objtype = c_otscreen
  3408.       ELSE
  3409.          LOCATE FOR platform = g_screens[m.i, 7] AND objtype = c_otscreen
  3410.       ENDIF
  3411.       IF NOT FOUND()
  3412.          DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3413.             LINENO(), c_error_3
  3414.          RETURN
  3415.       ENDIF
  3416.       IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3417.          m.name = basename(g_screens[m.i,1])
  3418.          DO gencomment WITH "Activate Code from screen: "+;
  3419.             m.name
  3420.       ENDIF
  3421.       IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3422.          \#REGION <<INT(m.i)>>
  3423.          DO writecode WITH ACTIVATE, getplatname(m.i), c_fromone, c_untilend, m.i
  3424.       ENDIF
  3425.    ENDFOR
  3426.    m.g_screen = 0
  3427. ENDIF
  3428.  
  3429. *
  3430. * DEATCLAUSE - Generate Read level deactivate clause function.
  3431. *
  3432. * Description:
  3433. * Generate the function containing the code segment(s) provided
  3434. * by the user for the read level DEACTIVATE clause.
  3435. * If multiple reads have been chosen, then this procedure generates
  3436. * a function for a single screen (i.e., the one it has been called for).
  3437. * If single read has been chosen and there are multiple screens,
  3438. * we will concatenate deactivate clause code segments from all screens
  3439. * to form a single function.  Each individual screen's code
  3440. * segment will be enclosed in "IF WOUTPUT('windowname')" statement.
  3441. * Desk top will be represented by a null character. The above
  3442. * mentioned is performed by the procedure gendeatbody.
  3443. *
  3444. *!*****************************************************************************
  3445. *!
  3446. *!      Procedure: DEATCLAUSE
  3447. *!
  3448. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3449. *!
  3450. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3451. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3452. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3453. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3454. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3455. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3456. *!
  3457. *!*****************************************************************************
  3458. PROCEDURE deatclause
  3459. PARAMETER m.screenno
  3460. PRIVATE m.i, m.name
  3461.  
  3462. IF m.g_deattype = "EXPR" OR EMPTY(m.g_deattype)
  3463.    RETURN
  3464. ENDIF
  3465. DO genfuncheader WITH m.g_deatname, "Read Level Deactivate", .T.
  3466. \FUNCTION <<m.g_deatname>>     && Read Level Deactivate
  3467.  
  3468. IF m.g_multreads
  3469.    IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3470.       \#REGION <<INT(m.screenno)>>
  3471.       DO writecode WITH DEACTIVATE, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3472.    ENDIF
  3473. ELSE
  3474.    FOR m.i = 1 TO m.g_nscreens
  3475.       m.g_screen = m.i
  3476.       m.dbalias = g_screens[m.i,5]
  3477.       SELECT (m.dbalias)
  3478.       IF g_screens[m.i,6]
  3479.          LOCATE FOR objtype = c_otscreen
  3480.       ELSE
  3481.          LOCATE FOR platform = g_screens[m.i, 7] AND objtype = c_otscreen
  3482.       ENDIF
  3483.       IF NOT FOUND()
  3484.          DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3485.             LINENO(), c_error_3
  3486.          RETURN
  3487.       ENDIF
  3488.       IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3489.          m.name = basename(g_screens[m.i,1])
  3490.          DO gencomment WITH "Deactivate Code from screen: "+;
  3491.             m.name
  3492.       ENDIF
  3493.       IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3494.          \#REGION <<INT(m.i)>>
  3495.          DO writecode WITH DEACTIVATE, getplatname(m.i), c_fromone, c_untilend, m.i
  3496.       ENDIF
  3497.    ENDFOR
  3498.    m.g_screen = 0
  3499. ENDIF
  3500.  
  3501. *
  3502. * SHOWCLAUSE - Generate Read level Show clause procedure.
  3503. *
  3504. * Description:
  3505. * Generate the function containing the code segment(s) provided
  3506. * by the user for the read level SHOW clause.  The function generated
  3507. * for the show clause will consist of refreshable @...SAY code and
  3508. * code segment(s) if applicable. If multiple reads have been chosen,
  3509. * then this procedure generates a function for a single screen
  3510. * (i.e., the one it has been called for).  If single read has been
  3511. * chosen and there are multiple screens, we will concatenate show
  3512. * clause code segments from all screens to form a single function.
  3513. * Each individual screen's refreshable SAYs will be enclosed in
  3514. * "IF SYS(2016)=('windowname') OR SYS(2016) = '*'" statement.
  3515. * (Desk top will be represented by a null character.)
  3516. *
  3517. *!*****************************************************************************
  3518. *!
  3519. *!      Procedure: SHOWCLAUSE
  3520. *!
  3521. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3522. *!
  3523. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3524. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3525. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3526. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3527. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  3528. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3529. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3530. *!
  3531. *!*****************************************************************************
  3532. PROCEDURE showclause
  3533. PARAMETER m.screenno
  3534. PRIVATE m.i, m.comment, m.name, m.thispretext, m.oldshow, m.showmod
  3535.  
  3536. IF m.g_showtype = "EXPR" OR EMPTY(m.g_showtype)
  3537.    RETURN
  3538. ENDIF
  3539. DO genfuncheader WITH m.g_showname, "Read Level Show", .T.
  3540.  
  3541. \FUNCTION <<m.g_showname>>     && Read Level Show
  3542. \PRIVATE currwind
  3543.  
  3544. \STORE WOUTPUT() TO currwind
  3545. m.thispretext = _PRETEXT
  3546. _PRETEXT = ""
  3547.  
  3548. IF m.g_multreads
  3549.    DO seekheader WITH m.screenno
  3550.    m.oldshow = Show
  3551.  
  3552.    m.showmod = ChkShow()
  3553.  
  3554.    m.comment = .T.
  3555.    \#REGION <<INT(m.screenno)>>
  3556.    IF NOT EMPTY(show) AND showtype<>0
  3557.       DO writecode WITH show, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3558.    ENDIF
  3559.    DO placesays WITH m.comment, m.g_showname, m.screenno
  3560.    IF m.showmod
  3561.       REPLACE show WITH m.oldshow
  3562.    ENDIF
  3563. ELSE
  3564.    FOR m.i = 1 TO m.g_nscreens
  3565.       m.g_screen = m.i
  3566.       m.dbalias = g_screens[m.i,5]
  3567.       SELECT (m.dbalias)
  3568.       m.comment = .F.
  3569.  
  3570.       DO seekheader WITH m.i
  3571.  
  3572.       m.name = basename(g_screens[m.i,1])
  3573.       IF NOT EMPTY(show) AND showtype<>0
  3574.          m.oldshow = Show   && record show snippet
  3575.          m.showmod = ChkShow()         && may modify show snippet directly
  3576.  
  3577.          DO gencomment WITH "Show Code from screen: "+m.name
  3578.          \#REGION <<INT(m.i)>>
  3579.          m.comment = .T.
  3580.          DO writecode WITH show, getplatname(m.i), c_fromone, c_untilend, m.i
  3581.          IF m.showmod
  3582.             REPLACE show WITH m.oldshow
  3583.          ENDIF
  3584.       ENDIF
  3585.       DO seekheader WITH m.i
  3586.       DO placesays WITH m.comment, m.name, m.i
  3587.    ENDFOR
  3588.    m.g_screen = 0
  3589. ENDIF
  3590. _PRETEXT = m.thispretext
  3591.  
  3592. IF !m.g_noreadplain
  3593.    \IF NOT EMPTY(currwind)
  3594.    \    ACTIVATE WINDOW (currwind) SAME
  3595.    \ENDIF
  3596. ENDIF
  3597.  
  3598. *!*****************************************************************************
  3599. *!
  3600. *!      Function: CHKSHOW
  3601. *!
  3602. *!*****************************************************************************
  3603. FUNCTION chkshow
  3604. PRIVATE m.thelineno, m.theline, m.oldmline, m.upline, m.newshow, m.found_one, m.leadspace, ;
  3605.    m.oldtext, m.theword, m.getsonly, m.j
  3606. * Check for a poisonous SHOW GETS in the SHOW snippet.  If one if executed
  3607. * there, runaway recursion results.
  3608. IF c_checkshow == 0   && check to see if this safety feature is enabled.
  3609.    RETURN .F.
  3610. ENDIF
  3611. m.thelineno = ATCLINE("SHOW GETS",show)
  3612. m.oldmline = _MLINE
  3613. m.oldtext = _TEXT
  3614. m.found_one = .F.
  3615. IF m.thelineno > 0
  3616.    * Step through the SHOW snippet a line at a time, commenting out any SHOW GETS or
  3617.    * SHOW GETS OFF statements.
  3618.    m.newshow = ""
  3619.    _MLINE = 0
  3620.    DO WHILE _MLINE < LEN(show)
  3621.       m.theline = MLINE(show,1,_MLINE)
  3622.       m.upline  = UPPER(LTRIM(m.theline))
  3623.       IF wordnum(m.upline,1) == "SHOW" AND wordnum(m.upline,2) == "GETS" ;
  3624.              AND (EMPTY(wordnum(m.upline,3)) OR wordnum(m.upline,3) == "OFF")
  3625.          m.leadspace = LEN(m.theline) - LEN(m.upline)
  3626.          m.newshow = m.newshow + SPACE(m.leadspace) + ;
  3627.             "* Commented out by GENSCRN: " + LTRIM(m.theline) + CHR(13) + CHR(10)
  3628.          DO errorhandler WITH "SHOW GETS statement commented out of SHOW snippet.",;
  3629.               LINENO(),c_error_1
  3630.          m.found_one = .T.
  3631.       ELSE
  3632.          m.newshow = m.newshow + m.theline + CHR(13) + CHR(10)
  3633.       ENDIF
  3634.    ENDDO
  3635.    IF m.found_one
  3636.       REPLACE show WITH m.newshow
  3637.    ENDIF
  3638. ENDIF
  3639. _MLINE = m.oldmline
  3640. _TEXT  = m.oldtext
  3641. RETURN m.found_one
  3642.  
  3643. *
  3644. * PLACESAYS - Generate @...SAY for refreshable says in the .PRG file.
  3645. *
  3646. * Description:
  3647. * Place @...SAY code for all refreshable say statements into
  3648. * the generated SHOW clause function.
  3649. *
  3650. *!*****************************************************************************
  3651. *!
  3652. *!      Procedure: PLACESAYS
  3653. *!
  3654. *!      Called by: SHOWCLAUSE         (procedure in GENSCRN.PRG)
  3655. *!
  3656. *!          Calls: GENCOMMENT         (procedure in GENSCRN.PRG)
  3657. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  3658. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  3659. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  3660. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  3661. *!               : ANYPICTURE         (procedure in GENSCRN.PRG)
  3662. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  3663. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  3664. *!
  3665. *!*****************************************************************************
  3666. PROCEDURE placesays
  3667. PARAMETER m.comment, m.scrnname, m.g_thisscreen
  3668. PRIVATE m.iswindow, m.sayfound, m.windowname, m.theexpr, m.occur, m.pos
  3669.  
  3670. IF EMPTY(STYLE)
  3671.    m.iswindow = .F.
  3672. ELSE
  3673.    m.iswindow = .T.
  3674.    m.windowname = g_screens[m.g_thisscreen,2]
  3675. ENDIF
  3676. m.sayfound = .T.
  3677. SCAN FOR ((objtype = c_otfield AND objcode = c_sgsay) OR ;
  3678.       (objtype = c_otpicture)) AND ;
  3679.       REFRESH = .T. AND (g_screens[m.g_thisscreen, 6] OR platform = g_screens[m.g_thisscreen, 7])
  3680.    IF m.sayfound
  3681.       IF NOT m.comment
  3682.          DO gencomment WITH "Show Code from screen: "+m.scrnname
  3683.          \#REGION <<INT(m.g_thisscreen)>>
  3684.       ENDIF
  3685.       IF !m.g_noreadplain    && not just emitting plain @ SAYs/GETs
  3686.          \IF SYS(2016) =
  3687.          IF m.iswindow
  3688.             \\ "<<UPPER(m.windowname)>>" OR SYS(2016) = "*"
  3689.             \    ACTIVATE WINDOW <<m.windowname>> SAME
  3690.          ELSE
  3691.             \\ "" OR SYS(2016) = "*"
  3692.             \    ACTIVATE SCREEN
  3693.          ENDIF
  3694.       ENDIF
  3695.       m.sayfound = .F.
  3696.    ENDIF
  3697.  
  3698.    IF objtype = c_otpicture
  3699.       DO genpicture
  3700.    ELSE
  3701.       m.theexpr = expr
  3702.       IF g_screens[m.g_thisscreen, 7] = 'WINDOWS' OR g_screens[m.g_thisscreen, 7] = 'MAC'
  3703.          SET DECIMALS TO 3
  3704.          m.occur = 1
  3705.          m.pos = AT(CHR(13), m.theexpr, m.occur)
  3706.  
  3707.          * Sometimes the screen builder surrounds text with single quotes and other
  3708.          * times with double quotes.
  3709.          q1 = LEFT(LTRIM(m.theexpr),1)
  3710.  
  3711.          DO WHILE m.pos > 0
  3712.             IF q1 = "'"
  3713.                m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  3714.                   "' + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "'" ;
  3715.                   + SUBSTR(m.theexpr, m.pos + 1)
  3716.             ELSE
  3717.                m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  3718.                   '" + CHR(13) + ;' + CHR(13)  + CHR(9) + CHR(9) + '"' ;
  3719.                   + SUBSTR(m.theexpr, m.pos + 1)
  3720.             ENDIF
  3721.             m.occur = m.occur + 1
  3722.             m.pos = AT(CHR(13), m.theexpr, m.occur)
  3723.          ENDDO
  3724.          IF mode = 1 AND objtype = c_otfield  AND objcode = c_sgsay    && transparent SAY text
  3725.             * Clear the space that the SAY is going into.  This makes refreshable SAYS
  3726.             * work with transparent fonts.
  3727.             \    @ <<Vpos>>,<<Hpos>> CLEAR TO <<Vpos+Height>>,<<Hpos+Width>>
  3728.          ENDIF
  3729.       ENDIF
  3730.       \    @ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  3731.       \        SIZE <<Height>>,<<Width>>, <<Spacing>>
  3732.       SET DECIMALS TO 0
  3733.       DO pushindent
  3734.       DO anyfont
  3735.       DO anystyle
  3736.       DO anypicture
  3737.       DO anyscheme
  3738.       DO popindent
  3739.    ENDIF
  3740. ENDSCAN
  3741. IF NOT m.sayfound
  3742.    \ENDIF
  3743. ENDIF
  3744.  
  3745. *
  3746. * GENCLOSEDBFS - Generate code to close all previously opened databases.
  3747. *
  3748. *!*****************************************************************************
  3749. *!
  3750. *!      Procedure: GENCLOSEDBFS
  3751. *!
  3752. *!      Called by: GENCLNENVIRON      (procedure in GENSCRN.PRG)
  3753. *!
  3754. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  3755. *!               : UNIQUEDBF()        (function  in GENSCRN.PRG)
  3756. *!
  3757. *!*****************************************************************************
  3758. PROCEDURE genclosedbfs
  3759. PRIVATE m.i, m.dbalias, m.dbfcnt, m.firstfound
  3760. m.firstfound = .T.
  3761. m.dbfcnt = 0
  3762. g_dbfs = ""
  3763. FOR m.i = 1 TO m.g_nscreens
  3764.    m.g_screen = m.i
  3765.    m.dbalias = g_screens[m.i,5]
  3766.    SELECT (m.dbalias)
  3767.    SCAN FOR objtype = c_otworkarea AND (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  3768.       IF m.firstfound
  3769.          DO commentblock WITH ""," Closing Databases"
  3770.          m.firstfound = .F.
  3771.       ENDIF
  3772.       IF uniquedbf(TAG)
  3773.          m.dbfcnt = m.dbfcnt + 1
  3774.          DIMENSION g_dbfs[m.dbfcnt]
  3775.          g_dbfs[m.dbfcnt] = TAG
  3776.       ELSE
  3777.          LOOP
  3778.       ENDIF
  3779.       \IF USED("<<LOWER(stripext(strippath(Tag)))>>")
  3780.       \    SELECT <<LOWER(stripext(strippath(Tag)))>>
  3781.       \    USE
  3782.       \ENDIF
  3783.       \
  3784.    ENDSCAN
  3785. ENDFOR
  3786. m.g_screen = 0
  3787. IF m.g_closefiles 
  3788.    \SELECT (m.currarea)
  3789.    \
  3790. ENDIF
  3791. DIMENSION g_dbfs[1]
  3792.  
  3793. *
  3794. * GENOPENDBFS - Generate USE... statement(s).
  3795. *
  3796. * Description:
  3797. * Generate code to open databases, set indexes, and relations as
  3798. * specified by the user.
  3799. *
  3800. *!*****************************************************************************
  3801. *!
  3802. *!      Procedure: GENOPENDBFS
  3803. *!
  3804. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  3805. *!
  3806. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  3807. *!               : UNIQUEDBF()        (function  in GENSCRN.PRG)
  3808. *!               : GENUSESTMTS        (procedure in GENSCRN.PRG)
  3809. *!               : STRIPPATH()        (function  in GENSCRN.PRG)
  3810. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3811. *!               : GENRELATIONS       (procedure in GENSCRN.PRG)
  3812. *!
  3813. *!*****************************************************************************
  3814. PROCEDURE genopendbfs
  3815. PRIVATE m.dbalias, m.i, m.dbfcnt, m.string, m.msg, m.firstfound
  3816. m.firstfound = .T.
  3817. FOR m.i = 1 TO m.g_nscreens
  3818.    m.g_screen = m.i
  3819.    m.dbalias = g_screens[m.i,5]
  3820.    SELECT (m.dbalias)
  3821.    m.dbfcnt = 0
  3822.    SCAN FOR objtype = c_otworkarea AND (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  3823.       IF m.firstfound
  3824.          DO commentblock WITH m.dbalias, ;
  3825.             " Databases, Indexes, Relations"
  3826.          m.firstfound = .F.
  3827.       ENDIF
  3828.       IF uniquedbf(TAG)
  3829.          m.dbfcnt = m.dbfcnt + 1
  3830.          DIMENSION g_dbfs[m.dbfcnt]
  3831.          g_dbfs[m.dbfcnt] = TAG
  3832.       ELSE
  3833.          LOOP
  3834.       ENDIF
  3835.       DO genusestmts WITH m.i
  3836.    ENDSCAN
  3837.  
  3838.    IF m.dbfcnt > 1
  3839.       IF NOT EMPTY(m.g_current)
  3840.          \SELECT <<m.g_current>>
  3841.       ELSE
  3842.          m.msg = "Please RE-SAVE screen environment... SCREEN: "+;
  3843.             strippath(g_screens[m.i,1])
  3844.          DO errorhandler WITH m.msg, LINENO(), c_error_1
  3845.       ENDIF
  3846.       \
  3847.    ENDIF
  3848. ENDFOR
  3849. m.g_screen = 0
  3850. DO genrelations
  3851.  
  3852. *
  3853. * UNIQUEDBF - Check if database name already seen.
  3854. *
  3855. *!*****************************************************************************
  3856. *!
  3857. *!       Function: UNIQUEDBF
  3858. *!
  3859. *!      Called by: GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  3860. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  3861. *!
  3862. *!*****************************************************************************
  3863. FUNCTION uniquedbf
  3864. PARAMETER m.dbfname
  3865. RETURN IIF(ASCAN(g_dbfs, m.dbfname)=0,.T.,.F.)
  3866.  
  3867. *
  3868. * GENUSESTMTS - Generate USE... statements
  3869. *
  3870. * Description:
  3871. * Generate USE... statements for each database encoded in the
  3872. * screen database.  Generate ORDER statement if appropriate.
  3873. *
  3874. *!*****************************************************************************
  3875. *!
  3876. *!      Procedure: GENUSESTMTS
  3877. *!
  3878. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  3879. *!
  3880. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  3881. *!               : GENORDER           (procedure in GENSCRN.PRG)
  3882. *!               : GENINDEXES()       (function  in GENSCRN.PRG)
  3883. *!
  3884. *!*****************************************************************************
  3885. PROCEDURE genusestmts
  3886. PARAMETER m.i
  3887. PRIVATE m.workarea, saverecno, MARGIN, m.name, m.order, m.tag
  3888. m.workarea  = objcode
  3889. saverecno = RECNO()
  3890. m.order   = LOWER(ALLTRIM(ORDER))
  3891. m.tag     = LOWER(ALLTRIM(tag2))
  3892. m.name    = LOWER(TAG)
  3893. m.relpath = LOWER(findrelpath(name))
  3894.  
  3895. IF UNIQUE AND EMPTY(m.g_current)
  3896.    m.g_current = m.name
  3897. ENDIF
  3898.  
  3899. MARGIN = 4
  3900. IF EMPTY(name)
  3901.    \SELECT <<m.name>>
  3902.    RETURN
  3903. ENDIF
  3904. \IF USED("<<m.name>>")
  3905. \    SELECT <<m.name>>
  3906. IF genindexes ("select", m.i)=0
  3907.    indexfound = 0
  3908.    \    SET ORDER TO
  3909.    DO genorder WITH indexfound,m.order,m.tag,m.name
  3910. ELSE
  3911.    indexfound = 1
  3912.    \\ ADDITIVE ;
  3913.    \        ORDER
  3914.    DO genorder WITH indexfound,m.order,m.tag,m.name
  3915. ENDIF
  3916.  
  3917. \ELSE
  3918. \    SELECT 0
  3919. \    USE (LOCFILE("<<m.relpath>>","DBF",
  3920. \\"Where is <<basename(m.relpath)>>?"));
  3921. \        AGAIN ALIAS <<m.name>>
  3922. MARGIN = 42+LEN(m.relpath)+2*LEN(m.name)
  3923. = genindexes("use", m.i)
  3924.  
  3925. GOTO saverecno
  3926. \\ ;
  3927. \        ORDER
  3928. DO genorder WITH indexfound,m.order,m.tag,m.name
  3929. \ENDIF
  3930. \
  3931.  
  3932. *
  3933. * FINDRELPATH - Find relative path for DATABASES.
  3934. *
  3935. *!*****************************************************************************
  3936. *!
  3937. *!       Function: FINDRELPATH
  3938. *!
  3939. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3940. *!               : GENINDEXES()       (function  in GENSCRN.PRG)
  3941. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  3942. *!               : ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  3943. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  3944. *!               : ANYICON            (procedure in GENSCRN.PRG)
  3945. *!
  3946. *!*****************************************************************************
  3947. FUNCTION findrelpath
  3948. PARAMETER m.name
  3949. PRIVATE m.fullpath, m.relpath
  3950. m.fullpath = FULLPATH(m.name, g_screens[1,1])
  3951. m.relpath  = SYS(2014, m.fullpath, m.g_homedir)
  3952. RETURN m.relpath
  3953.  
  3954. *
  3955. * GENORDER - Generate ORDER clause.
  3956. *
  3957. *!*****************************************************************************
  3958. *!
  3959. *!      Procedure: GENORDER
  3960. *!
  3961. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3962. *!
  3963. *!*****************************************************************************
  3964. PROCEDURE genorder
  3965. PARAMETER m.indexfound, m.order, m.tag, m.dbfname
  3966. IF EMPTY(m.order) AND EMPTY(m.tag)
  3967.    \\ 0
  3968.    RETURN
  3969. ENDIF
  3970. IF m.indexfound=0
  3971.    \\ TAG "<<m.tag>>"
  3972. ELSE
  3973.    IF EMPTY(m.tag)
  3974.       \\ <<basename(m.order)>>
  3975.    ELSE
  3976.       \\ TAG "<<m.tag>>"
  3977.       IF NOT EMPTY (m.order)
  3978.          \\ OF <<m.order>>
  3979.       ENDIF
  3980.    ENDIF
  3981. ENDIF
  3982.  
  3983. *
  3984. * GENINDEXES - Generate index names for a USE statement.
  3985. *
  3986. *!*****************************************************************************
  3987. *!
  3988. *!       Function: GENINDEXES
  3989. *!
  3990. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3991. *!
  3992. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  3993. *!
  3994. *!*****************************************************************************
  3995. FUNCTION genindexes
  3996. PARAMETER m.placement, m.i
  3997. PRIVATE m.idxcount, m.relpath
  3998. m.idxcount = 0
  3999.  
  4000. SCAN FOR objtype = c_otindex AND objcode = WORKAREA AND;
  4001.       (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4002.    m.relpath = LOWER(findrelpath(name))
  4003.    IF m.idxcount > 0
  4004.       IF MARGIN > 55
  4005.          MARGIN = 8 + LEN(m.relpath)
  4006.          \\, ;
  4007.          \        <<m.relpath>>
  4008.       ELSE
  4009.          \\, <<m.relpath>>
  4010.          MARGIN = MARGIN + 2 + LEN(m.relpath)
  4011.       ENDIF
  4012.    ELSE
  4013.       IF m.placement = "use"
  4014.          \\ ;
  4015.          \        INDEX <<m.relpath>>
  4016.          MARGIN = 8 + LEN(m.relpath)
  4017.       ELSE
  4018.          \    SET INDEX TO <<m.relpath>>
  4019.          MARGIN = 17
  4020.          MARGIN = MARGIN + LEN(m.relpath)
  4021.       ENDIF
  4022.    ENDIF
  4023.    m.idxcount = m.idxcount + 1
  4024. ENDSCAN
  4025. RETURN m.idxcount
  4026.  
  4027. *
  4028. * GENRELATIONS - Generate code to set all existing relations as they
  4029. *                 are encoded in the screen file(s).
  4030. *
  4031. * Description:
  4032. * Generate code for all relations as encoded in the screen database.
  4033. *
  4034. *!*****************************************************************************
  4035. *!
  4036. *!      Procedure: GENRELATIONS
  4037. *!
  4038. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  4039. *!
  4040. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  4041. *!               : GENRELSTMTS        (procedure in GENSCRN.PRG)
  4042. *!
  4043. *!*****************************************************************************
  4044. PROCEDURE genrelations
  4045. PRIVATE m.dbalias, m.i
  4046. FOR m.i = 1 TO m.g_nscreens
  4047.    m.g_screen = m.i
  4048.    m.dbalias  = g_screens[m.i,5]
  4049.    SELECT (m.dbalias)
  4050.  
  4051.    DO seekheader WITH m.i
  4052.    DO genrelstmts WITH m.i
  4053. ENDFOR
  4054. m.g_screen = 0
  4055.  
  4056. *
  4057. * GENRELSTMTS - Generate relation statements.
  4058. *
  4059. *!*****************************************************************************
  4060. *!
  4061. *!      Procedure: GENRELSTMTS
  4062. *!
  4063. *!      Called by: GENRELATIONS       (procedure in GENSCRN.PRG)
  4064. *!
  4065. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  4066. *!
  4067. *!*****************************************************************************
  4068. PROCEDURE genrelstmts
  4069. PARAMETER m.i
  4070. PRIVATE m.saverec, m.last, m.firstrel, m.firstsel, m.dbalias, m.setskip
  4071. m.dbalias  = ""
  4072. m.firstrel = .T.
  4073. m.firstsel = .T.
  4074. m.last     = 0
  4075. m.setskip  = ""
  4076.  
  4077. SCAN FOR objtype = c_otrel AND ;
  4078.       (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4079.    IF m.last<> objcode
  4080.       IF NOT (m.firstrel OR EMPTY(m.setskip))
  4081.          \SET SKIP TO <<m.setskip>>
  4082.          \
  4083.       ENDIF
  4084.       m.saverec = RECNO()
  4085.       m.last= objcode
  4086.  
  4087.       SCAN FOR objtype = c_otworkarea AND objcode = m.last AND ;
  4088.             (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4089.          m.dbalias = LOWER(basename(TAG))
  4090.          IF NOT (m.firstrel AND m.g_current = m.dbalias)
  4091.             \SELECT <<m.dbalias>>
  4092.          ENDIF
  4093.          m.setskip = ALLTRIM(LOWER(expr))
  4094.       ENDSCAN
  4095.  
  4096.       GOTO RECORD m.saverec
  4097.       m.firstrel = .F.
  4098.    ENDIF
  4099.  
  4100.    IF !(m.firstsel AND LOWER(tag2) == LOWER(m.g_current))
  4101.       \SELECT <<LOWER(Tag2)>>
  4102.       \
  4103.    ENDIF
  4104.    \SET RELATION OFF INTO <<LOWER(Tag)>>
  4105.    \SET RELATION TO <<LOWER(Expr)>> INTO <<LOWER(Tag)>> ADDITIVE
  4106.    \
  4107.  
  4108.    m.firstsel = .F.
  4109. ENDSCAN
  4110.  
  4111. IF m.last<> 0
  4112.    IF NOT EMPTY(m.setskip))
  4113.       \SET SKIP TO <<m.setskip>>
  4114.       \
  4115.    ENDIF
  4116.    IF NOT EMPTY(m.g_current)
  4117.       \SELECT <<m.g_current>>
  4118.    ENDIF
  4119. ENDIF
  4120.  
  4121. **
  4122. ** Code Associated With Building of the Format file statements.
  4123. **
  4124.  
  4125. *
  4126. * BUILDFMT - Build Format file statements.
  4127. *
  4128. * Description:
  4129. * Generate all boxes, text, fields, push buttons, radio buttons,
  4130. * popups, check boxes and scrollable lists encoded in a screen set.
  4131. *
  4132. *!*****************************************************************************
  4133. *!
  4134. *!      Procedure: BUILDFMT
  4135. *!
  4136. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4137. *!
  4138. *!          Calls: TICK()             (function  in GENSCRN.PRG)
  4139. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  4140. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  4141. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  4142. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  4143. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4144. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4145. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  4146. *!               : ANYWINDOWS         (procedure in GENSCRN.PRG)
  4147. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  4148. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  4149. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  4150. *!               : GENLINES           (procedure in GENSCRN.PRG)
  4151. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  4152. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  4153. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  4154. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  4155. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  4156. *!               : GENLIST            (procedure in GENSCRN.PRG)
  4157. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  4158. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  4159. *!               : GENACTISTMTS       (procedure in GENSCRN.PRG)
  4160. *!               : PLACEREAD          (procedure in GENSCRN.PRG)
  4161. *!               : TOCK()             (function  in GENSCRN.PRG)
  4162. *!
  4163. *!*****************************************************************************
  4164. PROCEDURE buildfmt
  4165. PARAMETER pnum   && platform number
  4166. PRIVATE m.pos, m.dbalias, m.adjuster, m.recadjust, m.factor, m.i, m.sn
  4167. m.msg = 'Generating Screen Code'
  4168. IF multiplat()
  4169.    m.msg = m.msg + " for "+versioncap(m.g_genvers)
  4170. ENDIF
  4171. DO putmsg WITH m.msg
  4172. m.g_nwindows = 0
  4173. m.adjuster   = INT(25/m.g_nscreens)
  4174. m.recadjust  = 35
  4175. FOR m.sn = 1 TO m.g_nscreens
  4176.    m.g_screen = m.sn
  4177.    m.dbalias = g_screens[m.sn,5]
  4178.    SELECT (m.dbalias)
  4179.    DO seekheader WITH m.sn
  4180.    m.factor = m.adjuster/RECCOUNT()
  4181.    DO commentblock WITH g_screens[m.sn,1], " Screen Layout"
  4182.    \#REGION <<INT(m.sn)>>
  4183.    IF ATC('#ITSE',setupcode)<>0
  4184.       DO gendirective WITH ;
  4185.          MLINE(setupcode,ATCLINE('#ITSE',setupcode)),;
  4186.          '#ITSE'
  4187.    ENDIF
  4188.    SCAN FOR (g_screens[m.sn, 6] OR platform = g_screens[m.sn, 7])
  4189.       m.recadjust = m.recadjust + m.factor
  4190.       DO updtherm WITH INT(m.recadjust) * m.pnum
  4191.  
  4192.       DO CASE
  4193.       CASE objtype = c_otscreen
  4194.          DO anywindows WITH (m.sn)
  4195.       CASE objtype = c_ottext
  4196.          DO gentext
  4197.       CASE objtype = c_otfield
  4198.          DO genfields
  4199.       CASE objtype = c_otbox
  4200.          DO genboxes
  4201.       CASE objtype = c_otline
  4202.          DO genlines
  4203.       CASE objtype = c_ottxtbut
  4204.          DO genpush
  4205.       CASE objtype = c_otradbut
  4206.          DO genradbut
  4207.       CASE objtype = c_otinvbut
  4208.          DO geninvbut
  4209.       CASE objtype = c_otpopup
  4210.          DO genpopup
  4211.       CASE objtype = c_otchkbox
  4212.          DO genchkbox
  4213.       CASE objtype = c_otlist
  4214.          DO genlist
  4215.       CASE objtype = c_otpicture
  4216.          DO genpicture
  4217.       CASE objtype = c_otspinner
  4218.          DO genspinner
  4219.       ENDCASE
  4220.    ENDSCAN
  4221.    DO genactistmts WITH (m.sn)
  4222.    IF !m.g_noread
  4223.       DO placeread WITH (m.sn)
  4224.    ENDIF
  4225. ENDFOR
  4226. m.g_screen = 0
  4227.  
  4228. *
  4229. * ANYWINDOWS - Issue ACTIVATE WINDOW ... SAME.
  4230. *
  4231. * Description:
  4232. * If windows present issue ACTIVATE WINDOW...SAME to make sure
  4233. * that the windows stack on screen in the correct order.
  4234. *
  4235. *!*****************************************************************************
  4236. *!
  4237. *!      Procedure: ANYWINDOWS
  4238. *!
  4239. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4240. *!
  4241. *!          Calls: GENACTWINDOW       (procedure in GENSCRN.PRG)
  4242. *!
  4243. *!*****************************************************************************
  4244. PROCEDURE anywindows
  4245. PARAMETER m.scrnno
  4246. PRIVATE m.pos
  4247. IF m.g_noreadplain
  4248.    RETURN
  4249. ENDIF
  4250.    
  4251. IF NOT EMPTY(STYLE)
  4252.    DO genactwindow WITH m.scrnno
  4253.  
  4254.    m.g_lastwindow = g_screens[m.scrnno,2]
  4255.    m.pos = ASCAN(g_wndows, m.g_lastwindow)
  4256.    * m.pos contains the element number (not the row) that matches.
  4257.    * The element number + 1 is a number representing window sequence.
  4258.    IF EMPTY(g_wndows[m.pos+1])
  4259.       m.g_nwindows = m.g_nwindows + 1
  4260.       g_wndows[m.pos+1] = m.g_nwindows
  4261.    ENDIF
  4262.  
  4263.    m.g_defasch1 = SCHEME
  4264.    m.g_defasch2 = scheme2
  4265. ELSE
  4266.    m.g_defasch1 = 0
  4267.    m.g_defasch2 = 0
  4268.  
  4269.    IF m.g_lastwindow<>""
  4270.       \HIDE WINDOW ALL
  4271.       \ACTIVATE SCREEN
  4272.       m.g_lastwindow = ""
  4273.    ENDIF
  4274. ENDIF
  4275.  
  4276. *
  4277. * GENACTISTMTS - Generate Activate window statements.
  4278. *
  4279. * Description:
  4280. * Generate ACTIVATE WINDOW... statements in order to activate all
  4281. * windows which have been previously activated with SAME clause.
  4282. *
  4283. *!*****************************************************************************
  4284. *!
  4285. *!      Procedure: GENACTISTMTS
  4286. *!
  4287. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4288. *!
  4289. *!*****************************************************************************
  4290. PROCEDURE genactistmts
  4291. PARAMETER m.scrnno
  4292. PRIVATE m.j, m.pos
  4293. \
  4294. IF m.scrnno=m.g_nscreens AND NOT m.g_multreads AND NOT m.g_noreadplain
  4295.    IF m.g_nwindows = 1
  4296.       \IF NOT WVISIBLE("<<g_wndows[1,1]>>")
  4297.       \    ACTIVATE WINDOW <<g_wndows[1,1]>>
  4298.       \ENDIF
  4299.       RETURN
  4300.    ENDIF
  4301.    FOR m.j = m.g_nwindows TO 1 STEP -1
  4302.       m.pos = ASCAN(g_wndows, m.j)
  4303.       * pos contains the element *numbered* j.  This will be somewhere in g_wndows[*,2].
  4304.       * Look to the preceding element to get the window name.
  4305.       IF m.pos<>0
  4306.          \IF NOT WVISIBLE("<<g_wndows[m.pos-1]>>")
  4307.          \    ACTIVATE WINDOW <<g_wndows[m.pos-1]>>
  4308.          \ENDIF
  4309.       ENDIF
  4310.    ENDFOR
  4311.    \
  4312. ENDIF
  4313.  
  4314. *
  4315. * PLACEREAD - Generate a 'READ' statement.
  4316. *
  4317. * Description:
  4318. * Called once per screen in the screen set.
  4319. * Generate a READ statement.  Depending on whether this is a single
  4320. * or multiread the read statement may be generated between @...SAY/GETs
  4321. * from each screen or at the end of a set of all @...SAY/GETs.
  4322. *
  4323. *!*****************************************************************************
  4324. *!
  4325. *!      Procedure: PLACEREAD
  4326. *!
  4327. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4328. *!
  4329. *!          Calls: ANYMODAL           (procedure in GENSCRN.PRG)
  4330. *!               : ANYLOCK            (procedure in GENSCRN.PRG)
  4331. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4332. *!               : GENWITHCLAUSE      (procedure in GENSCRN.PRG)
  4333. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  4334. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4335. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4336. *!               : GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4337. *!               : GENCLAUSECODE      (procedure in GENSCRN.PRG)
  4338. *!
  4339. *!*****************************************************************************
  4340. PROCEDURE placeread
  4341. PARAMETER m.scrnno
  4342. PRIVATE thispretext
  4343.  
  4344. \
  4345. IF m.g_multreads
  4346.    DO newreadclauses
  4347.    \READ
  4348.    IF m.g_readcycle AND m.scrnno = m.g_nscreens
  4349.       \\ CYCLE
  4350.    ENDIF
  4351.    DO anymodal
  4352.    DO anylock
  4353.    DO doplaceclause WITH m.scrnno
  4354.    DO genwithclause
  4355.    DO gengivenread WITH m.scrnno
  4356. ELSE
  4357.    IF NOT EMPTY(m.g_rddir) AND m.scrnno = m.g_nscreens
  4358.       DO commentblock WITH "","READ contains clauses from SCREEN "+;
  4359.          LOWER(g_screens[m.g_rddirno,5])
  4360.    ENDIF
  4361.    DO findreadclauses WITH m.scrnno
  4362.    IF m.scrnno = m.g_nscreens
  4363.       \READ
  4364.       IF m.g_readcycle
  4365.          \\ CYCLE
  4366.       ENDIF
  4367.       DO anymodal
  4368.       DO anylock
  4369.       DO genreadclauses
  4370.       DO genwithclause
  4371.       DO gengivenread WITH m.scrnno
  4372.       _TEXT = m.g_tmphandle
  4373.       m.thispretext = _PRETEXT
  4374.       _PRETEXT = ""
  4375.       DO genclausecode WITH m.scrnno
  4376.       _TEXT = m.g_orghandle
  4377.       _PRETEXT = m.thispretext
  4378.    ENDIF
  4379. ENDIF
  4380. \
  4381.  
  4382. *
  4383. * ANYMODAL - Generate MODAL clause on READ.
  4384. *
  4385. *!*****************************************************************************
  4386. *!
  4387. *!      Procedure: ANYMODAL
  4388. *!
  4389. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4390. *!
  4391. *!*****************************************************************************
  4392. PROCEDURE anymodal
  4393. IF m.g_readmodal
  4394.    \\ MODAL
  4395. ENDIF
  4396.  
  4397. *
  4398. * ANYLOCK - Generate LOCK/NOLOCK clause on READ.
  4399. *
  4400. *!*****************************************************************************
  4401. *!
  4402. *!      Procedure: ANYLOCK
  4403. *!
  4404. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4405. *!
  4406. *!*****************************************************************************
  4407. PROCEDURE anylock
  4408. IF m.g_readlock
  4409.    \\ NOLOCK
  4410. ENDIF
  4411.  
  4412. *
  4413. * GENWITHCLAUSE - Generate WITH clause on a READ.
  4414. *
  4415. *!*****************************************************************************
  4416. *!
  4417. *!      Procedure: GENWITHCLAUSE
  4418. *!
  4419. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4420. *!
  4421. *!*****************************************************************************
  4422. PROCEDURE genwithclause
  4423. IF NOT EMPTY(m.g_withlist)
  4424.    \\ ;
  4425.    \    WITH <<m.g_withlist>>
  4426. ENDIF
  4427.  
  4428. *
  4429. * DOPLACECLAUSE - Place READ level clauses for multiple reads.
  4430. *
  4431. * Description:
  4432. * According to the read level clauses encoded in the screen file
  4433. * set variables holding information about each clause.
  4434. *
  4435. *!*****************************************************************************
  4436. *!
  4437. *!      Procedure: DOPLACECLAUSE
  4438. *!
  4439. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4440. *!
  4441. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  4442. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4443. *!               : GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4444. *!               : GENCLAUSECODE      (procedure in GENSCRN.PRG)
  4445. *!
  4446. *!*****************************************************************************
  4447. PROCEDURE doplaceclause
  4448. PARAMETER m.scrnno
  4449. PRIVATE thispretext
  4450. IF g_screens[m.scrnno, 6]
  4451.    LOCATE FOR objtype = c_otscreen
  4452. ELSE
  4453.    LOCATE FOR platform = g_screens[m.scrnno, 7] AND objtype = c_otscreen
  4454. ENDIF
  4455. IF NOT FOUND()
  4456.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  4457.       LINENO(), c_error_3
  4458.    RETURN
  4459. ENDIF
  4460.  
  4461. DO findreadclauses WITH m.scrnno
  4462. DO genreadclauses
  4463. _TEXT = m.g_tmphandle
  4464. m.thispretext = _PRETEXT
  4465. _PRETEXT = ""
  4466.  
  4467. DO genclausecode WITH m.scrnno
  4468. _TEXT = m.g_orghandle
  4469. _PRETEXT = m.thispretext
  4470.  
  4471. *
  4472. * FINDREADCLAUSES - Find clauses for the final READ statement.
  4473. *
  4474. * Description:
  4475. * Keep track of clauses that were already seen to determine what
  4476. * clauses are placed on final read.  If this procedure is called for
  4477. * a multiple read setting, flag's settings apply only to the current
  4478. * screen.
  4479. *
  4480. *!*****************************************************************************
  4481. *!
  4482. *!      Procedure: FINDREADCLAUSES
  4483. *!
  4484. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4485. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4486. *!
  4487. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  4488. *!               : SETCLAUSEFLAGS     (procedure in GENSCRN.PRG)
  4489. *!               : ORCLAUSEFLAGS      (procedure in GENSCRN.PRG)
  4490. *!
  4491. *!*****************************************************************************
  4492. PROCEDURE findreadclauses
  4493. PARAMETER m.scrnno
  4494. PRIVATE m.dbalias, m.cur_rec
  4495. IF g_screens[m.scrnno,6]
  4496.    LOCATE FOR objtype = c_otscreen
  4497. ELSE
  4498.    LOCATE FOR platform = g_screens[m.scrnno, 7] AND objtype = c_otscreen
  4499. ENDIF
  4500. IF NOT FOUND()
  4501.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  4502.       LINENO(), c_error_3
  4503.    RETURN
  4504. ENDIF
  4505.  
  4506. IF EMPTY(m.g_validtype) AND !EMPTY(VALID)
  4507.    DO setclauseflags WITH validtype, VALID, m.g_validname,;
  4508.       m.g_validtype
  4509. ENDIF
  4510. IF EMPTY(m.g_whentype) AND !EMPTY(WHEN)
  4511.    DO setclauseflags  WITH whentype, WHEN, m.g_whenname,;
  4512.       m.g_whentype
  4513. ENDIF
  4514. IF EMPTY(m.g_actitype) AND !EMPTY(ACTIVATE)
  4515.    DO setclauseflags WITH activtype, ACTIVATE, m.g_actiname,;
  4516.       m.g_actitype
  4517. ENDIF
  4518. IF EMPTY(m.g_deattype) AND !EMPTY(DEACTIVATE)
  4519.    DO setclauseflags WITH deacttype, DEACTIVATE, m.g_deatname,;
  4520.       m.g_deattype
  4521. ENDIF
  4522.  
  4523. * SHOW is a special case since it can be generated with both procedures (for refreshable
  4524. * SAYs or just regular procedures) and expressions.  OR the flags together.
  4525. IF !EMPTY(SHOW)
  4526.    IF showtype != c_genexpr
  4527.       DO orclauseflags WITH showtype, SHOW, m.g_showname, m.g_showtype
  4528.    ELSE
  4529.       m.cur_rec = RECNO()
  4530.       * It's an expression, but look for refreshable SAYs too.
  4531.       LOCATE FOR ((objtype = c_otfield AND objcode = c_sgsay) OR (objtype = c_otpicture)) AND ;
  4532.          REFRESH = .T. AND (g_screens[m.scrnno, 6] OR platform = g_screens[m.scrnno, 7])
  4533.       IF FOUND()
  4534.          GOTO m.cur_rec
  4535.          DO orclauseflags WITH c_genboth, SHOW,   m.g_showname, m.g_showtype
  4536.       ELSE
  4537.          GOTO m.cur_rec
  4538.          DO orclauseflags WITH c_genexpr, SHOW,   m.g_showname, m.g_showtype
  4539.       ENDIF
  4540.       m.g_showexpr = m.g_showname
  4541.    ENDIF
  4542. ELSE
  4543.    * Look for refreshable SAYS
  4544.    LOCATE FOR ((objtype = c_otfield AND objcode = c_sgsay) OR (objtype = c_otpicture)) AND ;
  4545.       REFRESH = .T. AND (g_screens[m.scrnno, 6] OR platform = g_screens[m.scrnno, 7])
  4546.    IF FOUND()
  4547.       DO orclauseflags WITH c_gencode, SHOW,   m.g_showname, m.g_showtype
  4548.    ENDIF
  4549. ENDIF
  4550.  
  4551. *
  4552. * SETCLAUSEFLAGS - Load global flags with information about clauses.
  4553. *
  4554. * Description:
  4555. * If a clause is a snippet then a generic name is provided for the
  4556. * clause call statement in the READ and that same name is used to
  4557. * construct the corresponding function.
  4558. *
  4559. * The BOTH setting is used for SHOW clauses that are defined as expressions,
  4560. * in screens that also contain refreshable SAYS.  We have to generate a
  4561. * procedure to contain the code to refresh the SAYS.
  4562. *
  4563. *!*****************************************************************************
  4564. *!
  4565. *!      Procedure: SETCLAUSEFLAGS
  4566. *!
  4567. *!      Called by: FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4568. *!
  4569. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  4570. *!
  4571. *!*****************************************************************************
  4572. PROCEDURE setclauseflags
  4573. PARAMETER m.flagtype, m.memo, m.name, m.type
  4574. DO CASE
  4575. CASE m.flagtype = c_genexpr
  4576.    m.name = m.memo
  4577.    m.type = "EXPR"
  4578. CASE m.flagtype = c_genboth
  4579.    m.name = m.memo
  4580.    m.type = "BOTH"
  4581. OTHERWISE
  4582.    m.name = getcname(m.memo)
  4583.    m.type = "CODE"
  4584. ENDCASE
  4585.  
  4586. *
  4587. * ORCLAUSEFLAGS - Logical OR two flagtypes
  4588. *
  4589. *!*****************************************************************************
  4590. *!
  4591. *!      Procedure: ORCLAUSEFLAGS
  4592. *!
  4593. *!      Called by: FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4594. *!
  4595. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  4596. *!
  4597. *!*****************************************************************************
  4598. PROCEDURE orclauseflags
  4599. PARAMETER m.flagtype, m.memo, m.name, m.type
  4600. DO CASE
  4601. CASE m.flagtype = c_genexpr
  4602.    m.name = m.memo
  4603.    IF INLIST(m.type,"BOTH","CODE")
  4604.       m.type = "BOTH"
  4605.    ELSE
  4606.       m.type = "EXPR"
  4607.    ENDIF
  4608. CASE m.flagtype = c_genboth
  4609.    m.name = m.memo
  4610.    m.type = "BOTH"
  4611. OTHERWISE
  4612.    * Code of some sort.  The expr code is different for expanded snippets, closed snippets, etc.
  4613.    * It is 2 for expanded snippets and 3 for minimized snippets, for example.
  4614.    m.name = getcname(m.memo)
  4615.    IF INLIST(m.type,"BOTH","EXPR")
  4616.       m.type = "BOTH"
  4617.    ELSE
  4618.       m.type = "CODE"
  4619.    ENDIF
  4620. ENDCASE
  4621.  
  4622. *
  4623. * GENREADCLAUSES - Generate Clauses on a READ.
  4624. *
  4625. * Description:
  4626. * Check if clause is appropriate, if so call GENCLAUSE to
  4627. * generate the clause keyword.
  4628. *
  4629. *!*****************************************************************************
  4630. *!
  4631. *!      Procedure: GENREADCLAUSES
  4632. *!
  4633. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4634. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4635. *!
  4636. *!          Calls: GENCLAUSE          (procedure in GENSCRN.PRG)
  4637. *!
  4638. *!*****************************************************************************
  4639. PROCEDURE genreadclauses
  4640. IF NOT EMPTY(m.g_validtype)
  4641.    DO genclause WITH "VALID", m.g_validname, m.g_validtype
  4642. ENDIF
  4643. IF NOT EMPTY(m.g_whentype)
  4644.    DO genclause WITH "WHEN", m.g_whenname, m.g_whentype
  4645. ENDIF
  4646. IF NOT EMPTY(m.g_actitype)
  4647.    DO genclause WITH "ACTIVATE", m.g_actiname, m.g_actitype
  4648. ENDIF
  4649. IF NOT EMPTY(m.g_deattype)
  4650.    DO genclause WITH "DEACTIVATE", m.g_deatname, m.g_deattype
  4651. ENDIF
  4652. IF NOT EMPTY(m.g_showtype)
  4653.    DO genclause WITH "SHOW", m.g_showname, m.g_showtype, m.g_showexpr
  4654. ENDIF
  4655.  
  4656. *
  4657. * GENCLAUSE - Generate Read Level Clause keyword.
  4658. *
  4659. * Description:
  4660. * Generate SHOW,ACTIVATE,WHEN, or VALID clause keyword for a
  4661. * READ statement.
  4662. *
  4663. *!*****************************************************************************
  4664. *!
  4665. *!      Procedure: GENCLAUSE
  4666. *!
  4667. *!      Called by: GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4668. *!
  4669. *!*****************************************************************************
  4670. PROCEDURE genclause
  4671. PARAMETER m.keyword, m.name, m.type, m.expr
  4672. PRIVATE m.codename
  4673. \\ ;
  4674. \    <<m.keyword>>
  4675. DO CASE
  4676. CASE m.type = "CODE"
  4677.    \\ <<m.name>>
  4678.    \\()
  4679. CASE m.type = "EXPR"
  4680.    \\ <<stripCR(m.name)>>
  4681. CASE m.type = "BOTH"
  4682.    * This is tricky.  We need to generate the user's expression followed by
  4683.    * a procedure, presumably containing code to handle refreshable SAYS in
  4684.    * a READ ... SHOW clause.  Right now, the name variable contains the
  4685.    * expression.  Emit it, generate a random name for the SHOW snippet, then
  4686.    * record that random name in the m.name field so that we can remember it
  4687.    * later.  The expression needs to come second (due to the boolean short-cutting
  4688.    * optimization in the interpreter).
  4689.    IF EMPTY(m.expr)
  4690.       m.codename = LOWER(SYS(2015))
  4691.       \\ <<m.codename>>() AND (<<stripCR(m.name)>>)
  4692.       m.name     = m.codename
  4693.    ELSE
  4694.       * There was an explicit expression passed to us.  Use it.
  4695.       m.codename = LOWER(SYS(2015))
  4696.       \\ <<m.codename>>() AND (<<stripCR(m.expr)>>)
  4697.       m.name     = m.codename
  4698.    ENDIF
  4699. ENDCASE
  4700.  
  4701. *
  4702. * GENGIVENREAD - Generate another clause on the READ.
  4703. *
  4704. *!*****************************************************************************
  4705. *!
  4706. *!      Procedure: GENGIVENREAD
  4707. *!
  4708. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4709. *!
  4710. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  4711. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4712. *!
  4713. *!*****************************************************************************
  4714. PROCEDURE gengivenread
  4715. PARAMETER m.screen
  4716. PRIVATE m.i, m.dbalias
  4717. IF m.g_multreads
  4718.    DO seekheader WITH m.screen
  4719.  
  4720.    IF ATC('#READ',setupcode) <> 0
  4721.       DO gendirective WITH ;
  4722.          MLINE(setupcode,ATCLINE('#READ',setupcode)),'#READ'
  4723.    ENDIF
  4724. ELSE
  4725.    FOR m.i = 1 TO m.g_nscreens
  4726.       m.g_screen = m.i
  4727.       m.dbalias = g_screens[m.i,5]
  4728.       SELECT (m.dbalias)
  4729.       DO seekheader WITH m.i
  4730.  
  4731.       IF ATC('#READ',setupcode)<>0
  4732.          DO gendirective WITH ;
  4733.             MLINE(setupcode,ATCLINE('#READ',setupcode)),'#READ'
  4734.          RETURN
  4735.       ENDIF
  4736.    ENDFOR
  4737.    m.g_screen = 0
  4738. ENDIF
  4739.  
  4740. *
  4741. * GENDIRECTIVE - Process #ITSEXPRESSION, #READCLAUSES generator directives.
  4742. *
  4743. *!*****************************************************************************
  4744. *!
  4745. *!      Procedure: GENDIRECTIVE
  4746. *!
  4747. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4748. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  4749. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  4750. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  4751. *!
  4752. *!          Calls: SKIPWHITESPACE()   (function  in GENSCRN.PRG)
  4753. *!
  4754. *!*****************************************************************************
  4755. PROCEDURE gendirective
  4756. PARAMETER m.line, m.directive
  4757. PRIVATE m.newline
  4758. IF ATC(m.directive,m.line)=1
  4759.    IF UPPER(m.directive) = '#REDE'
  4760.       m.g_redefi = .T.
  4761.       RETURN
  4762.    ENDIF
  4763.    m.newline = skipwhitespace(m.line)
  4764.    IF NOT EMPTY(m.newline)
  4765.       DO CASE
  4766.       CASE UPPER(m.directive) = '#READ'
  4767.          \\ ;
  4768.          \    <<UPPER(m.newline)>>
  4769.       CASE UPPER(m.directive) = '#WCLA'
  4770.          \\ ;
  4771.          \    <<UPPER(m.newline)>>
  4772.       CASE UPPER(m.directive) = '#ITSE'
  4773.          m.g_itse = SUBSTR(m.newline,1,1)
  4774.       ENDCASE
  4775.    ENDIF
  4776. ENDIF
  4777.  
  4778. *
  4779. * SKIPWHITESPACE - Trim all white space from parameter string.
  4780. *
  4781. *!*****************************************************************************
  4782. *!
  4783. *!       Function: SKIPWHITESPACE
  4784. *!
  4785. *!      Called by: PREPWNAMES         (procedure in GENSCRN.PRG)
  4786. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4787. *!
  4788. *!*****************************************************************************
  4789. FUNCTION skipwhitespace
  4790. PARAMETER m.line
  4791. PRIVATE m.whitespace
  4792. m.whitespace = AT(' ',m.line)
  4793. IF m.whitespace = 0
  4794.    m.whitespace = AT(CHR(9),m.line)
  4795. ENDIF
  4796. m.line = ALLTRIM(SUBSTR(m.line,m.whitespace))
  4797. DO WHILE SUBSTR(m.line,1,1) = CHR(9)
  4798.    m.line = ALLTRIM(SUBSTR(m.line, 2))
  4799. ENDDO
  4800. RETURN m.line
  4801.  
  4802. **
  4803. ** Code Generating Various Screen Objects
  4804. **
  4805.  
  4806. *
  4807. * DEFPOPUPS - Define popups used in scrollable list definition.
  4808. *
  4809. * Description:
  4810. * Define popup which is later used in the definition of a
  4811. * scrollable list.
  4812. *
  4813. *!*****************************************************************************
  4814. *!
  4815. *!      Procedure: DEFPOPUPS
  4816. *!
  4817. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4818. *!
  4819. *!          Calls: GENPOPDEFI         (procedure in GENSCRN.PRG)
  4820. *!
  4821. *!*****************************************************************************
  4822. PROCEDURE defpopups
  4823. PRIVATE m.i, m.dbalias, m.cnt, m.anylists
  4824. m.cnt = 0
  4825. FOR m.i = 1 TO m.g_nscreens
  4826.    m.g_screen = m.i
  4827.    m.anylists = .F.
  4828.    m.dbalias = g_screens[m.i,5]
  4829.    SELECT (m.dbalias)
  4830.    SCAN FOR objtype = c_otlist AND STYLE > 1 AND ;
  4831.          (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4832.       IF NOT m.anylists
  4833.          \
  4834.          \#REGION <<INT(m.i)>>
  4835.          m.anylists = .T.
  4836.          m.g_somepops = .T.
  4837.       ENDIF
  4838.       m.cnt = m.cnt + 1
  4839.       g_popups[m.cnt,1] = m.dbalias
  4840.       g_popups[m.cnt,2] = RECNO()
  4841.       g_popups[m.cnt,3] = LOWER(SYS(2015))
  4842.  
  4843.       IF MOD(m.cnt,25)=0
  4844.          DIMENSION g_popups[ALEN(g_popups,1)+25,3]
  4845.       ENDIF
  4846.  
  4847.       DO genpopdefi
  4848.    ENDSCAN
  4849. ENDFOR
  4850. m.g_screen = 0
  4851.  
  4852. *
  4853. * GENPOPDEFI
  4854. *
  4855. *!*****************************************************************************
  4856. *!
  4857. *!      Procedure: GENPOPDEFI
  4858. *!
  4859. *!      Called by: DEFPOPUPS          (procedure in GENSCRN.PRG)
  4860. *!
  4861. *!*****************************************************************************
  4862. PROCEDURE genpopdefi
  4863. IF m.g_noreadplain
  4864.    RETURN
  4865. ENDIF
  4866.    
  4867. \DEFINE POPUP <<g_popups[m.cnt,3]>> ;
  4868. DO CASE
  4869. CASE STYLE = 2
  4870.    \    PROMPT STRUCTURE
  4871. CASE STYLE = 3
  4872.    \    PROMPT FIELD <<ALLTRIM(Expr)>>
  4873. CASE STYLE = 4
  4874.    \    PROMPT FILES
  4875.    IF NOT EMPTY(expr)
  4876.       \\ LIKE <<ALLTRIM(Expr)>>
  4877.    ENDIF
  4878. ENDCASE
  4879. \\ ;
  4880. \    SCROLL
  4881. IF m.g_genvers = 'DOS' OR m.g_genvers = 'UNIX'
  4882.    \\ ;
  4883.    \    MARGIN ;
  4884.    \    MARK ""
  4885.    \
  4886. ENDIF
  4887. *
  4888. * RELPOPUPS - Generate code to release generated popups.
  4889. *
  4890. * Description:
  4891. * Generate code to release all popups defined by the generator
  4892. * in conjunction with generating scrollable lists.
  4893. *
  4894. *!*****************************************************************************
  4895. *!
  4896. *!      Procedure: RELPOPUPS
  4897. *!
  4898. *!      Called by: GENCLNENVIRON      (procedure in GENSCRN.PRG)
  4899. *!
  4900. *!*****************************************************************************
  4901. PROCEDURE relpopups
  4902. PRIVATE m.popcnt, m.i, m.margin
  4903. m.popcnt = ALEN(g_popups,1)
  4904. m.margin = 16
  4905.  
  4906. IF EMPTY(g_popups[1,1]) OR m.g_noreadplain
  4907.    RETURN
  4908. ENDIF
  4909.  
  4910. \RELEASE POPUPS <<g_popups[1,3]>>
  4911. m.i = 2
  4912. DO WHILE m.i <= m.popcnt
  4913.    IF EMPTY(g_popups[m.i,1])
  4914.       RETURN
  4915.    ENDIF
  4916.    IF m.margin > 60
  4917.       m.margin = 4
  4918.       \\,;
  4919.       \    <<g_popups[m.i,3]>>
  4920.    ELSE
  4921.       \\, <<g_popups[m.i,3]>>
  4922.    ENDIF
  4923.    m.margin = m.margin + 3 + LEN(g_popups[m.i,3])
  4924.    m.i = m.i + 1
  4925. ENDDO
  4926. \
  4927.  
  4928. *
  4929. * DEFWINDOWS - Generate code for windows.
  4930. *
  4931. * Description:
  4932. * Generate code to define windows designed in the screen builder.
  4933. * Process all SCX databases and if window definitions found
  4934. * call GENWINDEFI to define the windows.
  4935. *
  4936. *!*****************************************************************************
  4937. *!
  4938. *!      Procedure: DEFWINDOWS
  4939. *!
  4940. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4941. *!
  4942. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4943. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4944. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  4945. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  4946. *!
  4947. *!*****************************************************************************
  4948. PROCEDURE defwindows
  4949. PRIVATE m.dbalias, m.pos, m.savearea, m.row, m.col, m.firstfound, m.i
  4950. m.firstfound = .T.
  4951. m.savearea = SELECT()
  4952. FOR m.i = 1 TO m.g_nscreens
  4953.    m.g_screen = m.i
  4954.    m.dbalias = g_screens[m.i,5]
  4955.    SELECT (m.dbalias)
  4956.  
  4957.    SCAN FOR objtype = c_otscreen AND ;
  4958.          (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4959.  
  4960.       IF m.firstfound AND !m.g_noreadplain
  4961.          DO commentblock WITH ""," Window definitions"
  4962.          m.firstfound = .F.
  4963.       ENDIF
  4964.  
  4965.       IF NOT EMPTY(STYLE)
  4966.          IF ATC('#ITSE',setupcode)<>0
  4967.             DO gendirective WITH ;
  4968.                MLINE(setupcode,ATCLINE('#ITSE',setupcode)),'#ITSE'
  4969.          ENDIF
  4970.          IF ATC('#REDE',setupcode)<>0
  4971.             DO gendirective WITH ;
  4972.                MLINE(setupcode,ATCLINE('#REDE',setupcode)),'#REDE'
  4973.          ENDIF
  4974.          DO genwindefi WITH m.i
  4975.       ELSE
  4976.          DO gendesktop WITH m.i
  4977.       ENDIF
  4978.    ENDSCAN
  4979. ENDFOR
  4980. m.g_screen = 0
  4981. SELECT (m.savearea)
  4982.  
  4983. *
  4984. * GENDESKTOP - Generate statements to change the desktop font
  4985. *
  4986. * Description:
  4987. * Generate code to change the desktop font if this screen is on
  4988. * the desktop.  This is done only if the user chose the define window
  4989. * option in the generate dialog.
  4990. *
  4991. *!*****************************************************************************
  4992. *!
  4993. *!      Procedure: GENDESKTOP
  4994. *!
  4995. *!      Called by: DEFWINDOWS         (procedure in GENSCRN.PRG)
  4996. *!
  4997. *!          Calls: WINDOWFROMTO       (procedure in GENSCRN.PRG)
  4998. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  4999. *!               : ANYTITLEORFOOTER   (procedure in GENSCRN.PRG)
  5000. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5001. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5002. *!               : ANYWINDOWCHARS     (procedure in GENSCRN.PRG)
  5003. *!               : ANYBORDER          (procedure in GENSCRN.PRG)
  5004. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  5005. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5006. *!               : ANYICON            (procedure in GENSCRN.PRG)
  5007. *!
  5008. *!*****************************************************************************
  5009. PROCEDURE gendesktop
  5010. PARAMETER m.g_screen
  5011. PRIVATE m.center_flag, m.arrange_flag, m.row, m.col, m.j, m.entries
  5012.  
  5013. IF (g_screens[m.g_screen, 7] != 'WINDOWS' AND g_screens[m.g_screen, 7] != 'MAC')
  5014.    RETURN
  5015. ENDIF
  5016.  
  5017. m.center_flag = .F.
  5018. m.arrange_flag = .F.
  5019.  
  5020. IF NOT m.g_defwin
  5021.    RETURN
  5022. ENDIF
  5023.  
  5024. m.g_moddesktop = .T.
  5025.  
  5026. \MODIFY WINDOW SCREEN ;
  5027.  
  5028. IF g_screens[m.g_screen,6]
  5029.    DO windowfromto
  5030.    IF m.g_genvers = "WINDOWS" OR m.g_genvers = "MAC"
  5031.       \\ ;
  5032.       \    FONT "FoxFont", 9
  5033.    ENDIF
  5034. ELSE
  5035.    SELECT (m.g_projalias)
  5036.    GOTO RECORD g_screens[m.g_screen,3]
  5037.  
  5038.    DO getarrange WITH m.dbalias, m.arrange_flag, m.center_flag
  5039.  
  5040.    DO anytitleorfooter
  5041.    DO anyfont
  5042.    DO anystyle
  5043.    DO anywindowchars
  5044.    DO anyborder
  5045.  
  5046.    IF  !EMPTY(PICTURE)
  5047.       DO anywallpaper
  5048.    ELSE
  5049.       DO anyscheme
  5050.    ENDIF
  5051.    DO anyicon
  5052.  
  5053.    IF (CENTER OR m.center_flag) AND !m.arrange_flag
  5054.       \MOVE WINDOW SCREEN CENTER
  5055.    ENDIF
  5056. ENDIF
  5057. \CLEAR
  5058.  
  5059. *
  5060. * GENWINDEFI - Generate window definition
  5061. *
  5062. * Description:
  5063. * Check to see if window name is unique, if not provide a unique name
  5064. * with the use of SYS(2015) and display a warning message if
  5065. * appropriate.  The window definition is generated only if the
  5066. * user selected that option in the generator dialog.
  5067. *
  5068. *!*****************************************************************************
  5069. *!
  5070. *!      Procedure: GENWINDEFI
  5071. *!
  5072. *!      Called by: DEFWINDOWS         (procedure in GENSCRN.PRG)
  5073. *!
  5074. *!          Calls: UNIQUEWIN()        (function  in GENSCRN.PRG)
  5075. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  5076. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  5077. *!               : ANYTITLEORFOOTER   (procedure in GENSCRN.PRG)
  5078. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5079. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5080. *!               : ANYWINDOWCHARS     (procedure in GENSCRN.PRG)
  5081. *!               : ANYBORDER          (procedure in GENSCRN.PRG)
  5082. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  5083. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5084. *!               : ANYICON            (procedure in GENSCRN.PRG)
  5085. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  5086. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  5087. *!
  5088. *!*****************************************************************************
  5089. PROCEDURE genwindefi
  5090. PARAMETER m.g_screen
  5091. PRIVATE m.name, m.pos, m.dupname, m.arrange_flag, m.center_flag, m.in_parms, m.j
  5092. m.arrange_flag = .F.
  5093. m.center_flag = .F.
  5094. m.dupname = .F.
  5095. m.name = IIF(!EMPTY(g_screens[m.g_screen,2]), g_screens[m.g_screen,2], LOWER(SYS(2015)))
  5096. m.pos = uniquewin(LOWER(m.name), m.g_nwindows, @g_wndows)
  5097. IF m.pos = 0
  5098.    m.dupname = .T.
  5099.    m.name = LOWER(SYS(2015))
  5100.    g_screens[m.g_screen,2] = m.name
  5101.    m.pos = uniquewin(m.name, m.g_nwindows, @g_wndows)
  5102. ENDIF
  5103.  
  5104. * Insert one row (two elements)
  5105. = AINS(g_wndows, m.pos)
  5106. g_wndows[m.pos,1] = m.name
  5107. g_wndows[m.pos,2] = .F.  && it will get a sequence number in AnyWindows
  5108. m.g_nwindows = m.g_nwindows + 1
  5109.  
  5110. m.g_windows = .T.
  5111. IF NOT m.g_defwin
  5112.    RETURN
  5113. ENDIF
  5114.  
  5115. IF NOT m.g_redefi
  5116.    \IF NOT WEXIST("<<m.name>>")
  5117.    * We can safely omit this extra code if the name was a randomly generated one
  5118.    IF  UPPER(LEFT(m.name,2)) <> UPPER(LEFT(SYS(2015),2))
  5119.       \\ ;
  5120.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'PJX'))>>" ;
  5121.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'SCX'))>>" ;
  5122.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'MNX'))>>" ;
  5123.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'PRG'))>>" ;
  5124.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'FRX'))>>" ;
  5125.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'QPR'))>>"
  5126.    ENDIF
  5127.    DO pushindent
  5128. ENDIF
  5129. \DEFINE WINDOW <<m.name>> ;
  5130.  
  5131. SELECT (m.g_projalias)
  5132. GOTO RECORD g_screens[m.g_screen,3]
  5133.  
  5134. DO getarrange WITH m.dbalias, m.arrange_flag, m.center_flag
  5135.  
  5136. DO anytitleorfooter
  5137. DO anyfont
  5138. DO anystyle
  5139. DO anywindowchars
  5140. DO anyborder
  5141.  
  5142. IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC')
  5143.    IF TAB
  5144.       \\ ;
  5145.       \    HALFHEIGHT
  5146.    ENDIF
  5147.    IF  !EMPTY(PICTURE)
  5148.       DO anywallpaper
  5149.    ELSE
  5150.       DO anyscheme
  5151.    ENDIF
  5152.    DO anyicon
  5153. ELSE
  5154.    DO anyscheme
  5155. ENDIF
  5156.  
  5157. * If the user defined additional window clauses, put them here
  5158. IF ATC("#WCLA",setupcode) > 0
  5159.    DO gendirective WITH ;
  5160.       MLINE(setupcode,ATCLINE('#WCLA',setupcode)),'#WCLA'
  5161. ENDIF
  5162.  
  5163. * Emit the MOVE WINDOW ... CENTER after all the window clauses have been emitted
  5164. IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC')
  5165.    IF (CENTER OR m.center_flag) AND !m.arrange_flag
  5166.       \MOVE WINDOW <<m.name>> CENTER
  5167.    ENDIF
  5168. ENDIF
  5169.  
  5170. IF !m.g_redefi
  5171.    DO popindent
  5172.    \ENDIF
  5173. ENDIF
  5174. \
  5175.  
  5176. *!*****************************************************************************
  5177. *!
  5178. *!      Procedure: GETARRANGE
  5179. *!
  5180. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  5181. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  5182. *!
  5183. *!          Calls: WINDOWFROMTO       (procedure in GENSCRN.PRG)
  5184. *!
  5185. *!*****************************************************************************
  5186. PROCEDURE getarrange
  5187. PARAMETER m.dbalias, m.arrange_flag, m.center_flag
  5188. PRIVATE m.j, m.pname, m.entries, m.row, m.col
  5189. IF !EMPTY(arranged)
  5190.    m.entries = INT(LEN(arranged)/26)
  5191.    m.j = 1
  5192.    DO WHILE m.j <= m.entries
  5193.       m.pname = ALLTRIM(UPPER(SUBSTR(arranged,(m.j-1)*26+1,8)))
  5194.       m.pname = ALLTRIM(CHRTRAN(m.pname,CHR(0)," "))
  5195.       IF m.pname == m.g_genvers    && found the right one
  5196.          IF INLIST(UPPER(SUBSTR(arranged,(m.j-1)*26 + 9,1)),'Y','T')    && is it arranged?
  5197.             IF INLIST(UPPER(SUBSTR(arranged,(m.j-1)*26 +10,1)),'Y','T') && is it centered?
  5198.                m.center_flag = .T.
  5199.             ELSE
  5200.                m.arrange_flag = .T.
  5201.                m.row = VAL(SUBSTR(arranged,(m.j-1)*26 + 11,8))
  5202.                m.col = VAL(SUBSTR(arranged,(m.j-1)*26 + 19,8))
  5203.             ENDIF
  5204.          ENDIF
  5205.          EXIT
  5206.       ENDIF
  5207.       m.j = m.j + 1
  5208.    ENDDO
  5209. ENDIF
  5210. SELECT (m.dbalias)
  5211. IF m.arrange_flag
  5212.    DO windowfromto WITH m.row, m.col
  5213. ELSE
  5214.    DO windowfromto
  5215. ENDIF
  5216. RETURN
  5217.  
  5218. *
  5219. * GENBOXES - Generate code for boxes.
  5220. *
  5221. * Description:
  5222. * Generate code to display all boxes as they appear on the painted
  5223. * screen(s).  Note since there is no FILL clause on @...TO command
  5224. * we use the command @...BOX whenever the fill option has been chosen.
  5225. * If Fill option is not chosen, then we use the simpler form for
  5226. * generating boxes, @...TO command which supplies us with clauses
  5227. * DOUBLE and PANEL for the box borders.
  5228. *
  5229. *!*****************************************************************************
  5230. *!
  5231. *!      Procedure: GENBOXES
  5232. *!
  5233. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5234. *!
  5235. *!          Calls: ANYPATTERN         (procedure in GENSCRN.PRG)
  5236. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5237. *!               : ANYPEN             (procedure in GENSCRN.PRG)
  5238. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5239. *!
  5240. *!*****************************************************************************
  5241. PROCEDURE genboxes
  5242. PRIVATE m.bottom, m.right, m.thisbox
  5243. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5244.    SET DECIMALS TO 3
  5245.    m.bottom = HEIGHT+vpos
  5246.    m.right = WIDTH+hpos
  5247. ELSE
  5248.    m.bottom = HEIGHT+vpos-1
  5249.    m.right = WIDTH+hpos-1
  5250. ENDIF
  5251. IF (m.g_genvers = 'WINDOWS' OR m.g_genvers = 'MAC')
  5252.    IF fillchar <> c_null AND fillchar <> " "
  5253.       \@ <<Vpos>>,<<Hpos>>,<<m.bottom>>,<<m.right>>
  5254.       DO CASE
  5255.       CASE objcode = c_sgbox
  5256.          m.thisbox = c_single
  5257.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5258.       CASE objcode = c_sgboxd
  5259.          m.thisbox = c_double
  5260.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5261.       CASE objcode = c_sgboxp
  5262.          m.thisbox = c_panel
  5263.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5264.       CASE objcode = c_sgboxc
  5265.          IF boxchar = '"'
  5266.             \\ BOX REPLICATE('<<Boxchar>>',8)
  5267.          ELSE
  5268.             \\ BOX REPLICATE("<<Boxchar>>",8)
  5269.          ENDIF
  5270.          IF fillchar = '"'
  5271.             \\+'<<Fillchar>>'
  5272.          ELSE
  5273.             \\+"<<Fillchar>>"
  5274.          ENDIF
  5275.       ENDCASE
  5276.       RETURN
  5277.    ELSE
  5278.       \@ <<Vpos>>,<<Hpos>> TO <<m.bottom>>,<<m.right>>
  5279.    ENDIF
  5280. ELSE
  5281.    IF fillchar <> c_null
  5282.       \@ <<Vpos>>,<<Hpos>>,<<m.bottom>>,<<m.right>>
  5283.       DO CASE
  5284.       CASE objcode = c_sgbox
  5285.          m.thisbox = c_single
  5286.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5287.       CASE objcode = c_sgboxd
  5288.          m.thisbox = c_double
  5289.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5290.       CASE objcode = c_sgboxp
  5291.          m.thisbox = c_panel
  5292.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5293.       CASE objcode = c_sgboxc
  5294.          IF boxchar = '"'
  5295.             \\ BOX REPLICATE('<<Boxchar>>',8)
  5296.          ELSE
  5297.             \\ BOX REPLICATE("<<Boxchar>>",8)
  5298.          ENDIF
  5299.          IF fillchar = '"'
  5300.             \\+'<<Fillchar>>'
  5301.          ELSE
  5302.             \\+"<<Fillchar>>"
  5303.          ENDIF
  5304.       ENDCASE
  5305.  
  5306.       IF (!EMPTY(colorpair) OR SCHEME <> 0)
  5307.          * Color the inside of the box if it is filled with something.
  5308.          \@ <<Vpos>>,<<Hpos>> FILL TO <<m.bottom>>,<<m.right>>
  5309.          DO anypattern
  5310.          DO anyscheme
  5311.       ENDIF
  5312.       RETURN
  5313.    ELSE
  5314.       \@ <<Vpos>>,<<Hpos>> TO <<m.bottom>>,<<m.right>>
  5315.    ENDIF
  5316. ENDIF
  5317.  
  5318. SET DECIMALS TO 0
  5319. DO CASE
  5320. CASE objcode = c_sgboxd
  5321.    \\ DOUBLE
  5322. CASE objcode = c_sgboxp
  5323.    \\ PANEL
  5324. CASE objcode = c_sgboxc
  5325.    IF boxchar = '"'
  5326.       \\ '<<Boxchar>>'
  5327.    ELSE
  5328.       \\ "<<Boxchar>>"
  5329.    ENDIF
  5330. ENDCASE
  5331. DO anypattern
  5332. DO anypen
  5333. DO anystyle
  5334. DO anyscheme
  5335.  
  5336. *
  5337. * GENLINES - Generate code for lines.
  5338. *
  5339. * Description:
  5340. * Generate code to display all lines as they appear on the painted
  5341. * screen(s).
  5342. *
  5343. *!*****************************************************************************
  5344. *!
  5345. *!      Procedure: GENLINES
  5346. *!
  5347. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5348. *!
  5349. *!          Calls: ANYPEN             (procedure in GENSCRN.PRG)
  5350. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5351. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5352. *!
  5353. *!*****************************************************************************
  5354. PROCEDURE genlines
  5355. PRIVATE m.x, m.y
  5356. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5357.    SET DECIMALS TO 3
  5358.    IF STYLE = 0
  5359.       m.x = HEIGHT+vpos
  5360.       m.y = hpos
  5361.    ELSE
  5362.       m.x = vpos
  5363.       m.y = WIDTH+hpos
  5364.    ENDIF
  5365. ELSE
  5366.    m.x = HEIGHT+vpos-1
  5367.    m.y = WIDTH+hpos-1
  5368. ENDIF
  5369.  
  5370. \@ <<Vpos>>,<<Hpos>> TO <<m.x>>,<<m.y>>
  5371. SET DECIMALS TO 0
  5372. IF BORDER = 1
  5373.    \\ DOUBLE
  5374. ENDIF
  5375. DO anypen
  5376. DO anystyle
  5377. DO anyscheme
  5378.  
  5379.  
  5380. *
  5381. * GENTEXT - Generate code for text.
  5382. *
  5383. * Description:
  5384. * Generate code that will display the text exactly as it appears
  5385. * in the painted screen(s).
  5386. *
  5387. *!*****************************************************************************
  5388. *!
  5389. *!      Procedure: GENTEXT
  5390. *!
  5391. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5392. *!
  5393. *!          Calls: ANYPICTURE         (procedure in GENSCRN.PRG)
  5394. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5395. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5396. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5397. *!
  5398. *!*****************************************************************************
  5399. PROCEDURE gentext
  5400. PRIVATE m.theexpr, m.occur, m.pos
  5401. m.theexpr = expr
  5402. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5403.    SET DECIMALS TO 3
  5404.    m.occur = 1
  5405.    m.pos = AT(CHR(13), m.theexpr, m.occur)
  5406.    * Sometimes the screen builder surrounds text with single quotes and other
  5407.    * times with double quotes.
  5408.    q1 = LEFT(LTRIM(m.theexpr),1)
  5409.  
  5410.    DO WHILE m.pos > 0
  5411.       IF q1 = "'"
  5412.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5413.             "' + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "'" ;
  5414.             + SUBSTR(m.theexpr, m.pos + 1)
  5415.       ELSE
  5416.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5417.             '" + CHR(13) + ;' + CHR(13)  + CHR(9) + CHR(9) + '"' ;
  5418.             + SUBSTR(m.theexpr, m.pos + 1)
  5419.       ENDIF
  5420.       m.occur = m.occur + 1
  5421.       m.pos = AT(CHR(13), m.theexpr, m.occur)
  5422.    ENDDO
  5423.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> 
  5424.    IF height > 1
  5425.       \\ ;
  5426.       \    SIZE <<Height>>,<<Width>>, <<Spacing>>
  5427.    ENDIF
  5428. ELSE
  5429.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  5430.    \    SIZE <<Height>>,<<Width>>, <<Spacing>>
  5431. ENDIF
  5432.  
  5433. SET DECIMALS TO 0
  5434. DO anypicture
  5435. DO anyfont
  5436. DO anystyle
  5437. DO anyscheme
  5438.  
  5439. *
  5440. * GENFIELDS - Generate fields.
  5441. *
  5442. * Description:
  5443. * Generate code to display SAY, GET, and EDIT statements exactly as they
  5444. * appear in the painted screen(s).
  5445. *
  5446. *!*****************************************************************************
  5447. *!
  5448. *!      Procedure: GENFIELDS
  5449. *!
  5450. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5451. *!
  5452. *!          Calls: ANYFONT            (procedure in GENSCRN.PRG)
  5453. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5454. *!               : ANYPICTURE         (procedure in GENSCRN.PRG)
  5455. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5456. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5457. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  5458. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5459. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5460. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5461. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5462. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5463. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5464. *!
  5465. *!*****************************************************************************
  5466. PROCEDURE genfields
  5467. PRIVATE m.theexpr
  5468. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5469.    SET DECIMALS TO 3
  5470. ENDIF
  5471. DO CASE
  5472. CASE objcode = c_sgsay
  5473.    m.theexpr = expr
  5474.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  5475.    \    SIZE <<Height>>,<<Width>>
  5476.    SET DECIMALS TO 0
  5477.    DO anyfont
  5478.    DO anystyle
  5479.    DO anypicture
  5480.    DO anyscheme
  5481.    RETURN
  5482. CASE objcode = c_sgget
  5483.    \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5484.    \    SIZE <<Height>>,<<Width>>
  5485.    DO elemrange
  5486. CASE objcode = c_sgedit
  5487.    DO gentxtrgn
  5488.    RETURN
  5489. ENDCASE
  5490. SET DECIMALS TO 0
  5491.  
  5492. DO gendefault
  5493. DO anyfont
  5494. DO anystyle
  5495. DO anypicture
  5496. DO anywhen
  5497. DO anyvalid
  5498. DO anymessage
  5499. DO anyerror
  5500. DO anydisabled
  5501. DO anyscheme
  5502.  
  5503. *
  5504. * GENINVBUT - Generate Invisible buttons.
  5505. *
  5506. * Description:
  5507. * Generate code to display invisible buttons exactly as they appear
  5508. * in the painted screen(s).
  5509. *
  5510. *!*****************************************************************************
  5511. *!
  5512. *!      Procedure: GENINVBUT
  5513. *!
  5514. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5515. *!
  5516. *!          Calls: ANYFONT            (procedure in GENSCRN.PRG)
  5517. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5518. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5519. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5520. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5521. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5522. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5523. *!
  5524. *!*****************************************************************************
  5525. PROCEDURE geninvbut
  5526.  
  5527. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5528.    SET DECIMALS TO 3
  5529. ENDIF
  5530. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5531. \    PICTURE <<Picture>> ;
  5532. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5533. \    DEFAULT 0
  5534. SET DECIMALS TO 0
  5535.  
  5536. DO anyfont
  5537. DO anystyle
  5538. DO anywhen
  5539. DO anyvalid
  5540. DO anydisabled
  5541. DO anymessage
  5542. DO anyscheme
  5543.  
  5544. *
  5545. * GENTXTRGN - Generate some statements for text edit region.
  5546. *
  5547. * Description:
  5548. * Generate code to display text edit regions exactly as they
  5549. * appear on the painted screen(s).
  5550. *
  5551. *!*****************************************************************************
  5552. *!
  5553. *!      Procedure: GENTXTRGN
  5554. *!
  5555. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  5556. *!
  5557. *!          Calls: ANYPICTURE         (procedure in GENSCRN.PRG)
  5558. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5559. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5560. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5561. *!               : ANYTAB             (procedure in GENSCRN.PRG)
  5562. *!               : ANYSCROLL          (procedure in GENSCRN.PRG)
  5563. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5564. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5565. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5566. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5567. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5568. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5569. *!
  5570. *!*****************************************************************************
  5571. PROCEDURE gentxtrgn
  5572. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5573.    SET DECIMALS TO 3
  5574. ENDIF
  5575. \@ <<Vpos>>,<<Hpos>> EDIT <<Name>> ;
  5576. \    SIZE <<IIF(Height < 1, 1, Height)>>,<<Width>>,<<Initialnum>>
  5577. SET DECIMALS TO 0
  5578.  
  5579. IF NOT EMPTY(PICTURE)
  5580.    DO anypicture
  5581. ENDIF
  5582. DO gendefault
  5583. DO anyfont
  5584. DO anystyle
  5585. DO anytab
  5586. DO anyscroll
  5587. DO anywhen
  5588. DO anyvalid
  5589. DO anymessage
  5590. DO anyerror
  5591. DO anydisabled
  5592. DO anyscheme
  5593.  
  5594. *
  5595. * GENPUSH - Generate Push buttons.
  5596. *
  5597. * Description:
  5598. * Generate code to display push buttons exactly as they appear
  5599. * in the painted screen(s).
  5600. *
  5601. *!*****************************************************************************
  5602. *!
  5603. *!      Procedure: GENPUSH
  5604. *!
  5605. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5606. *!
  5607. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5608. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5609. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5610. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5611. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5612. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5613. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5614. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5615. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5616. *!
  5617. *!*****************************************************************************
  5618. PROCEDURE genpush
  5619. PRIVATE m.thepicture
  5620.  
  5621. m.thepicture = PICTURE
  5622. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5623.    SET DECIMALS TO 3
  5624. ENDIF
  5625. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5626. DO anybitmapctrl WITH m.thepicture
  5627. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5628. SET DECIMALS TO 0
  5629. \    DEFAULT <<Initialnum>>
  5630. DO anyfont
  5631. DO anystyle
  5632. DO anywhen
  5633. DO anyvalid
  5634. DO anydisabled
  5635. DO anymessage
  5636. DO anyerror
  5637. DO anyscheme
  5638.  
  5639. *
  5640. * GENRADBUT - Generate Radio Buttons.
  5641. *
  5642. * Description:
  5643. * Generate code to display radio buttons exactly as they appear
  5644. * in the painted screen(s).
  5645. *
  5646. *!*****************************************************************************
  5647. *!
  5648. *!      Procedure: GENRADBUT
  5649. *!
  5650. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5651. *!
  5652. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5653. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5654. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5655. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5656. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5657. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5658. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5659. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5660. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5661. *!
  5662. *!*****************************************************************************
  5663. PROCEDURE genradbut
  5664. PRIVATE m.thepicture
  5665.  
  5666. m.thepicture = PICTURE
  5667. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5668.    SET DECIMALS TO 3
  5669. ENDIF
  5670. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5671. DO anybitmapctrl WITH m.thepicture
  5672. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5673. SET DECIMALS TO 0
  5674. \    DEFAULT <<Initialnum>>
  5675. DO anyfont
  5676. DO anystyle
  5677. DO anywhen
  5678. DO anyvalid
  5679. DO anydisabled
  5680. DO anymessage
  5681. DO anyerror
  5682. DO anyscheme
  5683.  
  5684. *
  5685. * GENCHKBOX - Generate Check Boxes
  5686. *
  5687. * Description:
  5688. * Generate code to display check boxes exactly as they appear
  5689. * in the painted screen(s).
  5690. *
  5691. *!*****************************************************************************
  5692. *!
  5693. *!      Procedure: GENCHKBOX
  5694. *!
  5695. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5696. *!
  5697. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5698. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5699. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5700. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5701. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5702. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5703. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5704. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5705. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5706. *!
  5707. *!*****************************************************************************
  5708. PROCEDURE genchkbox
  5709. PRIVATE m.thepicture
  5710.  
  5711. m.thepicture = PICTURE
  5712. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5713.    SET DECIMALS TO 3
  5714. ENDIF
  5715.  
  5716. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5717. DO anybitmapctrl WITH m.thepicture
  5718. \    SIZE <<Height>>,<<Width>> ;
  5719. SET DECIMALS TO 0
  5720. \    DEFAULT <<Initialnum>>
  5721. DO anyfont
  5722. DO anystyle
  5723. DO anywhen
  5724. DO anyvalid
  5725. DO anydisabled
  5726. DO anymessage
  5727. DO anyerror
  5728. DO anyscheme
  5729.  
  5730. *
  5731. * GENLIST - Generate Scrollable Lists.
  5732. *
  5733. * Description:
  5734. * Generate code to display scrollable lists exactly as they appear
  5735. * in the painted screen(s).
  5736. *
  5737. *!*****************************************************************************
  5738. *!
  5739. *!      Procedure: GENLIST
  5740. *!
  5741. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5742. *!
  5743. *!          Calls: CHOPPICTURE        (procedure in GENSCRN.PRG)
  5744. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5745. *!               : FROMPOPUP          (procedure in GENSCRN.PRG)
  5746. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5747. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5748. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5749. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5750. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5751. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5752. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5753. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5754. *!
  5755. *!*****************************************************************************
  5756. PROCEDURE genlist
  5757. PRIVATE m.pos, m.start
  5758. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5759.    SET DECIMALS TO 3
  5760. ENDIF
  5761. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5762. SET DECIMALS TO 0
  5763. IF NOT EMPTY(PICTURE)
  5764.    \     PICTURE
  5765.    DO choppicture WITH PICTURE
  5766.    \\ ;
  5767. ENDIF
  5768. IF STYLE = 0
  5769.    \    FROM <<Expr>>
  5770.    DO elemrange
  5771.    \\ ;
  5772.    IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5773.       SET DECIMALS TO 3
  5774.    ENDIF
  5775.    \    SIZE <<Height>>,<<Width>> ;
  5776.    SET DECIMALS TO 0
  5777.    \    DEFAULT 1
  5778. ELSE
  5779.    DO frompopup
  5780. ENDIF
  5781.  
  5782. DO anyfont
  5783. DO anystyle
  5784. DO anywhen
  5785. DO anyvalid
  5786. DO anydisabled
  5787. DO anymessage
  5788. DO anyerror
  5789. DO anyscheme
  5790.  
  5791. *
  5792. * GENPICTURE - Generate code for pictures.
  5793. *
  5794. * Description:
  5795. * Generate code to display pictures (bitmaps or bitmaps in general fields).
  5796. *
  5797. *!*****************************************************************************
  5798. *!
  5799. *!      Procedure: GENPICTURE
  5800. *!
  5801. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  5802. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  5803. *!
  5804. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  5805. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5806. *!
  5807. *!*****************************************************************************
  5808. PROCEDURE genpicture
  5809. PRIVATE m.relpath
  5810. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5811.    SET DECIMALS TO 3
  5812.    \@ <<Vpos>>,<<Hpos>> SAY
  5813.    IF STYLE = 0
  5814.       m.relpath = LOWER(findrelpath(SUBSTR(PICTURE,2,LEN(PICTURE)-2)))
  5815.       \\ (LOCFILE("<<m.relpath>>","BMP|ICO", "Where is <<basename(m.relpath)>>?")) BITMAP ;
  5816.    ELSE
  5817.       \\ <<Name>> ;
  5818.    ENDIF
  5819.    \    SIZE <<Height>>,<<Width>>
  5820.  
  5821.    IF CENTER
  5822.       \\ ;
  5823.       \    CENTER
  5824.    ENDIF
  5825.  
  5826.    DO CASE
  5827.    CASE BORDER = 1
  5828.       \\ ;
  5829.       \    ISOMETRIC
  5830.    CASE BORDER = 2
  5831.       \\ ;
  5832.       \    STRETCH
  5833.    ENDCASE
  5834.  
  5835.    SET DECIMALS TO 0
  5836.    DO anystyle
  5837. ENDIF
  5838.  
  5839. *
  5840. * GENSPINNER - Generate Spinners
  5841. *
  5842. * Description:
  5843. * Generate code to display spinners exactly as they appear
  5844. * in the painted screen(s).
  5845. *
  5846. *!*****************************************************************************
  5847. *!
  5848. *!      Procedure: GENSPINNER
  5849. *!
  5850. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5851. *!
  5852. *!          Calls: CHOPPICTURE        (procedure in GENSCRN.PRG)
  5853. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5854. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5855. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5856. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5857. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5858. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5859. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5860. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5861. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5862. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5863. *!
  5864. *!*****************************************************************************
  5865. PROCEDURE genspinner
  5866. PRIVATE m.thepicture
  5867.  
  5868. m.thepicture = PICTURE
  5869. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5870.    SET DECIMALS TO 3
  5871. ENDIF
  5872.  
  5873. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5874. \    SPINNER
  5875.  
  5876. ** Generate the increment value
  5877. IF !EMPTY(initialval)
  5878.    IF INT(VAL(initialval)) <> VAL(initialval)
  5879.       SET DECIMALS TO LEN(initialval) - AT('.',initialval)
  5880.    ENDIF
  5881.    \\ <<VAL(Initialval)>>
  5882.    SET DECIMALS TO 3
  5883. ELSE
  5884.    \\ 1.000
  5885. ENDIF
  5886.  
  5887. ** Generate the minimum value.
  5888. IF !EMPTY(TAG)
  5889.    \\, <<Tag>>
  5890. ELSE
  5891.    IF !EMPTY(tag2)
  5892.       \\,
  5893.    ENDIF
  5894. ENDIF
  5895.  
  5896. ** Generate the maximum value.
  5897. IF !EMPTY(tag2)
  5898.    \\, <<Tag2>>
  5899. ENDIF
  5900. \\ ;
  5901.  
  5902. IF !EMPTY(m.thepicture)
  5903.    \    PICTURE
  5904.    DO choppicture WITH m.thepicture
  5905.    \\ ;
  5906. ENDIF
  5907. \    SIZE <<Height>>, <<Width>>
  5908.  
  5909. ** Put out a default which corresponds to the range of valid values.
  5910. IF !EMPTY(TAG)
  5911.    \\ ;
  5912.    \    DEFAULT <<VAL(Tag)>>
  5913. ELSE
  5914.    IF !EMPTY(tag2)
  5915.       \\ ;
  5916.       \    DEFAULT <<VAL(Tag2)>>
  5917.    ELSE
  5918.       DO gendefault
  5919.    ENDIF
  5920. ENDIF
  5921.  
  5922. DO elemrange
  5923. DO anywhen
  5924. DO anyvalid
  5925. DO anydisabled
  5926. DO anymessage
  5927. DO anyerror
  5928. SET DECIMALS TO 0
  5929. DO anyfont
  5930. DO anystyle
  5931. DO anyscheme
  5932.  
  5933. *
  5934. * FROMPOPUP - Generate code for scrollable list defined from a popup.
  5935. *
  5936. * Description:
  5937. * Generate POPUP <popup name> code as part of a scrollable list
  5938. * definition.  Popup name may either be name explicitly provided by
  5939. * the user or a unique name generated by SYS(2015) function.
  5940. *
  5941. *!*****************************************************************************
  5942. *!
  5943. *!      Procedure: FROMPOPUP
  5944. *!
  5945. *!      Called by: GENLIST            (procedure in GENSCRN.PRG)
  5946. *!
  5947. *!*****************************************************************************
  5948. PROCEDURE frompopup
  5949. PRIVATE m.start, m.pos
  5950. \    POPUP
  5951. IF STYLE < 2
  5952.    IF NOT EMPTY(expr)
  5953.       \\ <<Expr>> ;
  5954.    ENDIF
  5955. ELSE
  5956.    m.start = 1
  5957.    m.pos   = 0
  5958.    DO WHILE .T.
  5959.       m.pos = ASCAN(g_popups, m.dbalias, m.start)
  5960.       IF g_popups[m.pos+1] = RECNO()
  5961.          EXIT
  5962.       ENDIF
  5963.       m.start = m.pos + 3
  5964.    ENDDO
  5965.    \\ <<g_popups[m.pos+2]>> ;
  5966. ENDIF
  5967.  
  5968. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5969.    SET DECIMALS TO 3
  5970. ENDIF
  5971. \    SIZE <<Height>>,<<Width>> ;
  5972. \    DEFAULT " "
  5973. SET DECIMALS TO 0
  5974.  
  5975. *
  5976. * GENPOPUP - Generate Popups.
  5977. *
  5978. * Description:
  5979. * Generate code to display popups exactly as they appear in the
  5980. * painted screen(s).
  5981. *
  5982. *!*****************************************************************************
  5983. *!
  5984. *!      Procedure: GENPOPUP
  5985. *!
  5986. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5987. *!
  5988. *!          Calls: ELEMRANGE          (procedure in GENSCRN.PRG)
  5989. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5990. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5991. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5992. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5993. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5994. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5995. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5996. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5997. *!
  5998. *!*****************************************************************************
  5999. PROCEDURE genpopup
  6000. PRIVATE m.thepicture, m.theinitval
  6001.  
  6002. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6003.    SET DECIMALS TO 3
  6004. ENDIF
  6005. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  6006. IF objcode = c_sgget
  6007.    m.thepicture = PICTURE
  6008.    m.theinitval = initialval
  6009.    \    PICTURE <<m.thepicture>> ;
  6010.    \    SIZE <<Height>>,<<Width>> ;
  6011.    \    DEFAULT <<IIF(EMPTY(m.theinitval), '" "', m.theinitval)>>
  6012. ELSE
  6013.    \    PICTURE "@^" ;
  6014.    \    FROM <<Expr>> ;
  6015.    \    SIZE <<Height>>,<<Width>>
  6016.    DO elemrange
  6017.    \\ ;
  6018.    \    DEFAULT 1
  6019. ENDIF
  6020. SET DECIMALS TO 0
  6021.  
  6022. DO anyfont
  6023. DO anystyle
  6024. DO anywhen
  6025. DO anyvalid
  6026. DO anydisabled
  6027. DO anymessage
  6028. DO anyerror
  6029. DO anyscheme
  6030.  
  6031. *
  6032. * ELEMRANGE - Element range clause for popup and scrollable list
  6033. *                defined form an array.
  6034. *
  6035. *!*****************************************************************************
  6036. *!
  6037. *!      Procedure: ELEMRANGE
  6038. *!
  6039. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6040. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6041. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6042. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6043. *!
  6044. *!          Calls: ADDTOCTRL          (procedure in GENSCRN.PRG)
  6045. *!
  6046. *!*****************************************************************************
  6047. PROCEDURE elemrange
  6048. PRIVATE m.firstelem, m.genericname
  6049. m.firstelem = .F.
  6050. IF NOT EMPTY(rangelo)
  6051.    m.firstelem = .T.
  6052.    \\ ;
  6053.    \    RANGE
  6054.    IF lotype = 0
  6055.       \\ <<ALLTRIM(Rangelo)>>
  6056.    ELSE
  6057.       m.genericname = LOWER(SYS(2015))
  6058.       \\ <<m.genericname>>()
  6059.       DO CASE
  6060.       CASE objtype = c_otfield
  6061.          DO addtoctrl WITH m.genericname, "GET Low RANGE", rangelo, name
  6062.       CASE objtype = c_otspinner
  6063.          DO addtoctrl WITH m.genericname, "SPINNER Low RANGE", rangelo, name
  6064.       OTHERWISE
  6065.          DO addtoctrl WITH m.genericname, "Popup From", rangelo, name
  6066.       ENDCASE
  6067.    ENDIF
  6068. ENDIF
  6069. IF NOT EMPTY(rangehi)
  6070.    IF NOT m.firstelem
  6071.       \\ ;
  6072.       \    RANGE ,
  6073.    ELSE
  6074.       \\,
  6075.    ENDIF
  6076.    IF hitype = 0
  6077.       \\ <<ALLTRIM(Rangehi)>>
  6078.    ELSE
  6079.       m.genericname = LOWER(SYS(2015))
  6080.       \\ <<m.genericname>>()
  6081.       DO CASE
  6082.       CASE objtype = c_otfield
  6083.          DO addtoctrl WITH m.genericname, "GET High RANGE", rangehi, name
  6084.       CASE objtype = c_otspinner
  6085.          DO addtoctrl WITH m.genericname, "SPINNER High RANGE", rangehi, name
  6086.       OTHERWISE
  6087.          DO addtoctrl WITH m.genericname, "Popup From", rangehi, name
  6088.       ENDCASE
  6089.    ENDIF
  6090. ENDIF
  6091.  
  6092. *
  6093. * GENACTWINDOW - Generate Activate Window Command.
  6094. *
  6095. * Description:
  6096. * Generate the ACTIVATE WINDOW... command.
  6097. *
  6098. *!*****************************************************************************
  6099. *!
  6100. *!      Procedure: GENACTWINDOW
  6101. *!
  6102. *!      Called by: ANYWINDOWS         (procedure in GENSCRN.PRG)
  6103. *!
  6104. *!*****************************************************************************
  6105. PROCEDURE genactwindow
  6106. PARAMETER m.cnt
  6107. IF !m.g_noreadplain
  6108.    IF m.g_lastwindow == g_screens[m.cnt,2]
  6109.       \@ 0,0 CLEAR
  6110.    ENDIF
  6111.    IF m.g_multreads
  6112.       \ACTIVATE WINDOW <<g_screens[m.cnt,2]>>
  6113.       RETURN
  6114.    ENDIF
  6115.    
  6116.    \IF WVISIBLE("<<g_screens[m.cnt,2]>>")
  6117.    \    ACTIVATE WINDOW <<g_screens[m.cnt,2]>> SAME
  6118.    \ELSE
  6119.    \    ACTIVATE WINDOW <<g_screens[m.cnt,2]>> NOSHOW
  6120.    \ENDIF
  6121. ENDIF
  6122.  
  6123. *
  6124. * GENDEFAULT - Generate Default Clause.
  6125. *
  6126. *!*****************************************************************************
  6127. *!
  6128. *!      Procedure: GENDEFAULT
  6129. *!
  6130. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6131. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6132. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6133. *!
  6134. *!*****************************************************************************
  6135. PROCEDURE gendefault
  6136. PRIVATE m.theinitval
  6137. IF EMPTY(initialval) AND EMPTY(fillchar)
  6138.    RETURN
  6139. ENDIF
  6140. \\ ;
  6141. \    DEFAULT
  6142. IF EMPTY(initialval)
  6143.    DO CASE
  6144.    CASE fillchar = "D"
  6145.       \\ {  /  /  }
  6146.    CASE fillchar = "C" OR fillchar = "M" OR fillchar = "G"
  6147.       \\ " "
  6148.    CASE fillchar = "L"
  6149.       \\ .F.
  6150.    CASE fillchar = "N"
  6151.       \\ 0
  6152.    CASE fillchar = "F"
  6153.       \\ 0.0
  6154.    ENDCASE
  6155. ELSE
  6156.    m.theinitval = initialval
  6157.    \\ <<ALLTRIM(m.theinitval)>>
  6158. ENDIF
  6159.  
  6160. **
  6161. **  Procedures Generating Various Clauses for Screen Objects
  6162. **
  6163.  
  6164. *
  6165. * ANYBITMAPCTRL - Parse the picture clause for a bitmap control (Push button, radio button, checkbox) and return it
  6166. *        with LOCAFILE and a relative path in place of each absolute path.
  6167. *
  6168. *!*****************************************************************************
  6169. *!
  6170. *!      Procedure: ANYBITMAPCTRL
  6171. *!
  6172. *!      Called by: GENPUSH            (procedure in GENSCRN.PRG)
  6173. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6174. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6175. *!
  6176. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6177. *!               : CHOPPICTURE        (procedure in GENSCRN.PRG)
  6178. *!
  6179. *!*****************************************************************************
  6180. PROCEDURE anybitmapctrl
  6181. PARAMETER m.picture
  6182. PRIVATE m.name, m.relpath, m.count
  6183.  
  6184. IF AT("B", SUBSTR(m.picture,1, AT(" ",m.picture))) <> 0
  6185.    \    PICTURE <<LEFT(m.picture, AT(" ",m.picture))>>"
  6186.  
  6187.    m.picture = SUBSTR(m.picture, AT(" ", m.picture)+1)
  6188.    m.picture = LEFT(m.picture, LEN(m.picture)-1)
  6189.    m.count = 0
  6190.  
  6191.    DO WHILE LEN(m.picture) <> 0
  6192.       m.count = m.count + 1
  6193.       IF AT(";", m.picture) <> 0
  6194.          m.name = LEFT(m.picture, AT(";", m.picture)-1)
  6195.          m.picture = SUBSTR(m.picture, AT(";",m.picture)+1)
  6196.       ELSE
  6197.          m.name = m.picture
  6198.          m.picture = ""
  6199.       ENDIF
  6200.  
  6201.       m.relpath = LOWER(findrelpath(m.name))
  6202.       IF m.count = 1
  6203.          \\ + ;
  6204.       ELSE
  6205.          \\ + ";" + ;
  6206.       ENDIF
  6207.       \        (LOCFILE("<<m.relpath>>","BMP|ICO","Where is <<basename(m.relpath)>>?"))
  6208.    ENDDO
  6209.  
  6210.    \\ ;
  6211. ELSE
  6212.    \    PICTURE
  6213.    DO choppicture WITH m.picture
  6214.    \\ ;
  6215. ENDIF
  6216.  
  6217. *
  6218. * CHOPPICTURE - Breaks a Picture clause into multiple 250 character segments to avoid
  6219. *        the maximum string length limit.
  6220. *
  6221. *!*****************************************************************************
  6222. *!
  6223. *!      Procedure: CHOPPICTURE
  6224. *!
  6225. *!      Called by: GENLIST            (procedure in GENSCRN.PRG)
  6226. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6227. *!               : ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  6228. *!
  6229. *!*****************************************************************************
  6230. PROCEDURE choppicture
  6231. PARAMETER m.pict
  6232. PRIVATE m.quotechar, m.first
  6233. m.quotechar = LEFT(m.pict,1)
  6234. m.first = .T.
  6235.  
  6236. DO WHILE LEN(m.pict) > 250
  6237.    IF m.first
  6238.       \\ <<LEFT(m.pict,250) + m.quotechar>> + ;
  6239.       m.first = .F.
  6240.    ELSE
  6241.       \        <<LEFT(m.pict,250) + m.quotechar>> + ;
  6242.    ENDIF
  6243.    m.pict = m.quotechar + SUBSTR(m.pict,251)
  6244. ENDDO
  6245.  
  6246. IF m.first
  6247.    \\ <<m.pict>>
  6248. ELSE
  6249.    \    <<m.pict>>
  6250. ENDIF
  6251.  
  6252. *
  6253. *
  6254. * ANYDISABLED - Place ENABLE/DISABLE clause.
  6255. *
  6256. *!*****************************************************************************
  6257. *!
  6258. *!      Procedure: ANYDISABLED
  6259. *!
  6260. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6261. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6262. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6263. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6264. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6265. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6266. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6267. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6268. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6269. *!
  6270. *!*****************************************************************************
  6271. PROCEDURE anydisabled
  6272. IF disabled
  6273.    \\ ;
  6274.    \    DISABLE
  6275. ENDIF
  6276.  
  6277. *
  6278. * ANYPICTURE
  6279. *
  6280. *!*****************************************************************************
  6281. *!
  6282. *!      Procedure: ANYPICTURE
  6283. *!
  6284. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6285. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6286. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6287. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6288. *!
  6289. *!*****************************************************************************
  6290. PROCEDURE anypicture
  6291. PRIVATE m.string, m.expr_pos, m.newstring
  6292. IF NOT EMPTY(PICTURE) AND PICTURE <> '" "'
  6293.    \\ ;
  6294.    m.string = SUBSTR(PICTURE,2)   && drop opening quotation mark
  6295.    DO CASE
  6296.    CASE SUBSTR(m.string,1,1) = m.g_itse
  6297.       \    PICTURE <<SUBSTR(m.string,2,RAT(LEFT(picture,1),m.string)-2)>>
  6298.    CASE hasexpr(m.string) > 0 && an #ITSEXPRESSION character somewhere in the middle
  6299.        m.expr_pos = hasexpr(picture)
  6300.        * Emit the first part of the PICTURE
  6301.        \    PICTURE <<LEFT(picture,expr_pos-1)>>
  6302.        * Emit a closing quotation mark, which will be the same as the opening one
  6303.        \\<<LEFT(picture,1)>>
  6304.        * Now emit the expression portion of the picture clause, not including a closing quote
  6305.        \\ + <<SUBSTR(picture,expr_pos+1,LEN(picture)-expr_pos-1))>>
  6306.    OTHERWISE
  6307.       \    PICTURE <<Picture>>
  6308.    ENDCASE
  6309. ENDIF
  6310.  
  6311.  
  6312. FUNCTION hasexpr
  6313. PARAMETER m.thepicture
  6314. RETURN ATC(m.g_itse,m.thepicture)
  6315.  
  6316. *
  6317. * ANYSCROLL - Place Scroll clause if applicable.
  6318. *
  6319. *!*****************************************************************************
  6320. *!
  6321. *!      Procedure: ANYSCROLL
  6322. *!
  6323. *!      Called by: GENTXTRGN          (procedure in GENSCRN.PRG)
  6324. *!
  6325. *!*****************************************************************************
  6326. PROCEDURE anyscroll
  6327. IF scrollbar
  6328.    \\ ;
  6329.    \    SCROLL
  6330. ENDIF
  6331.  
  6332. *
  6333. * ANYTAB - Place Tab clause on an @...EDIT command.
  6334. *
  6335. *!*****************************************************************************
  6336. *!
  6337. *!      Procedure: ANYTAB
  6338. *!
  6339. *!      Called by: GENTXTRGN          (procedure in GENSCRN.PRG)
  6340. *!
  6341. *!*****************************************************************************
  6342. PROCEDURE anytab
  6343. IF TAB
  6344.    \\ ;
  6345.    \    TAB
  6346. ENDIF
  6347.  
  6348. *
  6349. * ANYFONT - Place font clause on an object if in a graphical
  6350. *        environment
  6351. *
  6352. *!*****************************************************************************
  6353. *!
  6354. *!      Procedure: ANYFONT
  6355. *!
  6356. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6357. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6358. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6359. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6360. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6361. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6362. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6363. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6364. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6365. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6366. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6367. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6368. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6369. *!
  6370. *!*****************************************************************************
  6371. PROCEDURE anyfont
  6372. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6373.    \\ ;
  6374.    \    FONT "<<Fontface>>", <<Fontsize>>
  6375. ENDIF
  6376.  
  6377. *
  6378. * ANYSTYLE - Place a Style clause in an object.
  6379. *
  6380. *!*****************************************************************************
  6381. *!
  6382. *!      Procedure: ANYSTYLE
  6383. *!
  6384. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6385. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6386. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6387. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  6388. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6389. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6390. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6391. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6392. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6393. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6394. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6395. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6396. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6397. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  6398. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6399. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6400. *!
  6401. *!*****************************************************************************
  6402. PROCEDURE anystyle
  6403. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6404.    IF NOT EMPTY(fontstyle) OR mode != 0 OR ;
  6405.          (NOT EMPTY(STYLE) AND objtype != c_otscreen AND ;
  6406.          objtype != c_ottext )
  6407.       \\ ;
  6408.       \    STYLE "
  6409.       DO CASE
  6410.       CASE fontstyle = 1
  6411.          \\B
  6412.       CASE fontstyle = 2
  6413.          \\I
  6414.       CASE fontstyle = 3
  6415.          \\BI
  6416.       ENDCASE
  6417.  
  6418.       IF mode = 1
  6419.          \\T
  6420.       ENDIF
  6421.  
  6422.       IF NOT EMPTY(STYLE) AND objtype != c_otscreen AND ;
  6423.             objtype != c_otlist AND objtype != c_ottext AND ;
  6424.                         objtype != c_otpicture
  6425.          \\<<Style>>
  6426.       ENDIF
  6427.       \\"
  6428.    ENDIF
  6429. ENDIF
  6430.  
  6431. *
  6432. * ANYPATTERN - Place a PATTERN clause for boxes.
  6433. *
  6434. *!*****************************************************************************
  6435. *!
  6436. *!      Procedure: ANYPATTERN
  6437. *!
  6438. *!      Called by: GENBOXES           (procedure in GENSCRN.PRG)
  6439. *!
  6440. *!*****************************************************************************
  6441. PROCEDURE anypattern
  6442. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6443.    IF fillpat != 0
  6444.       \\ ;
  6445.       \    PATTERN <<Fillpat>>
  6446.    ENDIF
  6447. ENDIF
  6448.  
  6449. *
  6450. * ANYSCHEME - Place Color Scheme clause if applicable.
  6451. *
  6452. *!*****************************************************************************
  6453. *!
  6454. *!      Procedure: ANYSCHEME
  6455. *!
  6456. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6457. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6458. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6459. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  6460. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6461. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6462. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6463. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6464. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6465. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6466. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6467. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6468. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6469. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6470. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6471. *!
  6472. *!*****************************************************************************
  6473. PROCEDURE anyscheme
  6474.  
  6475. IF NOT EMPTY(colorpair)
  6476.    \\ ;
  6477.    \    COLOR <<Colorpair>>
  6478.    RETURN
  6479. ENDIF
  6480. IF SCHEME <> 0
  6481.    \\ ;
  6482.    \    COLOR SCHEME <<Scheme>>
  6483.    IF objtype = c_otpopup AND scheme2<>0
  6484.       \\, <<Scheme2>>
  6485.    ENDIF
  6486. ELSE
  6487.    IF m.g_defasch2 <> 0
  6488.       DO CASE
  6489.       CASE objtype = c_ottext AND HEIGHT > 1
  6490.          \\ ;
  6491.          \    COLOR SCHEME <<m.g_defasch2>>
  6492.       CASE objtype = c_otlist
  6493.          \\ ;
  6494.          \    COLOR SCHEME <<m.g_defasch2>>
  6495.       CASE objtype = c_otpopup
  6496.          \\ ;
  6497.          \    COLOR SCHEME <<m.g_defasch1>>, <<m.g_defasch2>>
  6498.       ENDCASE
  6499.    ELSE
  6500.       IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC' ) ;
  6501.             AND ((ObjTYpe = c_otscreen AND fillred >=0) ;
  6502.              OR (ObjType <> c_otscreen AND (penred >= 0 OR fillred >= 0)) )
  6503.          m.ctrlflag = .F.   && .T. if this is a control-type object (e.g., radio button)
  6504.          \\ ;
  6505.          \    COLOR
  6506.          DO CASE
  6507.          CASE INLIST(objtype,c_otfield,c_otspinner)
  6508.             ** Field or spinner - color pair 2
  6509.             DO CASE
  6510.             CASE objcode = c_sgget OR objcode = c_sgedit
  6511.                \\ ,RGB(
  6512.             CASE objcode = c_sgsay
  6513.                \\ RGB(
  6514.             CASE objcode = c_sgfrom
  6515.                \\ ,,,,,,,,RGB(
  6516.             ENDCASE
  6517.  
  6518.          CASE objtype = c_otlist
  6519.             m.ctrlflag = .T.    && remember that this is a control object
  6520.             \\ RGB(
  6521.  
  6522.  
  6523.          CASE objtype = c_ottext OR objtype = c_otscreen OR ;
  6524.                objtype = c_otbox OR objtype = c_otline
  6525.             ** Text, Box, Line, or Screen - color pair 1
  6526.             \\ RGB(
  6527.  
  6528.          OTHERWISE
  6529.             m.ctrlflag = .T.    && remember that this is a control object
  6530.             \\ ,,,,,,,,RGB(
  6531.          ENDCASE
  6532.  
  6533.          IF penred >= 0
  6534.             \\<<Penred>>,<<Pengreen>>,<<Penblue>>,
  6535.          ELSE
  6536.             \\,,,
  6537.          ENDIF
  6538.          IF fillred >= 0
  6539.             \\<<Fillred>>,<<Fillgreen>>,<<Fillblue>>)
  6540.          ELSE
  6541.             \\,,,)
  6542.          ENDIF
  6543.  
  6544.          IF m.ctrlflag AND INLIST(objtype, c_otradbut, c_otchkbox, c_otpopup,c_otlist)
  6545.             * Add one more RGB clause to control the disabled colors for control
  6546.             * objects such as radio buttons, check boxes, popups, etc.
  6547.             \\,RGB(
  6548.             IF penred >= 0
  6549.                \\<<Penred>>,<<Pengreen>>,<<Penblue>>,
  6550.             ELSE
  6551.                \\,,,
  6552.             ENDIF
  6553.             IF fillred >= 0
  6554.                \\<<Fillred>>,<<Fillgreen>>,<<Fillblue>>)
  6555.             ELSE
  6556.                \\,,,)
  6557.             ENDIF
  6558.          ENDIF
  6559.       ENDIF
  6560.    ENDIF
  6561. ENDIF
  6562.  
  6563. *
  6564. * ANYPEN - Place Color Scheme clause if applicable.
  6565. *
  6566. *!*****************************************************************************
  6567. *!
  6568. *!      Procedure: ANYPEN
  6569. *!
  6570. *!      Called by: GENBOXES           (procedure in GENSCRN.PRG)
  6571. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6572. *!
  6573. *!*****************************************************************************
  6574. PROCEDURE anypen
  6575. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6576.    \\ ;
  6577.    \    PEN <<Pensize>>, <<Penpat>>
  6578. ENDIF
  6579.  
  6580. *
  6581. * ANYVALID - Place Valid clause if applicable.
  6582. *
  6583. *!*****************************************************************************
  6584. *!
  6585. *!      Procedure: ANYVALID
  6586. *!
  6587. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6588. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6589. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6590. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6591. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6592. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6593. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6594. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6595. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6596. *!
  6597. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6598. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6599. *!
  6600. *!*****************************************************************************
  6601. PROCEDURE anyvalid
  6602. PRIVATE m.genericname, m.valid
  6603. IF NOT EMPTY(VALID)
  6604.    \\ ;
  6605.    IF validtype = 0
  6606.       m.valid = VALID
  6607.       \    VALID <<stripcr(m.valid)>>
  6608.    ELSE
  6609.       m.genericname = getcname(VALID)
  6610.       \    VALID <<m.genericname>>()
  6611.       DO addtoctrl WITH m.genericname, "VALID", VALID, name
  6612.    ENDIF
  6613. ENDIF
  6614.  
  6615. *
  6616. * ANYTITLEORFOOTER - Place Window Title/Footer clause.
  6617. *
  6618. *!*****************************************************************************
  6619. *!
  6620. *!      Procedure: ANYTITLEORFOOTER
  6621. *!
  6622. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6623. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6624. *!
  6625. *!*****************************************************************************
  6626. PROCEDURE anytitleorfooter
  6627. PRIVATE m.string, m.thetag
  6628. IF NOT EMPTY(TAG)
  6629.    \\ ;
  6630.    m.string = SUBSTR(TAG,2)
  6631.    IF SUBSTR(m.string,1,1) = m.g_itse
  6632.       \    TITLE <<SUBSTR(m.string, 2, RAT('"',m.string)-2)>>
  6633.    ELSE
  6634.       m.thetag = TAG
  6635.       \    TITLE <<m.thetag>>
  6636.    ENDIF
  6637. ENDIF
  6638. IF NOT EMPTY(tag2)
  6639.    \\ ;
  6640.    m.string = SUBSTR(tag2,2)
  6641.    IF SUBSTR(m.string,1,1) = m.g_itse
  6642.       \    FOOTER <<SUBSTR(m.string, 2, RAT('"',m.string)-2)>>
  6643.    ELSE
  6644.       m.thetag = tag2
  6645.       \    FOOTER <<m.thetag>>
  6646.    ENDIF
  6647. ENDIF
  6648.  
  6649.  
  6650. *
  6651. * ANYWHEN - Place a When clause in a Get field.
  6652. *
  6653. *!*****************************************************************************
  6654. *!
  6655. *!      Procedure: ANYWHEN
  6656. *!
  6657. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6658. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6659. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6660. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6661. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6662. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6663. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6664. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6665. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6666. *!
  6667. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6668. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6669. *!
  6670. *!*****************************************************************************
  6671. PROCEDURE anywhen
  6672. PRIVATE m.genericname, m.when
  6673. IF EMPTY(WHEN)
  6674.    RETURN
  6675. ENDIF
  6676. \\ ;
  6677. IF whentype = 0
  6678.    m.when = WHEN
  6679.    \    WHEN <<stripcr(m.when)>>
  6680. ELSE
  6681.    m.genericname = getcname(WHEN)
  6682.    \    WHEN <<m.genericname>>()
  6683.    DO addtoctrl WITH m.genericname, "WHEN", WHEN, name
  6684. ENDIF
  6685.  
  6686. *
  6687. * ANYMESSAGE - Place a message clause whenever appropriate.
  6688. *
  6689. *!*****************************************************************************
  6690. *!
  6691. *!      Procedure: ANYMESSAGE
  6692. *!
  6693. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6694. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6695. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6696. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6697. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6698. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6699. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6700. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6701. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6702. *!
  6703. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6704. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6705. *!
  6706. *!*****************************************************************************
  6707. PROCEDURE anymessage
  6708. PRIVATE m.genericname, m.mess
  6709. IF EMPTY(MESSAGE)
  6710.    RETURN
  6711. ENDIF
  6712. \\ ;
  6713. IF messtype = 0
  6714.    m.mess = MESSAGE
  6715.    \    MESSAGE
  6716.    \\ <<stripcr(m.mess)>>
  6717. ELSE
  6718.    m.genericname = getcname(MESSAGE)
  6719.    \    MESSAGE <<m.genericname>>()
  6720.    DO addtoctrl WITH m.genericname, "MESSAGE", MESSAGE, name
  6721. ENDIF
  6722.  
  6723. *
  6724. * ANYERROR - Place an error clause whenever appropriate.
  6725. *
  6726. *!*****************************************************************************
  6727. *!
  6728. *!      Procedure: ANYERROR
  6729. *!
  6730. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6731. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6732. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6733. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6734. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6735. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6736. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6737. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6738. *!
  6739. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6740. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6741. *!
  6742. *!*****************************************************************************
  6743. PROCEDURE anyerror
  6744. PRIVATE m.genericname, m.err
  6745. IF EMPTY(ERROR)
  6746.    RETURN
  6747. ENDIF
  6748. \\ ;
  6749. IF errortype = 0
  6750.    m.err = ERROR
  6751.    \    ERROR
  6752.    \\ <<stripcr(m.err)>>
  6753. ELSE
  6754.    m.genericname = getcname(ERROR)
  6755.    \    ERROR <<m.genericname>>()
  6756.    DO addtoctrl WITH m.genericname, "ERROR", ERROR, name
  6757. ENDIF
  6758.  
  6759. *
  6760. * ANYFILL - Place the Fill clause whenever appropriate.
  6761. *
  6762. *!*****************************************************************************
  6763. *!
  6764. *!      Procedure: ANYFILL
  6765. *!
  6766. *!*****************************************************************************
  6767. PROCEDURE anyfill
  6768. IF fillchar <> c_null
  6769.    \\ ;
  6770.    \    FILL "<<Fillchar>>"
  6771. ENDIF
  6772.  
  6773. *
  6774. * ANYWINDOWCHARS - Place window characteristics options.
  6775. *
  6776. * Description:
  6777. * Place the FLOAT, GROW, CLOSE, ZOOM, SHADOW, and MINIMIZE clauses
  6778. * for a window painted by the user.
  6779. *
  6780. *!*****************************************************************************
  6781. *!
  6782. *!      Procedure: ANYWINDOWCHARS
  6783. *!
  6784. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6785. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6786. *!
  6787. *!*****************************************************************************
  6788. PROCEDURE anywindowchars
  6789. \\ ;
  6790. \    <<IIF(Float, "FLOAT ;", "NOFLOAT ;")>>
  6791. \    <<IIF(Close, "CLOSE", "NOCLOSE")>>
  6792. IF SHADOW
  6793.    \\ ;
  6794.    \    SHADOW
  6795. ENDIF
  6796. IF MINIMIZE
  6797.    \\ ;
  6798.    \    MINIMIZE
  6799. ELSE
  6800.    \\ ;
  6801.    \    NOMINIMIZE
  6802. ENDIF
  6803.  
  6804. *
  6805. * ANYBORDER - Place Border type clause on a box.
  6806. *
  6807. * Description:
  6808. * Place border type clause on a box depending on the setting of
  6809. * the field Border.
  6810. *
  6811. *!*****************************************************************************
  6812. *!
  6813. *!      Procedure: ANYBORDER
  6814. *!
  6815. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6816. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6817. *!
  6818. *!*****************************************************************************
  6819. PROCEDURE anyborder
  6820. IF BORDER<>1
  6821.    \\ ;
  6822. ENDIF
  6823.  
  6824. DO CASE
  6825. CASE BORDER = 0
  6826.    \    NONE
  6827. CASE BORDER = 2
  6828.    \    DOUBLE
  6829. CASE BORDER = 3
  6830.    \    PANEL
  6831. CASE BORDER = 4
  6832.    \    SYSTEM
  6833. ENDCASE
  6834.  
  6835. *
  6836. * ANYWALLPAPER - Place FILL FILE clause on any window.
  6837. *
  6838. *!*****************************************************************************
  6839. *!
  6840. *!      Procedure: ANYWALLPAPER
  6841. *!
  6842. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6843. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6844. *!
  6845. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6846. *!
  6847. *!*****************************************************************************
  6848. PROCEDURE anywallpaper
  6849. IF !EMPTY(PICTURE)
  6850.    m.relpath = findrelpath(SUBSTR(PICTURE, 2, LEN(PICTURE) - 2))
  6851.    \\ ;
  6852.    \    FILL FILE LOCFILE("<<m.relpath>>","BMP|ICO", ;
  6853.    \        "Where is <<LOWER(basename(m.relpath))>>?")
  6854. ENDIF
  6855.  
  6856. *
  6857. * ANYICON - Place ICON FILE clause on any window.
  6858. *
  6859. *!*****************************************************************************
  6860. *!
  6861. *!      Procedure: ANYICON
  6862. *!
  6863. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6864. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6865. *!
  6866. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6867. *!
  6868. *!*****************************************************************************
  6869. PROCEDURE anyicon
  6870. IF !EMPTY(ORDER) AND ORDER <> '""'
  6871.    m.relpath = findrelpath(SUBSTR(ORDER, 2, LEN(ORDER) - 2))
  6872.    \\ ;
  6873.    \    ICON FILE LOCFILE("<<m.relpath>>","ICO", ;
  6874.    \        "Where is <<LOWER(basename(m.relpath))>>?")
  6875. ENDIF
  6876.  
  6877. *
  6878. * WINDOWFROMTO - Place FROM...TO clause on any window.
  6879. *
  6880. * Description:
  6881. * Place FROM...TO clause on any window designed in the screen
  6882. * painter.  If window is to be centered, then adjust the coordinates
  6883. * accordingly.
  6884. *
  6885. *!*****************************************************************************
  6886. *!
  6887. *!      Procedure: WINDOWFROMTO
  6888. *!
  6889. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6890. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  6891. *!
  6892. *!*****************************************************************************
  6893. PROCEDURE windowfromto
  6894. PARAMETER m.xcoord, m.ycoord
  6895. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6896.    SET DECIMALS TO 3
  6897. ENDIF
  6898. IF PARAMETERS() = 0
  6899.    IF CENTER
  6900.       IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6901.          \    AT  <<Vpos>>, <<Hpos>>  ;
  6902.          \    SIZE <<Height>>,<<Width>>
  6903.       ELSE
  6904.          \    FROM INT((SROW()-<<Height>>)/2),
  6905.          \\INT((SCOL()-<<Width>>)/2) ;
  6906.          \    TO INT((SROW()-<<Height>>)/2)+<<Height-1>>,
  6907.          \\INT((SCOL()-<<Width>>)/2)+<<Width-1>>
  6908.       ENDIF
  6909.    ELSE
  6910.       IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6911.          \    AT <<Vpos>>, <<Hpos>> ;
  6912.          \    SIZE <<Height>>,<<Width>>
  6913.       ELSE
  6914.          \    FROM <<Vpos>>, <<Hpos>> ;
  6915.          \    TO <<Height+Vpos-1>>,<<Width+Hpos-1>>
  6916.       ENDIF
  6917.    ENDIF
  6918. ELSE
  6919.    IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6920.       \    AT <<m.xcoord>>, <<m.ycoord>> ;
  6921.       \    SIZE <<Height>>,<<Width>>
  6922.    ELSE
  6923.       \    FROM <<m.xcoord>>, <<m.ycoord>> ;
  6924.       \    TO <<Height+m.xcoord-1>>,<<Width+m.ycoord-1>>
  6925.    ENDIF
  6926. ENDIF
  6927. SET DECIMALS TO 0
  6928.  
  6929. **
  6930. ** Code Generating Documentation in Control and Format files.
  6931. **
  6932.  
  6933. *
  6934. * HEADER - Generate application program's header.
  6935. *
  6936. * Description:
  6937. * As a part of the application's header generate program name, name
  6938. * of the author of the program, copyright notice, company name and
  6939. * address, and the word 'Description:' which will be followed with
  6940. * the application description generated by a separate procedure.
  6941. *
  6942. *!*****************************************************************************
  6943. *!
  6944. *!      Procedure: HEADER
  6945. *!
  6946. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  6947. *!
  6948. *!*****************************************************************************
  6949. PROCEDURE HEADER
  6950. IF LEN(_PRETEXT) <> 0
  6951.    \
  6952. ENDIF
  6953. \\*       <<m.g_corn1>><<REPLICATE(m.g_horiz,57)>><<m.g_corn2>>
  6954. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  6955. \*       <<m.g_verti1>> <<DATE()>>
  6956. \\<<PADC(UPPER(ALLTRIM(strippath(m.g_outfile))),IIF(SET("CENTURY")="ON",35,37))," ")>>
  6957. \\  <<TIME()>> <<m.g_verti2>>
  6958. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  6959. \*       <<m.g_corn5>><<REPLICATE(m.g_horiz,57)>><<m.g_corn6>>
  6960. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  6961. \*       <<m.g_verti1>> <<m.g_devauthor>>
  6962. \\<<REPLICATE(" ",56-LEN(m.g_devauthor))>><<m.g_verti2>>
  6963. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  6964. \*       <<m.g_verti1>>
  6965. \\ Copyright (c) <<YEAR(DATE())>>
  6966. IF LEN(ALLTRIM(m.g_devcompany)) <= 36
  6967.    \\ <<ALLTRIM(m.g_devcompany)>>
  6968.    \\<<REPLICATE(" ",37-LEN(ALLTRIM(m.g_devcompany)))>>
  6969.    \\<<m.g_verti2>>
  6970. ELSE
  6971.    \\ <<REPLICATE(" ",37)>><<m.g_verti2>>
  6972.    \*       <<m.g_verti1>> <<m.g_devcompany>>
  6973.    \\<<REPLICATE(" ",56-LEN(m.g_devcompany))>><<m.g_verti2>>
  6974. ENDIF
  6975. \*       <<m.g_verti1>> <<m.g_devaddress>>
  6976. \\<<REPLICATE(" ",56-LEN(m.g_devaddress))>><<m.g_verti2>>
  6977.  
  6978. \*       <<m.g_verti1>> <<ALLTRIM(m.g_devcity)>>, <<m.g_devstate>>
  6979. \\  <<ALLTRIM(m.g_devzip)>>
  6980. \\<<REPLICATE(" ",50-(LEN(ALLTRIM(m.g_devcity)+ALLTRIM(m.g_devzip))))>>
  6981. \\<<m.g_verti2>>
  6982.  
  6983. IF !INLIST(ALLTRIM(UPPER(m.g_devctry)),"USA","COUNTRY") AND !EMPTY(m.g_devctry)
  6984.    \*       <<m.g_verti1>> <<ALLTRIM(m.g_devctry)>>
  6985.    \\<<REPLICATE(" ",50-(LEN(ALLTRIM(m.g_devctry))))>>
  6986.    \\<<m.g_verti2>>
  6987. ENDIF
  6988.  
  6989. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  6990. \*       <<m.g_verti1>> Description:
  6991. \\                                            <<m.g_verti2>>
  6992. \*       <<m.g_verti1>>
  6993. \\ This program was automatically generated by GENSCRN.
  6994. \\    <<m.g_verti2>>
  6995. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  6996. \*       <<m.g_corn3>><<REPLICATE(m.g_horiz,57)>><<m.g_corn4>>
  6997. \
  6998.  
  6999. *
  7000. * GENFUNCHEADER - Generate Comment for Function/Procedure.
  7001. *
  7002. *!*****************************************************************************
  7003. *!
  7004. *!      Procedure: GENFUNCHEADER
  7005. *!
  7006. *!      Called by: VALICLAUSE         (procedure in GENSCRN.PRG)
  7007. *!               : WHENCLAUSE         (procedure in GENSCRN.PRG)
  7008. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7009. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7010. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7011. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  7012. *!
  7013. *!*****************************************************************************
  7014. PROCEDURE genfuncheader
  7015. PARAMETER m.procname, m.from, m.readlevel, m.varname
  7016. m.g_snippcnt = m.g_snippcnt + 1
  7017. \
  7018. \*       <<m.g_corn1>><<REPLICATE(m.g_horiz,57)>><<m.g_corn2>>
  7019. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7020. IF m.readlevel
  7021.    \*       <<m.g_verti1>>
  7022.    \\ <<UPPER(m.procname)>>           <<m.from>>
  7023.    \\<<REPLICATE(" ",45-LEN(m.procname+m.from))>><<m.g_verti2>>
  7024. ELSE
  7025.    \*       <<m.g_verti1>>
  7026.    \\ <<UPPER(m.procname)>>           <<m.varname>> <<m.from>>
  7027.    \\<<REPLICATE(" ",44-LEN(m.procname+m.varname+m.from))>><<m.g_verti2>>
  7028. ENDIF
  7029. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7030. \*       <<m.g_verti1>> Function Origin:
  7031. \\<<REPLICATE(" ",40)>><<m.g_verti2>>
  7032. IF m.readlevel
  7033.    \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7034.    \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7035.    \*       <<m.g_verti1>> From Platform:
  7036.    \\       <<VersionCap(m.g_genvers)>>
  7037.    \\<<REPLICATE(" ",35-LEN(VersionCap(m.g_genvers)))>>
  7038.    \\<<m.g_verti2>>
  7039.    \*       <<m.g_verti1>> From Screen:
  7040.    IF m.g_nscreens > 1 AND NOT m.g_multread
  7041.       \\         Multiple Screens
  7042.       \\<<REPLICATE(" ",19)>><<m.g_verti2>>
  7043.    ELSE
  7044.       \\         <<basename(SYS(2014,DBF()))>>
  7045.       \\<<REPLICATE(" ",35-LEN(basename(SYS(2014,DBF()))))>>
  7046.       \\<<m.g_verti2>>
  7047.    ENDIF
  7048.    \*       <<m.g_verti1>> Called By:           READ Statement
  7049.    \\<<REPLICATE(" ",21)>><<m.g_verti2>>
  7050.    \*       <<m.g_verti1>> Snippet Number:
  7051.    \\      <<ALLTRIM(STR(m.g_snippcnt,2))>>
  7052.    \\<<REPLICATE(" ",35-LEN(ALLTRIM(STR(m.g_snippcnt,2))))>><<m.g_verti2>>
  7053.    \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7054.    \*       <<m.g_corn3>><<REPLICATE(m.g_horiz,57)>><<m.g_corn4>>
  7055.    \*
  7056.    RETURN
  7057. ENDIF
  7058. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7059. \*       <<m.g_verti1>> From Platform:
  7060. \\       <<VersionCap(m.g_genvers)>>
  7061. \\<<REPLICATE(" ",35-LEN(VersionCap(m.g_genvers)))>>
  7062. \\<<m.g_verti2>>
  7063. \*       <<m.g_verti1>> From Screen:
  7064. \\         <<basename(SYS(2014,DBF()))>>
  7065. \\,     Record Number:  <<STR(RECNO(),3)>>
  7066. \\<<REPLICATE(" ",10-LEN(basename(SYS(2014,DBF())+STR(RECNO(),3))))>>
  7067. \\<<m.g_verti2>>
  7068. IF NOT EMPTY(m.varname)
  7069.    \*       <<m.g_verti1>> Variable:            <<m.varname>>
  7070.    \\<<REPLICATE(" ",35-LEN(m.varname))>><<m.g_verti2>>
  7071. ENDIF
  7072. \*       <<m.g_verti1>> Called By:           <<m.from+" Clause">>
  7073. \\<<REPLICATE(" ",35-LEN(m.from+" Clause"))>><<m.g_verti2>>
  7074. IF OBJECT(objtype) <> ""
  7075.    \*       <<m.g_verti1>> Object Type:
  7076.    \\         <<Object(Objtype)>>
  7077.    \\<<REPLICATE(" ",35-LEN(Object(Objtype)))>><<m.g_verti2>>
  7078. ENDIF
  7079. \*       <<m.g_verti1>> Snippet Number:
  7080. \\      <<ALLTRIM(STR(m.g_snippcnt,3))>>
  7081. \\<<REPLICATE(" ",35-LEN(ALLTRIM(STR(m.g_snippcnt,3))))>><<m.g_verti2>>
  7082. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7083. \*       <<m.g_corn3>><<REPLICATE(m.g_horiz,57)>><<m.g_corn4>>
  7084. \*
  7085.  
  7086. *
  7087. * COMMENTBLOCK - Generate a comment block.
  7088. *
  7089. *!*****************************************************************************
  7090. *!
  7091. *!      Procedure: COMMENTBLOCK
  7092. *!
  7093. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  7094. *!               : PUTPROCHEAD        (procedure in GENSCRN.PRG)
  7095. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  7096. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  7097. *!               : GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  7098. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  7099. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  7100. *!               : PLACEREAD          (procedure in GENSCRN.PRG)
  7101. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  7102. *!
  7103. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  7104. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  7105. *!
  7106. *!*****************************************************************************
  7107. PROCEDURE commentblock
  7108. PARAMETER m.dbalias, m.string
  7109. PRIVATE m.msg
  7110. IF !EMPTY(basename(m.dbalias))
  7111.    m.msg = basename(m.dbalias)+"/"+versioncap(g_genvers)+m.string
  7112. ELSE
  7113.    m.msg = versioncap(g_genvers)+m.string
  7114. ENDIF
  7115. \
  7116. \*       <<m.g_corn1>><<REPLICATE(m.g_horiz,57)>><<m.g_corn2>>
  7117. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7118. \*       <<m.g_verti1>>
  7119. \\ <<PADC(m.msg,55," ")>>
  7120. \\ <<m.g_verti2>>
  7121. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7122. \*       <<m.g_corn3>><<REPLICATE(m.g_horiz,57)>><<m.g_corn4>>
  7123. \*
  7124. \
  7125.  
  7126. *
  7127. * PROCCOMMENTBLOCK - Generate a procedure comment block.
  7128. *
  7129. *!*****************************************************************************
  7130. *!
  7131. *!      Procedure: PROCCOMMENTBLOCK
  7132. *!
  7133. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  7134. *!
  7135. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  7136. *!
  7137. *!*****************************************************************************
  7138. PROCEDURE proccommentblock
  7139. PARAMETER m.dbalias, m.string
  7140. PRIVATE m.msg
  7141. m.msg = basename(m.dbalias)+m.string
  7142. \
  7143. \*       <<m.g_corn1>><<REPLICATE(m.g_horiz,57)>><<m.g_corn2>>
  7144. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7145. \*       <<m.g_verti1>>
  7146. \\ <<PADC(m.msg,55," ")>>
  7147. \\ <<m.g_verti2>>
  7148. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7149. \*       <<m.g_corn3>><<REPLICATE(m.g_horiz,57)>><<m.g_corn4>>
  7150. \*
  7151. \
  7152.  
  7153. *
  7154. * GENCOMMENT - Generate a comment.
  7155. *
  7156. *!*****************************************************************************
  7157. *!
  7158. *!      Procedure: GENCOMMENT
  7159. *!
  7160. *!      Called by: GENVALIDBODY       (procedure in GENSCRN.PRG)
  7161. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7162. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7163. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7164. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7165. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  7166. *!
  7167. *!*****************************************************************************
  7168. PROCEDURE gencomment
  7169. PARAMETER m.msg
  7170. \*
  7171. \* <<m.msg>>
  7172. \*
  7173.  
  7174. **
  7175. ** General Supporting Routines
  7176. **
  7177.  
  7178. *
  7179. * BASENAME - returns strippath(stripext(filespec))
  7180. *
  7181. *!*****************************************************************************
  7182. *!
  7183. *!       Function: BASENAME
  7184. *!
  7185. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  7186. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  7187. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7188. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7189. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7190. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7191. *!               : GENRELSTMTS        (procedure in GENSCRN.PRG)
  7192. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  7193. *!               : PROCCOMMENTBLOCK   (procedure in GENSCRN.PRG)
  7194. *!
  7195. *!          Calls: STRIPPATH()        (function  in GENSCRN.PRG)
  7196. *!               : STRIPEXT()         (function  in GENSCRN.PRG)
  7197. *!
  7198. *!*****************************************************************************
  7199. FUNCTION basename
  7200. PARAMETER m.filename
  7201. RETURN strippath(stripext(m.filename))
  7202.  
  7203. *
  7204. * STRIPEXT - Strip the extension from a file name.
  7205. *
  7206. * Description:
  7207. * Use the algorithm employed by FoxPRO itself to strip a
  7208. * file of an extension (if any): Find the rightmost dot in
  7209. * the filename.  If this dot occurs to the right of a "\"
  7210. * or ":", then treat everything from the dot rightward
  7211. * as an extension.  Of course, if we found no dot,
  7212. * we just hand back the filename unchanged.
  7213. *
  7214. * Parameters:
  7215. * filename - character string representing a file name
  7216. *
  7217. * Return value:
  7218. * The string "filename" with any extension removed
  7219. *
  7220. *!*****************************************************************************
  7221. *!
  7222. *!       Function: STRIPEXT
  7223. *!
  7224. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  7225. *!               : BASENAME()         (function  in GENSCRN.PRG)
  7226. *!
  7227. *!*****************************************************************************
  7228. FUNCTION stripext
  7229. PARAMETER m.filename
  7230. PRIVATE m.dotpos, m.terminator
  7231. m.dotpos = RAT(".", m.filename)
  7232. m.terminator = MAX(RAT("\", m.filename), RAT(":", m.filename))
  7233. IF m.dotpos > m.terminator
  7234.    m.filename = LEFT(m.filename, m.dotpos-1)
  7235. ENDIF
  7236. RETURN m.filename
  7237.  
  7238. *
  7239. * STRIPPATH - Strip the path from a file name.
  7240. *
  7241. * Description:
  7242. * Find positions of backslash in the name of the file.  If there is one
  7243. * take everything to the right of its position and make it the new file
  7244. * name.  If there is no slash look for colon.  Again if found, take
  7245. * everything to the right of it as the new name.  If neither slash
  7246. * nor colon are found then return the name unchanged.
  7247. *
  7248. * Parameters:
  7249. * filename - character string representing a file name
  7250. *
  7251. * Return value:
  7252. * The string "filename" with any path removed
  7253. *
  7254. *!*****************************************************************************
  7255. *!
  7256. *!       Function: STRIPPATH
  7257. *!
  7258. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  7259. *!               : BASENAME()         (function  in GENSCRN.PRG)
  7260. *!
  7261. *!*****************************************************************************
  7262. FUNCTION strippath
  7263. PARAMETER m.filename
  7264. PRIVATE m.slashpos, m.namelen, m.colonpos
  7265. m.slashpos = RAT("\", m.filename)
  7266. IF m.slashpos > 0
  7267.    m.namelen  = LEN(m.filename) - m.slashpos
  7268.    m.filename = RIGHT(m.filename, m.namelen)
  7269. ELSE
  7270.    m.colonpos = RAT(":", m.filename)
  7271.    IF m.colonpos > 0
  7272.       m.namelen  = LEN(m.filename) - m.colonpos
  7273.       m.filename = RIGHT(m.filename, m.namelen)
  7274.    ENDIF
  7275. ENDIF
  7276. RETURN m.filename
  7277.  
  7278. *
  7279. * STRIPCR - Strip off terminating carriage returns and line feeds
  7280. *
  7281. *!*****************************************************************************
  7282. *!
  7283. *!       Function: STRIPCR
  7284. *!
  7285. *!*****************************************************************************
  7286. FUNCTION stripcr
  7287. PARAMETER m.strg
  7288. * Don't use a CHRTRAN since it's remotely possible that the CR or LF might
  7289. * be in a user's quoted string.
  7290. strg = ALLTRIM(strg)
  7291. i = LEN(strg)
  7292. DO WHILE i >= 0 AND INLIST(SUBSTR(strg,i,1),CHR(13),CHR(10))
  7293.    i = i - 1
  7294. ENDDO
  7295. RETURN LEFT(strg,i)
  7296.  
  7297. *
  7298. * ADDBS - Add a backslash unless there is one already there.
  7299. *
  7300. *!*****************************************************************************
  7301. *!
  7302. *!       Function: ADDBS
  7303. *!
  7304. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7305. *!
  7306. *!*****************************************************************************
  7307. FUNCTION addbs
  7308. * Add a backslash to a path name, if there isn't already one there
  7309. PARAMETER m.pathname
  7310. PRIVATE ALL
  7311. m.pathname = ALLTRIM(UPPER(m.pathname))
  7312. IF !(RIGHT(m.pathname,1) $ '\:') AND !EMPTY(m.pathname)
  7313.    m.pathname = m.pathname + '\'
  7314. ENDIF
  7315. RETURN m.pathname
  7316.  
  7317. *
  7318. * JUSTFNAME - Return just the filename (i.e., no path) from "filname"
  7319. *
  7320. *!*****************************************************************************
  7321. *!
  7322. *!       Function: JUSTFNAME
  7323. *!
  7324. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7325. *!
  7326. *!*****************************************************************************
  7327. FUNCTION justfname
  7328. PARAMETERS m.filname
  7329. PRIVATE ALL
  7330. IF RAT('\',m.filname) > 0
  7331.    m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
  7332. ENDIF
  7333. IF AT(':',m.filname) > 0
  7334.    m.filname = SUBSTR(m.filname,AT(':',m.filname)+1,255)
  7335. ENDIF
  7336. RETURN ALLTRIM(UPPER(m.filname))
  7337.  
  7338. *
  7339. * JUSTPATH - Returns just the pathname.
  7340. *
  7341. *!*****************************************************************************
  7342. *!
  7343. *!       Function: JUSTPATH
  7344. *!
  7345. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7346. *!
  7347. *!*****************************************************************************
  7348. FUNCTION justpath
  7349. * Return just the path name from "filname"
  7350. PARAMETERS m.filname
  7351. PRIVATE ALL
  7352. m.filname = ALLTRIM(UPPER(m.filname))
  7353. IF '\' $ m.filname
  7354.    m.filname = SUBSTR(m.filname,1,RAT('\',m.filname))
  7355.    IF RIGHT(m.filname,1) = '\' AND LEN(m.filname) > 1 ;
  7356.          AND SUBSTR(m.filname,LEN(m.filname)-1,1) <> ':'
  7357.       m.filname = SUBSTR(m.filname,1,LEN(m.filname)-1)
  7358.    ENDIF
  7359.    RETURN m.filname
  7360. ELSE
  7361.    RETURN ''
  7362. ENDIF
  7363.  
  7364. *
  7365. * FORCEEXT - Force filename to have a paricular extension.
  7366. *
  7367. *!*****************************************************************************
  7368. *!
  7369. *!       Function: FORCEEXT
  7370. *!
  7371. *!          Calls: JUSTPATH()         (function  in GENSCRN.PRG)
  7372. *!               : JUSTFNAME()        (function  in GENSCRN.PRG)
  7373. *!               : ADDBS()            (function  in GENSCRN.PRG)
  7374. *!
  7375. *!*****************************************************************************
  7376. FUNCTION forceext
  7377. * Force the extension of "filname" to be whatever ext is.
  7378. PARAMETERS m.filname,m.ext
  7379. PRIVATE ALL
  7380. IF SUBSTR(m.ext,1,1) = "."
  7381.    m.ext = SUBSTR(m.ext,2,3)
  7382. ENDIF
  7383.  
  7384. m.pname = justpath(m.filname)
  7385. m.filname = justfname(UPPER(ALLTRIM(m.filname)))
  7386. IF AT('.',m.filname) > 0
  7387.    m.filname = SUBSTR(m.filname,1,AT('.',m.filname)-1) + '.' + m.ext
  7388. ELSE
  7389.    m.filname = m.filname + '.' + m.ext
  7390. ENDIF
  7391. RETURN addbs(m.pname) + m.filname
  7392.  
  7393. *
  7394. * WhatStyle - Return the style string which corresponds to the style
  7395. *                stored in screen database.
  7396. *
  7397. *!*****************************************************************************
  7398. *!
  7399. *!       Function: WHATSTYLE
  7400. *!
  7401. *!*****************************************************************************
  7402. FUNCTION whatstyle
  7403. PARAMETER m.stylenum
  7404. IF NOT EMPTY(m.stylenum)
  7405.    DO CASE
  7406.    CASE m.stylenum= 1
  7407.       RETURN "B"
  7408.    CASE m.stylenum= 2
  7409.       RETURN "I"
  7410.    OTHERWISE
  7411.       RETURN "BI"
  7412.    ENDCASE
  7413. ELSE
  7414.    RETURN ""
  7415. ENDIF
  7416.  
  7417. *
  7418. * UNIQUEWIN - Check if a window name is unique.
  7419. *
  7420. *!*****************************************************************************
  7421. *!
  7422. *!       Function: UNIQUEWIN
  7423. *!
  7424. *!      Called by: GENWINDEFI         (procedure in GENSCRN.PRG)
  7425. *!
  7426. *!*****************************************************************************
  7427. FUNCTION uniquewin
  7428. PARAMETER m.windowname, m.windcnt, m.arry
  7429. EXTERNAL ARRAY arry
  7430. PRIVATE m.found, m.i, m.first, m.middle
  7431. m.found  = .F.
  7432. m.first  = 1
  7433. m.last   = m.windcnt
  7434. m.middle = 0
  7435.  
  7436. IF EMPTY(arry[1,1])
  7437.    RETURN 1
  7438. ENDIF
  7439. DO WHILE (m.last >= m.first) AND NOT m.found
  7440.    m.middle = INT((m.first+m.last) / 2)
  7441.    DO CASE
  7442.    CASE m.windowname < arry[m.middle,1]
  7443.       m.last = m.middle - 1
  7444.    CASE m.windowname > arry[m.middle,1]
  7445.       m.first = m.middle + 1
  7446.    OTHERWISE
  7447.       m.found = .T.
  7448.    ENDCASE
  7449. ENDDO
  7450. IF m.found
  7451.    RETURN 0
  7452. ELSE
  7453.    RETURN m.first
  7454. ENDIF
  7455.  
  7456. *
  7457. * ADDTOCTRL - Generate clause code for object level cluses.
  7458. *
  7459. *!*****************************************************************************
  7460. *!
  7461. *!      Procedure: ADDTOCTRL
  7462. *!
  7463. *!      Called by: ELEMRANGE          (procedure in GENSCRN.PRG)
  7464. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  7465. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  7466. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  7467. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  7468. *!
  7469. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  7470. *!               : GENFUNCHEADER      (procedure in GENSCRN.PRG)
  7471. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  7472. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  7473. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  7474. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  7475. *!
  7476. *!*****************************************************************************
  7477. PROCEDURE addtoctrl
  7478. PARAMETER m.procname, m.from, m.memo, m.varname
  7479. PRIVATE m.linecnt, m.count, m.textline, m.genfunction, m.notcomnt, m.at, ;
  7480.    m.thispretext, m.in_dec, m.platnum, m.wnamelen, m.upline, m.thisplat
  7481.  
  7482. m.thisplat = IIF(TYPE("platform") <> "U",platform,"DOS")
  7483. m.platnum = getplatnum(m.thisplat)
  7484.  
  7485. * Write this clause to the temporary file
  7486. _TEXT = m.g_tmphandle
  7487. m.thispretext = _PRETEXT
  7488. _PRETEXT = ""
  7489.  
  7490. m.genfunction = .F.
  7491. m.notcomnt = 0
  7492. m.linecnt = MEMLINES(m.memo)
  7493. _MLINE = 0
  7494. DO genfuncheader WITH m.procname, m.from, .F., ALLTRIM(m.varname)
  7495. FOR m.count = 1 TO m.linecnt
  7496.    m.textline = MLINE(m.memo, 1, _MLINE)
  7497.    m.upline = UPPER(LTRIM(CHRTRAN(m.textline,chr(9),' ')))
  7498.    IF oktogenerate(m.textline, @notcomnt)
  7499.       IF m.notcomnt > 0 AND NOT m.genfunction
  7500.          \FUNCTION <<m.procname>>     &&  <<m.varname>> <<m.from>>
  7501.          in_dec = SET("DECIMALS")
  7502.          SET DECIMALS TO 0
  7503.          \#REGION <<INT(m.g_screen)>>
  7504.          SET DECIMALS TO in_dec
  7505.          m.genfunction = .T.
  7506.       ENDIF
  7507.  
  7508.       IF NOT EMPTY(g_wnames[m.g_screen, m.platnum])
  7509.          m.at = atwname(g_wnames[m.g_screen, m.platnum], m.textline)
  7510.          IF m.at <> 0 AND !iscomment(@textline)
  7511.             m.wnamelen = LEN(g_wnames[m.g_screen, m.platnum])
  7512.             \<<STUFF(m.textline, m.at, m.wnamelen,g_screens[m.g_screen,2])>>
  7513.             \<<m.textline>>
  7514.          ELSE
  7515.             IF !geninsertcode(@upline,m.g_screen, .F., m.thisplat)
  7516.                \<<m.textline>>
  7517.             ENDIF
  7518.          ENDIF
  7519.       ELSE
  7520.          IF !geninsertcode(@upline,m.g_screen, .F., m.thisplat)
  7521.             \<<m.textline>>
  7522.          ENDIF
  7523.       ENDIF
  7524.    ENDIF
  7525. ENDFOR
  7526. IF m.notcomnt = 0
  7527.    \FUNCTION <<m.procname>>     &&  <<m.varname>> <<m.from>>
  7528. ENDIF
  7529. _TEXT = m.g_orghandle
  7530. _PRETEXT = m.thispretext
  7531.  
  7532. *
  7533. * OKTOGENERATE - Ok to generate this line?
  7534. *
  7535. * Description:
  7536. * Check if the code segment provided by the user for the object level
  7537. * VALID, MESSAGE, and WHEN clauses does not contain 'FUNCTION',
  7538. * 'PROCEDURE' or 'PARAMETER' statements as its first non-comment
  7539. * statements.  Further, do not output #NAME directives. This is done on line by
  7540. * line basis.
  7541. *
  7542. *!*****************************************************************************
  7543. *!
  7544. *!       Function: OKTOGENERATE
  7545. *!
  7546. *!      Called by: ADDTOCTRL          (procedure in GENSCRN.PRG)
  7547. *!
  7548. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  7549. *!               : MATCH()            (function  in GENSCRN.PRG)
  7550. *!
  7551. *!*****************************************************************************
  7552. FUNCTION oktogenerate
  7553. PARAMETER m.text, m.notcomnt
  7554. * "notcomnt" needs to be passed by reference, and is changed in this module
  7555.  
  7556. PRIVATE m.asterisk, m.ampersand, m.isnote, m.name, m.statement, m.word1
  7557. IF EMPTY(m.text)
  7558.    RETURN .T.
  7559. ENDIF
  7560.  
  7561. m.statement = UPPER(LTRIM(m.text))
  7562.  
  7563. DO CASE
  7564. CASE AT("*", m.statement) = 1 ;
  7565.       OR AT(m.g_dblampersand, m.statement) = 1 ;
  7566.       OR AT("NOTE", m.statement) = 1
  7567.    RETURN .T.
  7568. OTHERWISE
  7569.    * OK, it's not a comment
  7570.    m.notcomnt = m.notcomnt + 1
  7571.    * Make a quick test to see if we may exclude this line
  7572.    IF AT(LEFT(statement,1),"PF#") > 0
  7573.       * Postpone the expensive wordnum and match functions as long as possible
  7574.       word1 = CHRTRAN(wordnum(statement,1),';','')
  7575.       DO CASE
  7576.       CASE match(word1,"PROCEDURE") OR match(word1,"FUNCTION") OR match(word1,"PARAMETERS")
  7577.          *
  7578.          * If the first non-comment line is a FUNCTION, PROCEDURE, or
  7579.          * a PARAMETER statement then do not generate it.
  7580.          *
  7581.          IF m.notcomnt = 1
  7582.             RETURN .F.
  7583.          ENDIF
  7584.       CASE LEFT(statement,5) == "#NAME"   && Don't ever emit a #NAME directive
  7585.          RETURN .F.
  7586.       ENDCASE
  7587.    ENDIF
  7588. ENDCASE
  7589. RETURN .T.
  7590.  
  7591. *
  7592. * OBJECT - Return name of an object.
  7593. *
  7594. *!*****************************************************************************
  7595. *!
  7596. *!       Function: OBJECT
  7597. *!
  7598. *!*****************************************************************************
  7599. FUNCTION OBJECT
  7600. PARAMETER m.objecttype
  7601. PRIVATE m.objname
  7602. DO CASE
  7603. CASE m.objecttype = 11
  7604.    m.objname = "List"
  7605. CASE m.objecttype = 12
  7606.    m.objname = "Push Button"
  7607. CASE m.objecttype = 13
  7608.    m.objname = "Radio Button"
  7609. CASE m.objecttype = 14
  7610.    m.objname = "Check Box"
  7611. CASE m.objecttype = 15
  7612.    m.objname = "Field"
  7613. CASE m.objecttype = 16
  7614.    m.objname = "Popup"
  7615. OTHERWISE
  7616.    m.objname = ""
  7617. ENDCASE
  7618. RETURN m.objname
  7619.  
  7620. *
  7621. * COMBINE - Combine the original and the temp files.
  7622. *
  7623. *!*****************************************************************************
  7624. *!
  7625. *!      Procedure: COMBINE
  7626. *!
  7627. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7628. *!
  7629. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  7630. *!
  7631. *!*****************************************************************************
  7632. PROCEDURE combine
  7633. PRIVATE m.size, m.top, m.end, m.status, m.chunk
  7634.  
  7635. IF m.g_graphic
  7636.    SET MESSAGE TO 'Merging Files'
  7637. ENDIF
  7638. m.size = FSEEK(m.g_tmphandle,0,2)
  7639. m.top  = FSEEK(m.g_tmphandle,0)
  7640.  
  7641. DO WHILE .T.
  7642.    m.chunk = IIF(m.size>65000, 65000, m.size)
  7643.    m.end   = FSEEK(m.g_orghandle,0,2)
  7644.    m.status = FWRITE(m.g_orghandle,FREAD(m.g_tmphandle,m.chunk))
  7645.    IF m.status = 0 AND m.size > 0
  7646.       DO errorhandler WITH "Unsuccessful file merge...",;
  7647.          LINENO(), c_error_2
  7648.    ENDIF
  7649.    m.size = m.size - 65000
  7650.    IF m.size < 0
  7651.       EXIT
  7652.    ENDIF
  7653. ENDDO
  7654. IF m.g_graphic
  7655.    SET MESSAGE TO 'Generation Complete'
  7656. ELSE
  7657.    WAIT CLEAR
  7658. ENDIF
  7659. RETURN
  7660.  
  7661. **
  7662. ** Code Associated With Displaying of the Thermometer
  7663. **
  7664.  
  7665. *
  7666. * ACTTHERM(<text>) - Activate thermometer.
  7667. *
  7668. * Activates thermometer.  Update the thermometer with UPDTHERM().
  7669. * Thermometer window is named "thermometer."  Be sure to RELEASE
  7670. * this window when done with thermometer.  Creates the global
  7671. * m.g_thermwidth.
  7672. *
  7673. *!*****************************************************************************
  7674. *!
  7675. *!      Procedure: ACTTHERM
  7676. *!
  7677. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7678. *!
  7679. *!*****************************************************************************
  7680. PROCEDURE acttherm
  7681. PARAMETER m.text
  7682. PRIVATE m.prompt
  7683.  
  7684. IF m.g_graphic
  7685.    m.prompt = LOWER(m.g_outfile)
  7686.    IF TXTWIDTH(m.prompt, c_dlgface, c_dlgsize, c_dlgstyle) > 43
  7687.       DO WHILE TXTWIDTH(m.prompt+"...", c_dlgface, c_dlgsize, c_dlgstyle) > 43
  7688.          m.prompt = LEFT(m.prompt, LEN(m.prompt)-1)
  7689.       ENDDO
  7690.       m.prompt = m.prompt + "..."
  7691.    ENDIF
  7692.  
  7693.    DEFINE WINDOW thermomete ;
  7694.       AT  INT((SROW() - (( 5.615 * ;
  7695.       FONTMETRIC(1, c_dlgface, c_dlgsize, c_dlgstyle )) / ;
  7696.       FONTMETRIC(1, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2), ;
  7697.       INT((SCOL() - (( 63.833 * ;
  7698.       FONTMETRIC(6, c_dlgface, c_dlgsize, c_dlgstyle )) / ;
  7699.       FONTMETRIC(6, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2) ;
  7700.       SIZE 5.615,63.833 ;
  7701.       FONT c_dlgface, c_dlgsize ;
  7702.       STYLE c_dlgstyle ;
  7703.       NOFLOAT ;
  7704.       NOCLOSE ;
  7705.       NONE ;
  7706.       COLOR RGB(0, 0, 0, 192, 192, 192)
  7707.    MOVE WINDOW thermomete CENTER
  7708.    ACTIVATE WINDOW thermomete NOSHOW
  7709.  
  7710.    @ 0.5,3 SAY m.text FONT c_dlgface, c_dlgsize STYLE c_dlgstyle
  7711.    @ 1.5,3 SAY m.prompt FONT c_dlgface, c_dlgsize STYLE c_dlgstyle
  7712.    @ 0.000,0.000 TO 0.000,63.833 ;
  7713.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7714.    @ 0.000,0.000 TO 5.615,0.000 ;
  7715.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7716.    @ 0.385,0.667 TO 5.231,0.667 ;
  7717.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7718.    @ 0.308,0.667 TO 0.308,63.167 ;
  7719.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7720.    @ 0.385,63.000 TO 5.308,63.000 ;
  7721.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7722.    @ 5.231,0.667 TO 5.231,63.167 ;
  7723.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7724.    @ 5.538,0.000 TO 5.538,63.833 ;
  7725.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7726.    @ 0.000,63.667 TO 5.615,63.667 ;
  7727.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7728.    @ 3.000,3.333 TO 4.231,3.333 ;
  7729.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7730.    @ 3.000,60.333 TO 4.308,60.333 ;
  7731.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7732.    @ 3.000,3.333 TO 3.000,60.333 ;
  7733.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7734.    @ 4.231,3.333 TO 4.231,60.500 ;
  7735.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7736.    m.g_thermwidth = 56.269
  7737.  
  7738.    SHOW WINDOW thermomete TOP
  7739. ELSE
  7740.    m.prompt = SUBSTR(SYS(2014,m.g_outfile),1,48)+;
  7741.       IIF(LEN(m.g_outfile)>48,"...","")
  7742.  
  7743.    DEFINE WINDOW thermomete;
  7744.       FROM INT((SROW()-6)/2), INT((SCOL()-57)/2) ;
  7745.       TO INT((SROW()-6)/2) + 6, INT((SCOL()-57)/2) + 57;
  7746.       DOUBLE COLOR SCHEME 5
  7747.    ACTIVATE WINDOW thermomete NOSHOW
  7748.  
  7749.    m.g_thermwidth = 50
  7750.    @ 0,3 SAY m.text
  7751.    @ 1,3 SAY UPPER(m.prompt)
  7752.    @ 2,1 TO 4,m.g_thermwidth+4 &g_boxstrg
  7753.  
  7754.    SHOW WINDOW thermomete TOP
  7755. ENDIF
  7756. RETURN
  7757.  
  7758. *
  7759. * UPDTHERM(<percent>) - Update thermometer.
  7760. *
  7761. *!*****************************************************************************
  7762. *!
  7763. *!      Procedure: UPDTHERM
  7764. *!
  7765. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7766. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  7767. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  7768. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  7769. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  7770. *!
  7771. *!*****************************************************************************
  7772. PROCEDURE updtherm
  7773. PARAMETER m.percent
  7774. PRIVATE m.nblocks, m.percent
  7775.  
  7776. ACTIVATE WINDOW thermomete
  7777.  
  7778. * Map to the number of platforms we are generating for
  7779. m.percent = MIN(INT(m.percent / m.g_numplatforms) ,100)
  7780.  
  7781. m.nblocks = (m.percent/100) * (m.g_thermwidth)
  7782. IF m.g_graphic
  7783.    @ 3.000,3.333 TO 4.231,m.nblocks + 3.333 ;
  7784.       PATTERN 1 COLOR RGB(128, 128, 128, 128, 128, 128)
  7785. ELSE
  7786.    @ 3,3 SAY REPLICATE("█",m.nblocks)
  7787. ENDIF
  7788. RETURN
  7789.  
  7790. *
  7791. * DEACTTHERMO - Deactivate and Release thermometer window.
  7792. *
  7793. *!*****************************************************************************
  7794. *!
  7795. *!      Procedure: DEACTTHERMO
  7796. *!
  7797. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7798. *!
  7799. *!*****************************************************************************
  7800. PROCEDURE deactthermo
  7801. IF WEXIST("thermomete")
  7802.    RELEASE WINDOW thermomete
  7803. ENDIF
  7804. RETURN
  7805.  
  7806. **
  7807. ** Error Handling Code
  7808. **
  7809.  
  7810. *
  7811. * ERRORHANDLER - Error Processing Center.
  7812. *
  7813. *!*****************************************************************************
  7814. *!
  7815. *!      Procedure: ERRORHANDLER
  7816. *!
  7817. *!      Called by: GENSCRN.PRG
  7818. *!               : OPENPROJDBF()      (function  in GENSCRN.PRG)
  7819. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  7820. *!               : CHECKPARAM()       (function  in GENSCRN.PRG)
  7821. *!               : PREPFILE           (procedure in GENSCRN.PRG)
  7822. *!               : CLOSEFILE          (procedure in GENSCRN.PRG)
  7823. *!               : GETPLATFORM()      (function  in GENSCRN.PRG)
  7824. *!               : REFRESHPREFS       (procedure in GENSCRN.PRG)
  7825. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  7826. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  7827. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  7828. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7829. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7830. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7831. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7832. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  7833. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  7834. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  7835. *!               : COMBINE            (procedure in GENSCRN.PRG)
  7836. *!
  7837. *!          Calls: CLEANUP            (procedure in GENSCRN.PRG)
  7838. *!               : ERRLOG             (procedure in GENSCRN.PRG)
  7839. *!               : ERRSHOW            (procedure in GENSCRN.PRG)
  7840. *!               : CLOSEFILE          (procedure in GENSCRN.PRG)
  7841. *!
  7842. *!*****************************************************************************
  7843. PROCEDURE errorhandler
  7844. PARAMETERS m.msg, m.linenum, m.errcode
  7845. IF ERROR() = 22   && too many memory variables--just bomb out as fast as we can
  7846.    ON ERROR
  7847.    DO cleanup
  7848.    CANCEL
  7849. ENDIF
  7850.  
  7851. DO CASE
  7852. CASE errcode == "Minor"
  7853.    DO errlog WITH m.msg, m.linenum
  7854.    m.g_status = 1
  7855. CASE errcode == "Serious"
  7856.    DO errlog  WITH m.msg, m.linenum
  7857.    DO errshow WITH m.msg, m.linenum
  7858.    m.g_status = 2
  7859.    ON ERROR
  7860. CASE errcode == "Fatal"
  7861.    ON ERROR
  7862.    IF m.g_havehand = .T.
  7863.       DO errlog WITH m.msg, m.linenum
  7864.       DO closefile WITH m.g_orghandle
  7865.       DO closefile WITH m.g_tmphandle
  7866.    ENDIF
  7867.    DO errshow WITH m.msg, m.linenum
  7868.    IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  7869.       RELEASE WINDOW thermometer
  7870.    ENDIF
  7871.    DO cleanup
  7872.    CANCEL
  7873. ENDCASE
  7874.  
  7875. *
  7876. * ESCHANDLER - Escape handler.
  7877. *
  7878. *!*****************************************************************************
  7879. *!
  7880. *!      Procedure: ESCHANDLER
  7881. *!
  7882. *!      Called by: BUILDENABLE        (procedure in GENSCRN.PRG)
  7883. *!
  7884. *!          Calls: BUILDDISABLE       (procedure in GENSCRN.PRG)
  7885. *!               : CLEANUP            (procedure in GENSCRN.PRG)
  7886. *!
  7887. *!*****************************************************************************
  7888. PROCEDURE eschandler
  7889. ON ERROR
  7890. WAIT WINDOW "Generation process stopped." NOWAIT
  7891. DO builddisable
  7892. IF m.g_havehand
  7893.    ERASE (m.g_outfile)
  7894.    ERASE (m.g_tmpfile)
  7895. ENDIF
  7896. IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  7897.    RELEASE WINDOW thermometer
  7898. ENDIF
  7899. DO cleanup
  7900. CANCEL
  7901.  
  7902. *
  7903. * ERRLOG - Save an error message in the error log file.
  7904. *
  7905. *!*****************************************************************************
  7906. *!
  7907. *!      Procedure: ERRLOG
  7908. *!
  7909. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  7910. *!
  7911. *!          Calls: OPENERRFILE        (procedure in GENSCRN.PRG)
  7912. *!
  7913. *!*****************************************************************************
  7914. PROCEDURE errlog
  7915. PARAMETER m.msg, m.linenum
  7916. DO openerrfile
  7917.  
  7918. SET CONSOLE OFF
  7919. \\GENERATOR: <<ALLTRIM(m.msg)>>
  7920. IF NOT EMPTY(m.linenum)
  7921.    \\ LINE NUMBER: <<m.linenum>>
  7922. ENDIF
  7923. \
  7924. = FCLOSE(_TEXT)
  7925. _TEXT = m.g_orghandle
  7926.  
  7927. *
  7928. * ERRSHOW - Show error in an alert box on the screen.
  7929. *
  7930. *!*****************************************************************************
  7931. *!
  7932. *!      Procedure: ERRSHOW
  7933. *!
  7934. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  7935. *!               : OPENERRFILE        (procedure in GENSCRN.PRG)
  7936. *!
  7937. *!*****************************************************************************
  7938. PROCEDURE errshow
  7939. PARAMETER m.msg, m.lineno
  7940. PRIVATE m.curcursor
  7941.  
  7942. IF m.g_graphic
  7943.    DEFINE WINDOW ALERT ;
  7944.       AT  INT((SROW() - (( 6.615 * ;
  7945.       FONTMETRIC(1, c_dlgface, c_dlgsize, c_dlgstyle )) / ;
  7946.       FONTMETRIC(1, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2), ;
  7947.       INT((SCOL() - (( 63.833 * ;
  7948.       FONTMETRIC(6, c_dlgface, c_dlgsize, c_dlgstyle )) / ;
  7949.       FONTMETRIC(6, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2) ;
  7950.       SIZE 6.615,63.833 ;
  7951.       FONT c_dlgface, c_dlgsize ;
  7952.       STYLE c_dlgstyle ;
  7953.       NOCLOSE ;
  7954.       DOUBLE ;
  7955.       TITLE "Genscrn Error" ;
  7956.       COLOR RGB(0, 0, 0, 255, 255, 255)
  7957.    MOVE WINDOW ALERT CENTER
  7958.    ACTIVATE WINDOW ALERT NOSHOW
  7959.  
  7960.    m.dispmsg = m.msg
  7961.    IF TXTWIDTH(m.dispmsg) > WCOLS()
  7962.       * Make sure it isn't too long.
  7963.       DO WHILE TXTWIDTH(m.dispmsg+'...') > WCOLS()
  7964.          m.dispmsg = LEFT(m.dispmsg,LEN(m.dispmsg)-1)
  7965.       ENDDO
  7966.       IF m.msg <> m.dispmsg    && Has display message been shortened?
  7967.          m.dispmsg = m.dispmsg + '...'
  7968.       ENDIF
  7969.    ENDIF
  7970.  
  7971.    @ 1,MAX((WCOLS()-TXTWIDTH( m.dispmsg ))/2,1) SAY m.dispmsg
  7972.  
  7973.    m.msg = "Genscrn Line Number: "+STR(m.lineno, 4)
  7974.    @ 2,(WCOLS()-TXTWIDTH( m.msg ))/2 SAY m.msg
  7975.  
  7976.    IF TYPE("m.g_screen") <> "U" AND m.g_screen <> 0
  7977.       m.msg = "Generating from: "+LOWER(g_screens[m.g_screen,1])
  7978.       @ 3,MAX((WCOLS()-TXTWIDTH( m.msg ))/2,1) SAY m.msg
  7979.    ENDIF
  7980.  
  7981.    m.msg = "Press any key to cleanup and exit..."
  7982.    @ 4,(WCOLS()-TXTWIDTH( m.msg ))/2 SAY m.msg
  7983.  
  7984.    SHOW WINDOW ALERT
  7985. ELSE
  7986.    DEFINE WINDOW ALERT;
  7987.       FROM INT((SROW()-7)/2), INT((SCOL()-50)/2) TO INT((SROW()-7)/2) + 6, INT((SCOL()-50)/2) + 50 ;
  7988.       FLOAT NOGROW NOCLOSE NOZOOM SHADOW DOUBLE;
  7989.       COLOR SCHEME 7
  7990.  
  7991.    ACTIVATE WINDOW ALERT
  7992.  
  7993.    @ 0,0 CLEAR
  7994.    @ 1,0 SAY PADC(SUBSTR(m.msg,1,44)+;
  7995.       IIF(LEN(m.msg)>44,"...",""), WCOLS())
  7996.    @ 2,0 SAY PADC("Line Number: "+STR(m.lineno, 4), WCOLS())
  7997.  
  7998.    IF TYPE("m.g_screen") <> "U" AND m.g_screen <> 0
  7999.       m.msg = "Working on screen: "+LOWER(g_screens[m.g_screen])
  8000.       @ 3,0 SAY PADC(m.msg,WCOLS())
  8001.    ENDIF
  8002.  
  8003.    @ 4,0 SAY PADC("Press any key to cleanup and exit...", WCOLS())
  8004. ENDIF
  8005.  
  8006. m.curcursor = SET( "CURSOR" )
  8007. SET CURSOR OFF
  8008.  
  8009. WAIT ""
  8010.  
  8011. RELEASE WINDOW ALERT
  8012. SET CURSOR &curcursor
  8013.  
  8014. RELEASE WINDOW ALERT
  8015.  
  8016. *
  8017. * OPENERRFILE - Open error file.
  8018. *
  8019. *!*****************************************************************************
  8020. *!
  8021. *!      Procedure: OPENERRFILE
  8022. *!
  8023. *!      Called by: ERRLOG             (procedure in GENSCRN.PRG)
  8024. *!
  8025. *!          Calls: ERRSHOW            (procedure in GENSCRN.PRG)
  8026. *!
  8027. *!*****************************************************************************
  8028. PROCEDURE openerrfile
  8029. PRIVATE m.errfile, m.errhandle
  8030. m.errfile   = m.g_errlog+".ERR"
  8031. m.errhandle = FOPEN(m.errfile,2)
  8032. IF m.errhandle < 0
  8033.    m.errhandle = FCREATE(m.errfile)
  8034.    IF m.errhandle < 0
  8035.       DO errshow WITH ".ERR could not be opened...", LINENO()
  8036.       m.g_status = 2
  8037.       IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  8038.          RELEASE WINDOW thermometer
  8039.       ENDIF
  8040.       ON ERROR
  8041.       RETURN TO MASTER
  8042.    ENDIF
  8043. ELSE
  8044.    = FSEEK(m.errhandle,0,2)
  8045. ENDIF
  8046. IF SET("TEXTMERGE") = "OFF"
  8047.    SET TEXTMERGE ON
  8048. ENDIF
  8049. _TEXT = m.errhandle
  8050.  
  8051. *
  8052. * PUSHINDENT - Add another indentation level
  8053. *
  8054. *!*****************************************************************************
  8055. *!
  8056. *!      Procedure: PUSHINDENT
  8057. *!
  8058. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8059. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  8060. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  8061. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  8062. *!
  8063. *!*****************************************************************************
  8064. PROCEDURE pushindent
  8065. _PRETEXT = CHR(9) + _PRETEXT
  8066.  
  8067. *
  8068. * POPINDENT - Remove one indentation level
  8069. *
  8070. *!*****************************************************************************
  8071. *!
  8072. *!      Procedure: POPINDENT
  8073. *!
  8074. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8075. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  8076. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  8077. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  8078. *!
  8079. *!*****************************************************************************
  8080. PROCEDURE popindent
  8081. IF LEFT(_PRETEXT,1) = CHR(9)
  8082.    _PRETEXT = SUBSTR(_PRETEXT,2)
  8083. ENDIF
  8084.  
  8085. *
  8086. * COUNTPLATFORMS - Count the number of platforms in this SCX that are in common across
  8087. *                    all the SCXs in this screen set.
  8088. *
  8089. *!*****************************************************************************
  8090. *!
  8091. *!      Procedure: COUNTPLATFORMS
  8092. *!
  8093. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8094. *!
  8095. *!*****************************************************************************
  8096. PROCEDURE countplatforms
  8097. PRIVATE m.cnt, m.i
  8098. IF TYPE("g_platforms") <> "U"
  8099.    m.cnt = 0
  8100.    FOR m.i = 1 TO ALEN(g_platforms)
  8101.       IF !EMPTY(g_platforms[m.i])
  8102.          m.cnt = m.cnt + 1
  8103.       ENDIF
  8104.    ENDFOR
  8105.    RETURN m.cnt
  8106. ELSE
  8107.    RETURN 0
  8108. ENDIF
  8109.  
  8110. *
  8111. * LOOKUPPLATFORM - Return the n-th platform name
  8112. *
  8113. *!*****************************************************************************
  8114. *!
  8115. *!      Procedure: LOOKUPPLATFORM
  8116. *!
  8117. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8118. *!
  8119. *!*****************************************************************************
  8120. PROCEDURE lookupplatform
  8121. PARAMETER m.n
  8122. IF TYPE("g_platforms") <> "U" AND ALEN(g_platforms) >= m.n ;
  8123.       AND m.n > 0 AND TYPE("g_platforms[m.n]") = "C"
  8124.    RETURN UPPER(g_platforms[m.n])
  8125. ENDIF
  8126. RETURN ""
  8127.  
  8128. *
  8129. * GETPARAM - Return the PARAMETER statement from a setup snippet, if one is there
  8130. *
  8131. *!*****************************************************************************
  8132. *!
  8133. *!       Function: GETPARAM
  8134. *!
  8135. *!      Called by: CHECKPARAM()       (function  in GENSCRN.PRG)
  8136. *!
  8137. *!          Calls: ISCOMMENT()        (function  in GENSCRN.PRG)
  8138. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  8139. *!               : MATCH()            (function  in GENSCRN.PRG)
  8140. *!
  8141. *!*****************************************************************************
  8142. FUNCTION getparam
  8143. PARAMETER m.snipname
  8144. PRIVATE m.i, m.thisparam, m.numlines, m.thisline, m.word1
  8145.  
  8146. * Do a quick check to see if we need to search further.
  8147. IF ATC("PARA",&snipname) = 0
  8148.    RETURN ""
  8149. ENDIF
  8150.  
  8151. m.numlines = MEMLINES(&snipname)
  8152. _MLINE = 0
  8153. m.i = 1
  8154. DO WHILE m.i <= m.numlines
  8155.    m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  8156.    
  8157.    * Drop any double-ampersand comment
  8158.    IF AT(m.g_dblampersand,m.thisline) > 0
  8159.       m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  8160.    ENDIF
  8161.    
  8162.    IF !EMPTY(m.thisline) AND !iscomment(@thisline)
  8163.       * See if the first non-blank, non-comment, non-directive, non-EXTERNAL
  8164.       * line is a #SECTION 1
  8165.       DO CASE
  8166.       CASE LEFT(m.thisline,5) = "#SECT" AND AT('1',m.thisline) <> 0
  8167.          * Read until we find a #SECTION 2, the end of the snippet or a
  8168.          * PARAMETER statement.
  8169.          DO WHILE m.i <= m.numlines
  8170.             m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  8171.             
  8172.             * Drop any double-ampersand comment
  8173.             IF AT(m.g_dblampersand,m.thisline) > 0
  8174.                m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  8175.             ENDIF
  8176.             
  8177.             m.word1 = CHRTRAN(wordnum(m.thisline,1),';','')
  8178.             DO CASE
  8179.             CASE match(m.word1,"PARAMETERS")
  8180.             
  8181.                * Replace tabs with spaces
  8182.                m.thisline = CHRTRAN(m.thisline,CHR(9)," ")
  8183.  
  8184.                * Process continuation lines.  Replace tabs in incoming lines with spaces.
  8185.                DO WHILE RIGHT(RTRIM(m.thisline),1) = ';'
  8186.                   m.thisline = m.thisline + ' '+ CHR(13)+CHR(10)+CHR(9);
  8187.                      +CHRTRAN(UPPER(LTRIM(MLINE(&snipname, 1, _MLINE))),CHR(9)," ")
  8188.                ENDDO
  8189.                
  8190.                * Clean up the parameters so that minor differences in
  8191.                * spacing don't cause the comparisons to fail.
  8192.  
  8193.                * Take the parameters but not the PARAMETER keyword itself
  8194.                m.thisparam = SUBSTR(m.thisline,AT(' ',m.thisline)+1)
  8195.                DO WHILE INLIST(LEFT(m.thisparam,1),CHR(10),CHR(13),CHR(9),' ')
  8196.                   m.thisparam = SUBSTR(m.thisparam,2)
  8197.                ENDDO
  8198.  
  8199.                * Force single spacing in the param string
  8200.                DO WHILE AT('  ',m.thisparam) > 0
  8201.                   m.thisparam = STRTRAN(m.thisparam,'  ',' ')
  8202.                ENDDO
  8203.  
  8204.                * Drop "m." designations so that they don't make the variables look different
  8205.                m.thisparam = STRTRAN(m.thisparam,'m.','')
  8206.                m.thisparam = STRTRAN(m.thisparam,'m->','')
  8207.  
  8208.                RETURN LOWER(m.thisparam)
  8209.             CASE LEFT(m.thisline,5) = "#SECT" AND AT('2',m.thisline) <> 0
  8210.                * No parameter statement, since we found #SECTION 2 first
  8211.                RETURN ""
  8212.             ENDCASE
  8213.             m.i = m.i + 1
  8214.          ENDDO
  8215.       CASE LEFT(m.thisline,1) = "#"   && some other directive
  8216.          * Do nothing.  Get next line.
  8217.       CASE match(wordnum(m.thisline,1),"EXTERNAL")
  8218.          * Ignore it.  This doesn't disqualify a later statement from being a PARAMETER
  8219.          * statement.
  8220.       OTHERWISE
  8221.          * no #SECTION 1, so no parameters
  8222.          RETURN ""
  8223.       ENDCASE
  8224.    ENDIF
  8225.    m.i = m.i + 1
  8226. ENDDO
  8227. RETURN ""
  8228.  
  8229.  
  8230. *
  8231. * MATCH - Returns TRUE is candidate is a valid 4-or-more-character abbreviation of keyword
  8232. *
  8233. *!*****************************************************************************
  8234. *!
  8235. *!       Function: MATCH
  8236. *!
  8237. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8238. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  8239. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  8240. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  8241. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8242. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  8243. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  8244. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  8245. *!
  8246. *!*****************************************************************************
  8247. FUNCTION match
  8248. PARAMETER m.candidate, m.keyword
  8249. PRIVATE in_exact
  8250. m.in_exact = SET("EXACT")
  8251. SET EXACT OFF
  8252. DO CASE
  8253. CASE EMPTY(m.candidate)
  8254.    RETURN EMPTY(m.keyword)
  8255. CASE LEN(m.candidate) < 4
  8256.    RETURN m.candidate == m.keyword
  8257. OTHERWISE
  8258.    RETURN m.keyword = m.candidate
  8259. ENDCASE
  8260. IF m.in_exact != "OFF"
  8261.    SET EXACT ON
  8262. ENDIF
  8263.  
  8264. *
  8265. * WORDNUM - Returns w_num-th word from string strg
  8266. *
  8267. *!*****************************************************************************
  8268. *!
  8269. *!       Function: WORDNUM
  8270. *!
  8271. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8272. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  8273. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  8274. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  8275. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8276. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  8277. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  8278. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  8279. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  8280. *!
  8281. *!*****************************************************************************
  8282. FUNCTION wordnum
  8283. PARAMETERS m.strg,m.w_num
  8284. PRIVATE strg,s1,w_num,ret_str
  8285.  
  8286. m.s1 = ALLTRIM(m.strg)
  8287.  
  8288. * Replace tabs with spaces
  8289. m.s1 = CHRTRAN(m.s1,CHR(9)," ")
  8290.  
  8291. * Reduce multiple spaces to a single space
  8292. DO WHILE AT('  ',m.s1) > 0
  8293.    m.s1 = STRTRAN(m.s1,'  ',' ')
  8294. ENDDO
  8295.  
  8296. ret_str = ""
  8297. DO CASE
  8298. CASE m.w_num > 1
  8299.    DO CASE
  8300.    CASE AT(" ",m.s1,m.w_num-1) = 0   && No word w_num.  Past end of string.
  8301.       m.ret_str = ""
  8302.    CASE AT(" ",m.s1,m.w_num) = 0     && Word w_num is last word in string.
  8303.       m.ret_str = SUBSTR(m.s1,AT(" ",m.s1,m.w_num-1)+1,255)
  8304.    OTHERWISE                         && Word w_num is in the middle.
  8305.       m.strt_pos = AT(" ",m.s1,m.w_num-1)
  8306.       m.ret_str  = SUBSTR(m.s1,strt_pos,AT(" ",m.s1,m.w_num)+1 - strt_pos)
  8307.    ENDCASE
  8308. CASE m.w_num = 1
  8309.    IF AT(" ",m.s1) > 0               && Get first word.
  8310.       m.ret_str = SUBSTR(m.s1,1,AT(" ",m.s1)-1)
  8311.    ELSE                              && There is only one word.  Get it.
  8312.       m.ret_str = m.s1
  8313.    ENDIF
  8314. ENDCASE
  8315. RETURN ALLTRIM(m.ret_str)
  8316.  
  8317.  
  8318. * GETCNAME - Generates a name for a clause.  Will take name from a
  8319. *              generator directive stored in a snippet if present,
  8320. *              or generates a generic name otherwise.  The name is
  8321. *              designated by a #NAME name directive
  8322. *
  8323. *!*****************************************************************************
  8324. *!
  8325. *!       Function: GETCNAME
  8326. *!
  8327. *!      Called by: SETCLAUSEFLAGS     (procedure in GENSCRN.PRG)
  8328. *!               : ORCLAUSEFLAGS      (procedure in GENSCRN.PRG)
  8329. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  8330. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  8331. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  8332. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  8333. *!
  8334. *!*****************************************************************************
  8335. FUNCTION getcname
  8336. PARAMETERS m.snippet
  8337. PRIVATE dirname
  8338. IF ATC("#NAME",m.snippet) > 0
  8339.    m.dirname = MLINE(m.snippet, ATCLINE('#NAME',m.snippet))
  8340.    m.dirname = UPPER(ALLTRIM(SUBSTR(m.dirname,AT(' ',m.dirname)+1)))
  8341.    IF !EMPTY(m.dirname)
  8342.       RETURN m.dirname
  8343.    ENDIF
  8344. ENDIF
  8345. RETURN LOWER(SYS(2015))
  8346.  
  8347. *
  8348. * NOTEAREA - Note that we are using this area so that we can clean up at exit
  8349. *
  8350. *!*****************************************************************************
  8351. *!
  8352. *!      Procedure: NOTEAREA
  8353. *!
  8354. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  8355. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  8356. *!
  8357. *!*****************************************************************************
  8358. PROCEDURE notearea
  8359. g_areas[m.g_areacount] = SELECT()
  8360. m.g_areacount = m.g_areacount + 1
  8361. RETURN
  8362.  
  8363. *
  8364. * CLEARAREAS - Clear the ones we opened.
  8365. *
  8366. *!*****************************************************************************
  8367. *!
  8368. *!      Procedure: CLEARAREAS
  8369. *!
  8370. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  8371. *!
  8372. *!*****************************************************************************
  8373. PROCEDURE clearareas
  8374. FOR i = 1 TO m.g_areacount
  8375.    SELECT g_areas[m.i]
  8376.    USE
  8377. ENDFOR
  8378. RETURN
  8379.  
  8380.  
  8381. *
  8382. * INITTICK, TICK, and TOCK - Profiling functions
  8383. *
  8384. *!*****************************************************************************
  8385. *!
  8386. *!      Procedure: INITTICK
  8387. *!
  8388. *!      Called by: GENSCRN.PRG
  8389. *!
  8390. *!*****************************************************************************
  8391. PROCEDURE inittick
  8392. IF TYPE("ticktock") = "U"
  8393.    PUBLIC ticktock[10]
  8394. ENDIF
  8395. FOR i = 1 TO 10
  8396.    ticktock[i] = 0
  8397. ENDFOR
  8398.  
  8399. *!*****************************************************************************
  8400. *!
  8401. *!       Function: TICK
  8402. *!
  8403. *!      Called by: GENSCRN.PRG
  8404. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8405. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8406. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  8407. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  8408. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8409. *!
  8410. *!*****************************************************************************
  8411. FUNCTION tick
  8412. PARAMETER m.bucket
  8413. ticktock[bucket] = ticktock[bucket] - SECONDS()
  8414.  
  8415. *!*****************************************************************************
  8416. *!
  8417. *!       Function: TOCK
  8418. *!
  8419. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  8420. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8421. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8422. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  8423. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  8424. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8425. *!
  8426. *!*****************************************************************************
  8427. FUNCTION tock
  8428. PARAMETER m.bucket
  8429. ticktock[bucket] = ticktock[bucket] + SECONDS()
  8430.  
  8431. *
  8432. * Display a status message on the status bar at the bottom of the screen
  8433. *
  8434. *!*****************************************************************************
  8435. *!
  8436. *!      Procedure: PUTMSG
  8437. *!
  8438. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8439. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8440. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8441. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8442. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8443. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8444. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8445. *!
  8446. *!*****************************************************************************
  8447. PROCEDURE putmsg
  8448. PARAMETER m.msg
  8449. IF m.g_graphic
  8450.    SET MESSAGE TO msg
  8451. ENDIF
  8452.  
  8453. *
  8454. * VERSIONCAP - Return platform name suitable for display
  8455. *
  8456. *!*****************************************************************************
  8457. *!
  8458. *!       Function: VERSIONCAP
  8459. *!
  8460. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8461. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8462. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8463. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8464. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8465. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  8466. *!
  8467. *!*****************************************************************************
  8468. FUNCTION versioncap
  8469. PARAMETER m.strg
  8470. DO CASE
  8471. CASE strg = "DOS"
  8472.    RETURN "MS-DOS"
  8473. CASE strg = "WINDOWS"
  8474.    RETURN "Windows"
  8475. CASE strg = "MAC"
  8476.    RETURN "Macintosh"
  8477. CASE strg = "UNIX"
  8478.    RETURN "UNIX"
  8479. OTHERWISE
  8480.    RETURN strg
  8481. ENDCASE
  8482.  
  8483. *
  8484. * MULTIPLAT - Returns TRUE if we are generating for multiple platforms
  8485. *
  8486. *!*****************************************************************************
  8487. *!
  8488. *!       Function: MULTIPLAT
  8489. *!
  8490. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8491. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8492. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8493. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8494. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8495. *!
  8496. *!*****************************************************************************
  8497. FUNCTION multiplat
  8498. RETURN IIF(m.g_allplatforms AND m.g_numplatforms > 1, .T. , .F.)
  8499.  
  8500. *
  8501. * SEEKHEADER - Find the header for this screen/platform
  8502. *
  8503. *!*****************************************************************************
  8504. *!
  8505. *!      Procedure: SEEKHEADER
  8506. *!
  8507. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  8508. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8509. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8510. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8511. *!               : GENRELATIONS       (procedure in GENSCRN.PRG)
  8512. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8513. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  8514. *!
  8515. *!*****************************************************************************
  8516. PROCEDURE seekheader
  8517. PARAMETER m.i
  8518. IF g_screens[m.i,6]
  8519.    GO TOP
  8520. ELSE
  8521.    LOCATE FOR platform = g_screens[m.i,7] AND objtype = c_otscreen
  8522. ENDIF
  8523.  
  8524. *
  8525. * GETPLATNAME - Return the platform for a screen
  8526. *
  8527.  
  8528. *!*****************************************************************************
  8529. *!
  8530. *!       Function: GETPLATNAME
  8531. *!
  8532. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  8533. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8534. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8535. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8536. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  8537. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  8538. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  8539. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  8540. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  8541. *!
  8542. *!*****************************************************************************
  8543. FUNCTION getplatname
  8544. PARAMETER m.i
  8545. IF g_screens[m.i,6]
  8546.    RETURN "DOS"
  8547. ELSE
  8548.    RETURN platform
  8549. ENDIF
  8550.  
  8551.  
  8552. *!*****************************************************************************
  8553. *!
  8554. *!      Procedure: INSERTFILE
  8555. *!
  8556. *!      Called by: GENINSERTCODE      (procedure in GENSCRN.PRG)
  8557. *!
  8558. *!          Calls: WRITECODE          (procedure in GENSCRN.PRG)
  8559. *!
  8560. *!*****************************************************************************
  8561. PROCEDURE insertfile
  8562. PARAMETER m.incfn, m.scrnno, m.insetup, m.platname
  8563. PRIVATE m.oldals, m.insdbfname, m.oldmline, m.fptname
  8564.  
  8565. * Search for the file in the current directory, along the FoxPro path, and along
  8566. * the DOS path.
  8567. IF !FILE(m.incfn)
  8568.    DO CASE
  8569.    CASE FILE(FULLPATH(m.incfn))
  8570.       m.incfn = FULLPATH(m.incfn)
  8571.    CASE FILE(FULLPATH(m.incfn,1))
  8572.       m.incfn = FULLPATH(m.incfn,1)
  8573.    ENDCASE
  8574. ENDIF
  8575.  
  8576. IF FILE((m.incfn))
  8577.    m.oldals = ALIAS()
  8578.    m.insdbfname = SYS(3)+".DBF"
  8579.    m.oldmline = _MLINE
  8580.  
  8581.    * The following lines create a temporary file with a single memo field
  8582.    * and appends the inserted file into the memo field. Effectively creating
  8583.    * a code snippet. This allows the standard procedure for generating code
  8584.    * snippets to be call to process the inserted file. This in turn allows
  8585.    * the include file to contain generator directives.
  8586.    CREATE TABLE (m.insdbfname) (inscode m)
  8587.    APPEND BLANK
  8588.    APPEND MEMO inscode FROM (m.incfn)
  8589.  
  8590.    \** Start of inserted file <<m.incfn>> <<REPLICATE(m.g_horiz,32)+"start">>
  8591.  
  8592.    * Make a recursive call to the standard snippet generation procedure
  8593.    DO writecode WITH inscode, m.platname, 1, 0, m.scrnno, m.insetup
  8594.  
  8595.    \** End of inserted file <<m.incfn>> <<REPLICATE(m.g_horiz,36)+"end">>
  8596.    \
  8597.  
  8598.    USE
  8599.    DELETE FILE (m.insdbfname)
  8600.    m.fptname = forceext(m.insdbfname,"FPT")
  8601.    IF FILE(m.fptname)
  8602.       DELETE FILE (m.fptname)
  8603.    ENDIF
  8604.    
  8605.    SELECT (m.oldals)
  8606.    _MLINE=oldmline
  8607. ELSE
  8608.    \*
  8609.    \* Inserted file <<m.incfn>> not found!
  8610.    \*
  8611. ENDIF
  8612. RETURN
  8613.  
  8614. *: EOF: GENSCRN.PRG
  8615.