home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a087 / 4.ddi / FXAPCODE.PR_ / FXAPCODE.bin
Encoding:
Text File  |  1994-02-02  |  85.8 KB  |  2,801 lines

  1. * FoxApp 2.6 -- FoxPro 2.6 application generator
  2. * Author: Walter J. Kennamer
  3. * Copyright 1994, Microsoft Corporation
  4. * Modified by: John L. Alden, Alden Anderson
  5. * ------------------------------------------------------------------------
  6. * The following code was migrated here from the #SECTION 1 SETUP code in
  7. * the APPSCX screen. FxApCode.prg is now the Main file in the FoxApp 
  8. * project, rather than appscx.
  9.  
  10. PARAMETERS rscused, forceregen, fxapAppname
  11. PRIVATE ALL
  12.  
  13. * Parameter    Type     Description
  14. * ----------   ------   --------------------------------------------------
  15. * rscused      L        Determines whether the resource file
  16. *                          is checked for relations
  17. * forceregen   L or N   Determines whether FoxApp generates full or
  18. *                          abbreviated project files.  It can take these
  19. *                          values:
  20. *                          1 (or .T.)   Always generate full project
  21. *                          2 (or .F.)   Always generate abbreviated project
  22. *                          3            Check CONFIG.FP for instructions
  23. * fxapAppname  C        Memvar included when called from Catalog Manager. Name of
  24. *                        .app file is stored to this memvar before returning.
  25.  
  26. * Record the status of TALK and SAFETY
  27. IF SET('TALK') = 'ON'
  28.    SET TALK OFF
  29.    m.app_talk = 'ON'
  30. ELSE
  31.    m.app_talk = 'OFF'
  32. ENDIF
  33.  
  34. DO CASE
  35. CASE _WINDOWS
  36.     m.app_platform = "WINDOWS"
  37.     m.g_dfltfface = "MS Sans Serif"
  38.     m.g_dfltfsize = 8
  39.     m.g_dfltfstyle = "B"
  40. CASE _MAC
  41.     m.app_platform = "MAC"
  42.     m.g_dfltfface = "Geneva"
  43.     m.g_dfltfsize = 10
  44.     m.g_dfltfstyle = ""
  45. CASE _DOS
  46.     m.app_platform = "DOS"
  47.     m.g_dfltfface = "FoxFont"
  48.     m.g_dfltfsize = 10
  49.     m.g_dfltfstyle = ""
  50. OTHERWISE
  51. *    WAIT WINDOW "This version of FoxApp only runs on Windows or the Macintosh." NOWAIT
  52. *    RETURN
  53. ENDCASE
  54.  
  55. m.app_safe = SET("SAFETY")
  56. SET SAFETY OFF
  57. m.app_dele = SET("DELETED")
  58. SET DELETED ON
  59.  
  60. IF PARAMETERS() < 3
  61.    m.fxapAppname = ""     && memvar will acquire name of .app file
  62. ENDIF
  63. IF PARAMETERS() < 2
  64.    m.forceregen  = 3     && forces check of CONFIG.FP
  65. ENDIF
  66. IF PARAMETERS() < 1
  67.    m.rscused     = .T.   && store/restore relations from resource file?
  68. ENDIF
  69.  
  70. * Map the 'forceregen' variable into numeric form.
  71. IF TYPE('forceregen') = "L"
  72.    IF m.forceregen
  73.       m.forceregen = 1
  74.    ELSE
  75.       m.forceregen = 2
  76.    ENDIF
  77. ENDIF
  78.  
  79. m.appfile = ""        && this is the memvar that FoxApp uses to keep the 
  80.                     && name of the .app that is generated. When called
  81.                     && by the Catlaog Manager, this value needs to be 
  82.                     && assigned to the incoming parameter m.fxapAppname.
  83.  
  84. DO APPSCX.SPR
  85.  
  86. m.fxapAppname = alltrim(m.appfile)
  87. release appfile
  88.  
  89. return
  90.  
  91.  
  92. *------------------------------------------------------------------
  93. * Common procedure code for FoxApp, migrated here from the snippets
  94. * of the various screens.
  95. *------------------------------------------------------------------
  96.  
  97. *!*****************************************************************
  98. *!
  99. *!      Procedure: CLOSE_UP
  100. *!
  101. *!*****************************************************************
  102. PROCEDURE close_up
  103. * Do closing housekeeping for FoxApp.
  104.  
  105. SET TOPIC TO (mtopic)
  106.  
  107. RELEASE scxname, dbfname, invname, cdxname, repname, tmfname, ;
  108.    bailout, skipdbfbut, origname, dbflist, mnuname  && , appfile
  109. RELEASE origdbflist
  110.  
  111. CLOSE DATABASES
  112.  
  113. CLEAR WINDOW
  114.  
  115. * Restore the PUSH-ed system menu 
  116. POP MENU _msysmenu
  117.  
  118. POP KEY
  119.  
  120. CLEAR PROGRAM
  121. m.scrn_font   = WFONT(1,"")
  122. m.scrn_fsize  = WFONT(2,"")
  123. m.scrn_fstyle = WFONT(3,"")
  124. IF ! _DOS
  125.   MODIFY WINDOW SCREEN FONT m.scrn_font,m.scrn_fsize STYLE m.scrn_fstyle
  126. ENDIF
  127.  
  128. * Restore original ON ERROR & ON ESCAPE routines
  129. ON ERROR  &app_error
  130. ON ESCAPE &app_escape
  131. RELEASE app_error, app_escape
  132.  
  133. * Get rid of any vue files that might be hanging around
  134. IF FILE('qprview.vue')
  135.    DELETE FILE qprview.vue
  136. ENDIF
  137. IF FILE('appview.vue')
  138.    DELETE FILE appview.vue
  139. ENDIF
  140. IF FILE('dbfselec.vue')
  141.    DELETE FILE dbfselec.vue
  142. ENDIF
  143. IF FILE('foxapp.vue')
  144.    SET VIEW TO foxapp
  145.    DELETE FILE foxapp.vue
  146. ENDIF
  147.  
  148. IF m.app_talk = "ON"
  149.    SET TALK ON
  150. ENDIF
  151. IF m.app_dele = "OFF"
  152.    SET DELETED OFF
  153. ENDIF
  154. IF m.app_safe = "ON"
  155.    SET SAFETY ON
  156. ENDIF
  157.  
  158. RELEASE app_talk, app_safe, app_dele, dbflist
  159.  
  160. * CANCEL            && rem'd out by JLA
  161.  
  162. return
  163.  
  164.  
  165. *!*****************************************************************
  166. *!
  167. *!      Procedure: COPYPIECE
  168. *!
  169. *!*****************************************************************
  170. PROCEDURE copypiece
  171. * Copy FoxApp pieces to project directory
  172.  
  173. IF _MAC
  174.   fxpath = addbs(SYS(2027,foxappdir))         && probably C:\foxpro2\foxapp\
  175. ELSE
  176.   fxpath = addbs(foxappdir)
  177. ENDIF
  178. projdir = addbs(justpath(m.appfile))
  179.  
  180. =putout('prgs\appproc.prg',m.fxpath,m.projdir)
  181. =putout('menus\appmenu.mnx',m.fxpath,m.projdir)
  182. =putout('menus\appmenu.mnt',m.fxpath,m.projdir)
  183. =putout('screens\getdest.scx',m.fxpath,m.projdir)
  184. =putout('screens\getdest.sct',m.fxpath,m.projdir)
  185. =putout('screens\getorder.scx',m.fxpath,m.projdir)
  186. =putout('screens\getorder.sct',m.fxpath,m.projdir)
  187. =putout('screens\appabout.scx',m.fxpath,m.projdir)
  188. =putout('screens\appabout.sct',m.fxpath,m.projdir)
  189. =putout('screens\appsrch.scx',m.fxpath,m.projdir)
  190. =putout('screens\appsrch.sct',m.fxpath,m.projdir)
  191. =putout('screens\prtsetup.scx',m.fxpath,m.projdir)
  192. =putout('screens\prtsetup.sct',m.fxpath,m.projdir)
  193. =putout('screens\prtopts.scx',m.fxpath,m.projdir)
  194. =putout('screens\prtopts.sct',m.fxpath,m.projdir)
  195. =putout('screens\appctrl.scx',m.fxpath,m.projdir)
  196. =putout('screens\appctrl.sct',m.fxpath,m.projdir)
  197.  
  198. *!*****************************************************************
  199. *!
  200. *!      Procedure: PUTOUT
  201. *!
  202. *!*****************************************************************
  203. FUNCTION putout
  204. * Copies a file with name "Pathname" from the path specified in "source"
  205. * the the "target" path.
  206.  
  207. PARAMETERS pathname, source, target
  208. PRIVATE pathname, source, target, filname, file1, file2
  209.  
  210. m.filname = justfname(m.pathname)
  211. m.target = addbs(m.target)
  212. m.source = addbs(m.source)
  213. m.file1 = m.source + m.pathname
  214. m.file2 = m.target + m.filname
  215. IF FILE(m.file1)
  216.    COPY FILE (file1) TO (file2)
  217. ENDIF
  218.  
  219.  
  220. *!*****************************************************************
  221. *!
  222. *!      Function: FINDSRC
  223. *!
  224. *!*****************************************************************
  225. FUNCTION findsrc
  226. parameter appdir
  227. * Make sure that the FoxApp source files have been installed.
  228. * If they haven't, I can't build a project.
  229. m.targfile = addbs(SYS(2004))+'FOXAPP\FOXAPP.SRC'
  230. IF !FILE(m.targfile)
  231.    m.targfile = addbs(SYS(2004))+'FOXAPPW\FOXAPP.SRC'
  232.    IF !FILE(m.targfile)
  233.       * See if we are in the FOXAPP directory itself then
  234.       m.targfile = addbs(SYS(2004))+'GOODIES\FOXAPP\FOXAPP.SRC'
  235.       IF !FILE(m.targfile)
  236.          * See if we are in the FOXAPP directory itself then
  237.          m.targfile = addbs(CURDIR())+'FOXAPP.SRC'
  238.          IF !FILE(m.targfile)
  239.             WAIT WINDOW "FoxApp source files must be available to build projects." NOWAIT
  240.             m.targfile = GETFILE('SRC','Please locate the FOXAPP.SRC file:')
  241.             IF EMPTY(m.targfile)
  242.                DO alert WITH "FoxApp cannot build a full project without its source files."
  243.                DO close_up
  244.                RETURN ''
  245.             ELSE
  246.                m.newpath = SET('PATH')+';'+justpath(m.targfile)
  247.                SET PATH TO (m.newpath)
  248.             ENDIF
  249.          ENDIF
  250.       ENDIF
  251.    ENDIF
  252. ENDIF
  253. RETURN justpath(m.targfile)
  254.  
  255. *!*****************************************************************
  256. *!
  257. *!      Procedure: VERSIONDATE
  258. *!
  259. *!*****************************************************************
  260. FUNCTION versiondate
  261. * Returns the FoxPro build date as a date value
  262.  
  263. * VERSION(1) returns a string like this:
  264. *     FoxPro/LAN 2.0 (X) [Nov 15 1991 16:16:06] Serial # DEV001296 
  265. * We want to return 11/15/91 as a date value
  266.  
  267. m.v1 = VERSION(1)
  268.  
  269. * extract the portion of the VERSION(1) string between the brackets
  270. m.vdatestr = SUBSTR(m.v1,AT('[',m.v1)+1,RAT(']',m.v1)-AT('[',m.v1))
  271.  
  272. * extract just the date portion of the date/time string
  273. m.vdatestr = ALLTRIM(SUBSTR(m.vdatestr,1,AT(' ',m.vdatestr,3)-1))
  274.  
  275. * Pull out the month abbreviation and figure out which month number it is
  276. m.vmonthstr = UPPER(SUBSTR(m.vdatestr,1,3))
  277. DO CASE
  278. CASE INLIST(m.vmonthstr,'JANUARY','JAN')
  279.    m.vmonth = 1
  280. CASE INLIST(m.vmonthstr,'FEBRUARY','FEB')
  281.    m.vmonth = 2
  282. CASE INLIST(m.vmonthstr,'MARCH','MAR')
  283.    m.vmonth = 3
  284. CASE INLIST(m.vmonthstr,'APRIL','APR')
  285.    m.vmonth = 4
  286. CASE INLIST(m.vmonthstr,'MAY')
  287.    m.vmonth = 5
  288. CASE INLIST(m.vmonthstr,'JUNE','JUN')
  289.    m.vmonth = 6
  290. CASE INLIST(m.vmonthstr,'JULY','JUL')
  291.    m.vmonth = 7
  292. CASE INLIST(m.vmonthstr,'AUGUST','AUG')
  293.    m.vmonth = 8
  294. CASE INLIST(m.vmonthstr,'SEPTEMBER','SEP','SEPT')
  295.    m.vmonth = 9
  296. CASE INLIST(m.vmonthstr,'OCTOBER','OCT')
  297.    m.vmonth = 10
  298. CASE INLIST(m.vmonthstr,'NOVEMBER','NOV')
  299.    m.vmonth = 11
  300. CASE INLIST(m.vmonthstr,'DECEMBER','DEC')
  301.    m.vmonth = 12
  302. ENDCASE
  303.  
  304. * Reconstruct the string by using the month number 
  305. m.vdatestr = STR(m.vmonth,2)+'/'+LTRIM(SUBSTR(m.vdatestr,AT(' ',m.vdatestr)))
  306.  
  307. * Replace spaces with slashes
  308. m.vdatestr = CHRTRAN(m.vdatestr,' ','/')
  309. RETURN CTOD(m.vdatestr)
  310. *!*****************************************************************
  311. *!
  312. *!      Procedure: TRIMZERO
  313. *!
  314. *!*****************************************************************
  315. FUNCTION trimzero
  316. * Trims ASCII 0 characters from strg
  317. PARAMETER m.strg
  318. RETURN CHRTRAN(m.strg,CHR(0),"")
  319.  
  320. *!*****************************************************************
  321. *!
  322. *!      Procedure: FORCEEXT
  323. *!
  324. *!*****************************************************************
  325. FUNCTION forceext
  326. * Force the extension of "filname" to be whatever ext is.
  327. PARAMETERS filname,ext
  328. PRIVATE ALL
  329. IF SUBSTR(m.ext,1,1) = "."
  330.    m.ext = SUBSTR(m.ext,2,3)
  331. ENDIF
  332.  
  333. m.pname = justpath(m.filname)
  334. m.filname = justfname(UPPER(ALLTRIM(m.filname)))
  335. IF AT('.',m.filname) > 0
  336.    m.filname = SUBSTR(m.filname,1,AT('.',m.filname)-1) + '.' + m.ext
  337. ELSE
  338.    m.filname = m.filname + '.' + m.ext
  339. ENDIF
  340. RETURN addbs(m.pname) + m.filname
  341. *!*****************************************************************
  342. *!
  343. *!      Procedure: DEFAULTEXT
  344. *!
  345. *!*****************************************************************
  346. FUNCTION defaultext
  347. * Force the extension of "filname" to be whatever ext is, unless it
  348. * already has an extension.
  349. PARAMETERS filname,ext
  350. PRIVATE ALL
  351. IF EMPTY(justext(m.filname))
  352.    RETURN forceext(m.filname,m.ext)
  353. ELSE
  354.    RETURN m.filname
  355. ENDIF   
  356. *!*****************************************************************
  357. *!
  358. *!      Procedure: JUSTFNAME
  359. *!
  360. *!*****************************************************************
  361. FUNCTION justfname
  362. * Return just the filename (i.e., no path) from "filname"
  363. PARAMETERS filname
  364. PRIVATE ALL
  365. IF RAT('\',m.filname) > 0
  366.    m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
  367. ENDIF
  368. IF RAT(':',m.filname) > 0
  369.    m.filname = SUBSTR(m.filname,RAT(':',m.filname)+1,255)
  370. ENDIF
  371. RETURN ALLTRIM(UPPER(m.filname))
  372.  
  373. *!*****************************************************************
  374. *!
  375. *!      Procedure: JUSTSTEM
  376. *!
  377. *!*****************************************************************
  378. FUNCTION juststem
  379. * Return just the stem name from "filname"
  380. PARAMETERS m.filname
  381. PRIVATE ALL
  382. IF RAT('\',m.filname) > 0
  383.    m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
  384. ENDIF
  385. IF RAT(':',m.filname) > 0
  386.    m.filname = SUBSTR(m.filname,RAT(':',m.filname)+1,255)
  387. ENDIF
  388. IF AT('.',m.filname) > 0
  389.    m.filname = SUBSTR(m.filname,1,AT('.',m.filname)-1)
  390. ENDIF
  391. RETURN ALLTRIM(UPPER(m.filname))
  392.  
  393. *!*****************************************************************
  394. *!
  395. *!      Procedure: JUSTEXT
  396. *!
  397. *!*****************************************************************
  398. FUNCTION justext
  399. * Return just the extension from "filname"
  400. PARAMETERS m.filname
  401. PRIVATE ALL
  402. filname = JustFname(m.filname)   && prevents problems with ..\ paths
  403. m.ext = ""
  404. IF AT('.',m.filname) > 0
  405.    m.ext = SUBSTR(m.filname,AT('.',m.filname)+1,3)
  406. ENDIF
  407. RETURN UPPER(m.ext)
  408.  
  409.  
  410. *!*****************************************************************
  411. *!
  412. *!      Procedure: JUSTPATH
  413. *!
  414. *!*****************************************************************
  415. FUNCTION justpath
  416. * Return just the path name from "filname"
  417. PARAMETERS m.filname
  418. PRIVATE ALL
  419. m.filname = ALLTRIM(UPPER(m.filname))
  420. m.pathsep = IIF(_MAC,":", "\")
  421. IF _MAC
  422.    m.found_it = .F.
  423.    m.maxchar = max(RAT("\", m.filname), RAT(":", m.filname))
  424.    IF m.maxchar > 0
  425.       m.filname = SUBSTR(m.filname,1,m.maxchar)
  426.       IF RIGHT(m.filname,1) $ ":\" AND LEN(m.filname) > 1 ;
  427.             AND !(SUBSTR(m.filname,LEN(m.filname)-1,1)  $ ":\")
  428.          m.filname = SUBSTR(m.filname,1,LEN(m.filname)-1)
  429.       ENDIF
  430.       RETURN m.filname
  431.    ENDIF
  432. ELSE
  433.    IF m.pathsep $ filname
  434.       m.filname = SUBSTR(m.filname,1,RAT(m.pathsep,m.filname))
  435.       IF RIGHT(m.filname,1) = m.pathsep AND LEN(m.filname) > 1 ;
  436.             AND SUBSTR(m.filname,LEN(m.filname)-1,1) <> m.pathsep
  437.          m.filname = SUBSTR(m.filname,1,LEN(m.filname)-1)
  438.       ENDIF
  439.       RETURN m.filname
  440.    ENDIF      
  441. ENDIF
  442. RETURN ''
  443.  
  444. *!*****************************************************************
  445. *!
  446. *!      Procedure: ADDBS
  447. *!
  448. *!*****************************************************************
  449. FUNCTION addbs
  450. * Add a backslash to a path name if there isn't already one there
  451. PARAMETER m.pathname
  452. PRIVATE ALL
  453. m.pathname = ALLTRIM(UPPER(m.pathname))
  454. IF !(RIGHT(m.pathname,1) $ '\:') AND !EMPTY(m.pathname)
  455.    m.pathname = m.pathname + IIF(_MAC,':','\')
  456. ENDIF
  457. RETURN m.pathname
  458.  
  459. *!*****************************************************************
  460. *!
  461. *!      Function: ADDCOLON
  462. *!
  463. *!*****************************************************************
  464. FUNCTION Addcolon
  465. PARAMETER m.strg
  466. PRIVATE m.retval
  467. * If strg is the name of the current disk, add a colon to it.  This 
  468. * function is used mainly by SET DEFAULT TO statements, where we have
  469. * to have the colon.
  470. IF UPPER(m.strg)+":" == UPPER(SET("DEFAULT"))
  471.    m.retval = m.strg + ":"
  472. ELSE
  473.    m.retval = m.strg 
  474. ENDIF      
  475. RETURN m.retval
  476.  
  477. *!*****************************************************************
  478. *!
  479. *!      Function: TERM
  480. *!
  481. *!*****************************************************************
  482. FUNCTION term
  483. * Returns the item-th term from string strg, where a term is a set of characters
  484. * separated by commas.
  485.  
  486. PARAMETERS m.strg, m.item
  487. m.numcommas = OCCURS(",",strg)
  488. IF m.item > m.numcommas + 1
  489.    RETURN ""
  490. ELSE   
  491.     DO CASE
  492.     CASE m.item = 1
  493.        RETURN LEFT(m.strg,AT(",",m.strg)-1)
  494.     CASE m.item = m.numcommas + 1
  495.        RETURN SUBSTR(m.strg,RAT(",",m.strg)+1)
  496.     OTHERWISE
  497.        RETURN SUBSTR(m.strg,AT(",",m.strg,m.item-1)+1,;
  498.           AT(",",m.strg,m.item) - AT(",",m.strg,m.item-1) - 1)
  499.     ENDCASE
  500. ENDIF     
  501. *!*****************************************************************
  502. *!
  503. *!      Procedure: INVERT
  504. *!
  505. *!*****************************************************************
  506. PROCEDURE invert
  507. * Completely invert the "filname" database into a CDX file, creating
  508. * an index tag on each field.
  509.  
  510. PARAMETERS m.filname
  511. PRIVATE m.filname, m.i, m.safe_stat, m.comp_stat, m.in_area, m.fldname
  512.  
  513. m.comp_stat = SET("COMPATIBLE")
  514. m.safe_stat = SET("SAFETY")
  515. SET COMPATIBLE TO FOXPLUS
  516. SET SAFETY OFF
  517.  
  518. m.in_area = SELECT()            && currently selected area
  519.  
  520. m.fstem = makealias(juststem(m.filname))
  521. IF USED(m.fstem)
  522.    SELECT (m.fstem)
  523. ELSE
  524.    SELECT 0
  525.    USE (m.filname)
  526. ENDIF
  527.  
  528. FOR m.i = 1 TO FCOUNT()
  529.    m.fldname = FIELD(m.i)
  530.    WAIT WINDOW "Indexing on "+m.fldname + "." NOWAIT
  531.    IF !INLIST(TYPE(m.fldname),"M","G","P")
  532.       IF TYPE(m.fldname) = "C" AND LEN(&fldname) >= 99
  533.          INDEX ON SUBSTR(&fldname,1,99) TO (m.fldname)
  534.       ELSE
  535.          INDEX ON &fldname TAG (m.fldname)
  536.       ENDIF
  537.    ENDIF
  538. ENDFOR
  539. WAIT WINDOW "Indexing for "+m.fstem+" is complete!" NOWAIT
  540.  
  541. IF m.in_area <> SELECT()
  542.    USE
  543. ENDIF
  544. SELECT (m.in_area)
  545. IF m.comp_stat = "ON" OR m.comp_stat = "DB4"
  546.    SET COMPATIBLE TO DB4
  547. ENDIF
  548. IF m.safe_stat = "ON"
  549.    SET SAFETY ON
  550. ENDIF
  551. RETURN
  552.  
  553.  
  554. *!*****************************************************************
  555. *!
  556. *!      Procedure: MERGECTRL
  557. *!
  558. *!*****************************************************************
  559. PROCEDURE mergectrl
  560. * Merge the FoxApp control panel into user's screen to create a 
  561. * screen set.  This routine also forces all other screens to be
  562. * modal.
  563.  
  564. PARAMETERS m.pjxname, m.scxname, m.ctrl_y, m.ctrl_x
  565. PRIVATE pjxname, scxname, in_area, ctrl_y, ctrl_x, sname, ctrl_name
  566.  
  567. m.in_area = SELECT()
  568.  
  569. * name of the control panel screen, as it exists inside FOXAPP.APP
  570. * (or copied onto the disk, if regen is in effect)
  571. IF m.regen
  572.    m.ctrl_scx   = addbs(justpath(m.pjxname))+'APPCTRL.SCX'
  573. ELSE
  574.    m.ctrl_scx   = addbs(SYS(2004))+'FOXAPP\SCREENS\APPCTRL.SCX'
  575. ENDIF
  576. IF _MAC
  577.   m.ctrl_scx = SYS(2027, m.ctrl_scx)
  578. ENDIF
  579.  
  580. IF FILE(m.ctrl_scx)
  581.    SELECT 0
  582.    USE (m.ctrl_scx) AGAIN ALIAS ctrlscx
  583.    REPLACE ctrlscx.hpos WITH m.ctrl_x, ctrlscx.vpos WITH m.ctrl_y
  584.    USE
  585. ELSE
  586.    WAIT WINDOW "Could not find "+m.ctrl_scx
  587.    RETURN   
  588. ENDIF
  589.  
  590. * Quit now if the project file is hiding.
  591. IF !FILE(m.pjxname)
  592.    RETURN
  593. ENDIF
  594.  
  595. * The lower case comparisons won't work if COLLATE <> MACHINE
  596. m.mcollate = SET("COLLATE")
  597. SET COLLATE TO "MACHINE"
  598.  
  599. IF USED(makealias(juststem(m.pjxname)))
  600.    * Open it again with the 'pjxfile' alias.
  601.    m.sname = makealias(juststem(m.pjxname))
  602.    SELECT (sname)
  603. ELSE
  604.    SELECT 0
  605. ENDIF
  606. USE (m.pjxname) ALIAS pjxfile
  607.  
  608. * Find the home directory
  609. LOCATE FOR UPPER(pjxfile.type) == "H" 
  610. IF FOUND()
  611.    m.homename = pjxfile.homedir
  612. ELSE
  613.    m.homename = CURDIR()
  614. ENDIF
  615.  
  616. * Locate the master screen set record
  617. LOCATE FOR UPPER(justfname(trimzero(pjxfile.name))) ;
  618.    == UPPER(forceext(justfname(m.scxname),'SPR')) AND pjxfile.type = 'S'
  619. IF FOUND()
  620.    m.setnum = pjxfile.setid
  621.    * Now locate the user screen SCX record
  622.    GOTO TOP
  623.    LOCATE FOR UPPER(justfname(trimzero(pjxfile.name)));
  624.        == UPPER(justfname(m.scxname)) ;
  625.       AND setid = m.setnum
  626.    IF FOUND()
  627.       * Use the coordinates stored in the screen file itself.  These
  628.       * reflect the changes that the user made to the screen location
  629.       * while inside FoxApp.
  630.       REPLACE pjxfile.arranged  WITH "WINDOWS"+CHR(0)+"N"+"N";
  631.          +PADL(LTRIM(STR(m.ctrl_y,4)),8)+PADL(LTRIM(STR(m.ctrl_x,4)),8) ;
  632.          +"MAC     "+CHR(0)+"N"+"N";
  633.          +PADL(LTRIM(STR(m.ctrl_y,4)),8)+PADL(LTRIM(STR(m.ctrl_x,4)),8)
  634.       REPLACE pjxfile.scrnorder WITH 0
  635.    ENDIF
  636.  
  637.    * Figure out how many screens are in this screen set (usually 1
  638.    * if this is a FoxApp generated app, but perhaps the user has 
  639.    * added some more screens).   
  640.    GOTO TOP
  641.    COUNT FOR pjxfile.setid = m.setnum TO m.ctrl_order
  642.  
  643.    * Put the control panel into the project as a screen set member 
  644.    * of the user's screen set.  If it is already there, update it.
  645.    * If not, create a new record and insert it.
  646.    GOTO TOP
  647.    LOCATE FOR justfname(UPPER(ALLTRIM(trimzero(pjxfile.name))))  ;
  648.       == UPPER(justfname(m.ctrl_scx)) 
  649.  
  650.    IF !FOUND()
  651.       APPEND BLANK
  652.    ELSE
  653.       m.ctrl_order = m.ctrl_order - 1   && don't count existing one
  654.    ENDIF
  655.  
  656.    * Update the project file to point to the control panel as part of the
  657.    * user screen set. 
  658.    IF m.regen
  659.       m.user_scx =   m.ctrl_scx
  660.    ELSE
  661.       m.user_scx =   SYS(2014,m.ctrl_scx,m.pjxname)
  662.    ENDIF
  663.    REPLACE pjxfile.name WITH m.user_scx, ;
  664.       pjxfile.TYPE      WITH 's',        ;
  665.       pjxfile.setid     WITH m.setnum,   ;
  666.       pjxfile.timestamp WITH 0,          ;
  667.       pjxfile.exclude   WITH .F.,        ;
  668.       pjxfile.scrnorder WITH m.ctrl_order
  669.    SET COLLATE TO "&mcollate"
  670. ELSE
  671.    * This means that something went badly wrong during BUILD PROJECT
  672.    WAIT WINDOW "FoxApp could not complete this application."
  673.    SET DEFAULT TO (c_path)
  674.    SET COLLATE TO "&mcollate"
  675.    DO close_up
  676.    CANCEL
  677. ENDIF
  678.  
  679. USE
  680. SELECT (in_area)
  681.  
  682.  
  683. *!*****************************************************************
  684. *!
  685. *!      Procedure: INITDBFLIST
  686. *!
  687. *!*****************************************************************
  688. PROCEDURE initdbflist
  689. * Initialize the DBFLIST array 
  690. PRIVATE m.i,m.j
  691.  
  692. PUBLIC dbflist[m.numareas,m.numcols]
  693.  
  694. * Format the stem names for the popup
  695. FOR m.i = 1 TO m.numareas
  696.    dbflist[m.i,m.cstemnum]   = '\'   && start everything off disabled
  697.    dbflist[m.i,m.arranged]   = "N"   && user hasn't arranged the screen yet
  698.    dbflist[m.i,m.theFont]    = defaultfont
  699.    dbflist[m.i,m.cascadenum] = defaultcasc
  700. ENDFOR
  701.  
  702. * Initialize the other columns in the dbflist array, except screen
  703. * positions
  704. FOR m.i = 1 TO m.numareas
  705.    FOR m.j = 2 TO m.srownum - 1
  706.       dbflist[m.i,m.j] = ''
  707.    ENDFOR
  708. ENDFOR
  709.  
  710. * Initialize the screen positions
  711. FOR m.i = 1 TO m.numareas
  712.    dbflist[m.i,m.srownum] = ALLTRIM(STR(m.i,3))
  713.    dbflist[m.i,m.scolnum] = ALLTRIM(STR(m.i,3))
  714.    dbflist[m.i,m.erownum] = "6"                     && 6 rows high
  715.    dbflist[m.i,m.ecolnum] = ALLTRIM(STR(76-m.i,3))  && width
  716. ENDFOR
  717.  
  718. *!*****************************************************************
  719. *!
  720. *!      Procedure: OPENDBF
  721. *!
  722. *!*****************************************************************
  723. FUNCTION opendbf
  724. * Open a DBF and return the alias, or blanks if the database could 
  725. *   not be opened.
  726. PARAMETERS fname
  727. PRIVATE fname, stem, thealias
  728. IF FILE(m.fname)
  729.    m.stem = juststem(m.fname)
  730.    m.thealias = LEFT(m.stem,10)
  731.    m.thealias = CHRTRAN(m.thealias, ' ', '_')
  732.    IF USED(m.thealias)
  733.       SELECT (m.thealias)
  734.    ELSE
  735.       SELECT 0
  736.       m.fname = LOCFILE(m.fname,'DBF','Please locate the database')
  737.       IF EMPTY(m.fname)
  738.          RETURN ''
  739.       ELSE
  740.          USE (m.fname)
  741.       ENDIF
  742.    ENDIF
  743.    RETURN ALIAS()
  744. ELSE
  745.    RETURN ''
  746. ENDIF
  747.  
  748. *!*****************************************************************
  749. *!
  750. *!      Procedure: CREATESCX
  751. *!
  752. *!*****************************************************************
  753. PROCEDURE createscx
  754. PRIVATE maxh, maxv, s_name
  755. * Create a quick-screen SCX file from the named database
  756. m.scxname = ALLTRIM(m.scxname)
  757. IF !EMPTY(opendbf(m.dbfname))
  758.    m.s_name = addbs(justpath(m.scxname)) + juststem(m.scxname)   && don't need extension
  759.    IF _MAC
  760.      WAIT WINDOW "Creating screen "+SYS(2027,m.s_name) NOWAIT
  761.    ELSE
  762.      WAIT WINDOW "Creating screen "+m.s_name NOWAIT
  763.    ENDIF
  764.    CREATE SCREEN (m.s_name) FROM (m.dbfname) ROW
  765.    m.scxname = forceext(m.scxname,"SCX")
  766.    IF FILE(m.scxname)
  767.       SHOW GET addscx DISABLE
  768.       SHOW GET modscx ENABLE
  769.    ENDIF
  770.    IF !EMPTY(m.scxname)
  771.       SELECT 0
  772.       USE (m.scxname) ALIAS fxscxname
  773.       REPLACE fxscxname.width WITH MIN(my_scols(),fxscxname.width)
  774.       m.maxh = width
  775.       m.maxv = height
  776.  
  777.       IF relateddbfs() AND UPPER(dbflist[1,m.arranged]) = "N"
  778.          * No screen position yet defined for the main database.  Center it,
  779.          * unless there are lots of related databases.  If there are, put
  780.          * it closer to the top of the screen.
  781.          IF m.nextdbf < 3  && just one database used in app
  782.             m.start_row = MAX(INT(my_srows()/2-height/2),0)
  783.             m.start_col = MAX(INT(my_scols()/2-width/2),0)
  784.          ELSE
  785.             m.start_row = 1
  786.             m.start_col = MAX(INT(my_scols()/2-width/2),0)
  787.          ENDIF
  788.       ELSE   && center the screen horizontally if it hasn't been arranged.
  789.          m.start_row = 1
  790.          m.start_col = MAX(INT(my_scols()/2-width/2),0)
  791.       ENDIF
  792.       m.start_row = MAX(0,m.start_row)
  793.       m.start_col = MAX(0,m.start_col)
  794.       
  795.       REPLACE ALL fxscxname.vpos WITH m.start_row, fxscxname.hpos WITH m.start_col;
  796.          FOR objtype = 1 AND platform = getplat()
  797.          
  798.       * Make some space around the fields
  799.       REPLACE ALL fxscxname.hpos WITH fxscxname.hpos + 1,;
  800.          fxscxname.vpos WITH fxscxname.vpos + 1 ;
  801.          FOR objtype > 4 AND objtype <> 23 AND platform = getplat()
  802.          
  803.       SCAN FOR objtype > 4 and objtype <> 23
  804.          m.thish = fxscxname.hpos + fxscxname.width ;
  805.           * FONTMETRIC(6,fxscxname.fontface,fxscxname.fontsize, ;
  806.              whatstyle(fxscxname.fontstyle)) ;
  807.           /  FONTMETRIC(6,WFONT(1,""),WFONT(2,""),WFONT(3,""))
  808.          m.thisv = fxscxname.vpos + fxscxname.height ;
  809.           * FONTMETRIC(1,fxscxname.fontface,fxscxname.fontsize, ;
  810.              whatstyle(fxscxname.fontstyle)) ;
  811.           /  FONTMETRIC(1,WFONT(1,""),WFONT(2,""),WFONT(3,""))
  812.          m.maxh = MAX(m.thish,m.maxh)
  813.          m.maxv = MAX(m.thisv,m.maxv)
  814.       ENDSCAN
  815.       GOTO TOP
  816.       REPLACE fxscxname.center WITH .T.,;
  817.          fxscxname.width WITH m.maxh + 6, ;
  818.          fxscxname.height WITH m.maxv + 1,;
  819.          fxscxname.name WITH makealias(juststem(m.scxname)), ;
  820.          fxscxname.style WITH 2,;
  821.          fxscxname.border WITH 1,;
  822.          fxscxname.tag WITH '" '+makealias(juststem(m.scxname))+' "'
  823.          
  824.       IF relateddbfs()
  825.          dbflist[1,m.srownum] = ALLTRIM(STR(m.start_row,4))
  826.          dbflist[1,m.scolnum] = ALLTRIM(STR(m.start_col,4))
  827.          dbflist[1,m.erownum] = ALLTRIM(STR(fxscxname.height,4))
  828.          dbflist[1,m.ecolnum] = ALLTRIM(STR(fxscxname.width,4))
  829.       ENDIF
  830.                
  831.       USE
  832.    ENDIF
  833.    WAIT WINDOW "Screen has been created." NOWAIT
  834. ELSE
  835.    DO errshow WITH "Database could not be opened.",10
  836. ENDIF
  837. SHOW GETS
  838. RETURN
  839.  
  840.  
  841. *!*****************************************************************
  842. *!
  843. *!      Procedure: FILATTR
  844. *!
  845. *!*****************************************************************
  846. FUNCTION filattr
  847. * Return file attributes of "filname"
  848. PARAMETER m.filname
  849. PRIVATE filarray, m.filpos
  850. m.filname = UPPER(ALLTRIM(m.filname))
  851. IF ADIR(filarray,m.filname) > 0
  852.    m.filpos = ASCAN(filarray,justfname(m.filname))
  853.    IF m.filpos > 0
  854.       RETURN filarray[m.filpos,5]
  855.    ENDIF
  856. ENDIF
  857. RETURN ''
  858. *!*****************************************************************
  859. *!
  860. *!      Procedure: RELATEDDBFS
  861. *!
  862. *!*****************************************************************
  863. FUNCTION relateddbfs
  864. * RETURN T if related DBF files have been defined through FoxApp
  865. RETURN m.nextdbf > 2
  866.  
  867. *!*****************************************************************
  868. *!
  869. *!      Procedure: GETDBFLIST
  870. *!
  871. *!*****************************************************************
  872. FUNCTION getdbflist
  873. * Retrieve dbflist from resource file
  874.  
  875. PARAMETERS cstem
  876. PRIVATE m.nextdbf, m.in_area, m.cstem, m.i, m.j, m.j1_at, m.j2_at
  877.  
  878. IF !FILE(SYS(2005))    && resource file not found.
  879.    RETURN 0
  880. ENDIF
  881.  
  882. m.nextdbf = 0
  883. m.in_area = SELECT(0)
  884.  
  885. m.cstem = UPPER(ALLTRIM(m.cstem))
  886. IF EMPTY(m.cstem)
  887.    RETURN 0
  888. ENDIF
  889.  
  890. m.memwidth = SET('MEMOWIDTH')
  891. SET MEMOWIDTH TO 255
  892.  
  893. SELECT 0
  894. USE (SYS(2005)) AGAIN ALIAS rsc
  895.  
  896. LOCATE FOR UPPER(ALLTRIM(rsc.type)) == m.rsctype;
  897.    AND UPPER(ALLTRIM(rsc.id)) == 'DBFLIST' ;
  898.    AND UPPER(ALLTRIM(rsc.name)) == m.cstem ;
  899.    AND !DELETED()
  900.  
  901. IF FOUND() AND !EMPTY(rsc.data)
  902.    WAIT WINDOW "Retrieving stored relationships." NOWAIT
  903.  
  904.    IF TYPE("dbflist") = "U"
  905.       DO initdbflist
  906.    ENDIF
  907.  
  908.    * First get the position of the control panel
  909.    m.ctrlline = MLINE(rsc.data,1)
  910.    m.ctrlrow  = VAL(SUBSTR(m.ctrlline,1,AT(';',m.ctrlline)-1))
  911.    m.ctrlcol  = VAL(SUBSTR(m.ctrlline,AT(';',m.ctrlline)+1))
  912.  
  913.    FOR m.i = 1 TO m.numareas
  914.       m.this_dbf = MLINE(rsc.data,m.i+1)
  915.       FOR m.j = 1 TO m.numcols
  916.          DO CASE
  917.          CASE m.j = 1
  918.             IF AT(';',m.this_dbf) = 1
  919.                dbflist[m.i,m.j] = '\'   && make this empty area disabled in the list
  920.             ELSE
  921.                dbflist[m.i,m.j] = SUBSTR(m.this_dbf,1,AT(';',m.this_dbf)-1)
  922.             ENDIF
  923.          CASE m.j = m.numcols
  924.             dbflist[m.i,m.j] = SUBSTR(m.this_dbf,AT(';',m.this_dbf,m.numcols-1)+1)
  925.          OTHERWISE
  926.             m.j1_at = AT(';',m.this_dbf,m.j-1)
  927.             m.j2_at = AT(';',m.this_dbf,m.j)
  928.             dbflist[m.i,m.j] = SUBSTR(m.this_dbf,m.j1_at + 1,m.j2_at - m.j1_at - 1)
  929.          ENDCASE
  930.  
  931.       ENDFOR
  932.  
  933.       IF !EMPTY(dbflist[m.i,m.cstemnum])       ;
  934.             AND dbflist[m.i,m.cstemnum] <> '\' ;
  935.             AND !USED(dbflist[m.i,m.cstemnum])
  936.  
  937.          IF !FILE(dbflist[m.i,m.cdbfnum])
  938.             * See if we can find it anywhere along the path
  939.             IF FILE(FULLPATH(dbflist[m.i,m.cdbfnum]))
  940.                dbflist[m.i,m.cdbfnum] = FULLPATH(dbflist[m.i,m.cdbfnum])
  941.                dbflist[m.i,m.cstemnum] = makealias(juststem(dbflist[m.i,m.cdbfnum]))
  942.             ELSE   && it is nowhere to be found.  Ask where it is.
  943.                dbflist[m.i,m.cdbfnum] = GETFILE('DBF',;
  944.                   'Where is '+juststem(dbflist[m.i,m.cdbfnum])+'?')
  945.                IF EMPTY(dbflist[m.i,m.cdbfnum]) OR !FILE(dbflist[m.i,m.cdbfnum])
  946.                   DO alert WITH dbflist[m.i,m.cstemnum]+" could not be found!"
  947.                   DO close_up
  948.                ENDIF
  949.             ENDIF
  950.          ENDIF
  951.  
  952.          dbflist[m.i,m.cstemnum] = makealias(juststem(dbflist[i,m.cdbfnum]))
  953.  
  954.          IF FILE(dbflist[m.i,m.cdbfnum])
  955.             * full name of database including path
  956.             SELECT 0
  957.             USE (dbflist[m.i,m.cdbfnum]) AGAIN
  958.          ENDIF
  959.  
  960.          * Ensure that this database has a corresponding CDX file
  961.          DO makecdx WITH dbflist[m.i,m.cdbfnum], dbflist[m.i,m.cfldnum]
  962.       ENDIF
  963.  
  964.       * Record the first open database area
  965.       IF !EMPTY(dbflist[m.i,m.cstemnum]) AND dbflist[m.i,m.cstemnum] <> '\'
  966.          m.nextdbf = m.i+1
  967.       ENDIF
  968.  
  969.    ENDFOR
  970.    WAIT CLEAR
  971. ENDIF
  972. SELECT rsc
  973. USE
  974. SELECT (m.in_area)
  975. SET MEMOWIDTH TO m.memwidth
  976.  
  977. RETURN m.nextdbf
  978.  
  979.  
  980. *!*****************************************************************
  981. *!
  982. *!      Procedure: PUTDBFLIST
  983. *!
  984. *!*****************************************************************
  985. FUNCTION putdbflist
  986. PARAMETERS cstem
  987. PRIVATE m.cstem, m.in_area, m.i, m.j, m.repl_str
  988.  
  989. * Store the dbflist array in the resource file
  990. * The format for storing the dbflist array in the data memo field is:
  991. *    string;string;string;string... CHR(13)+CHR(10)
  992.  
  993. IF !FILE(SYS(2005)) OR EMPTY(m.cstem)
  994.    RETURN 0
  995. ENDIF
  996.  
  997. * Don't update if this is a read-only file
  998. * SYS(2026,filename) is a last-minute function that returns 'Y' if the 
  999. * file is both open and marked read-only, for any reason (e.g., it's in an APP, it's
  1000. * the resource file for another instance of FoxPro, etc.)
  1001. IF 'R' $ filattr(SYS(2005)) OR SYS(2026,SYS(2005)) <> "N"
  1002.    WAIT WINDOW "Resource file is read-only.  Not updated." NOWAIT
  1003.    m.storersc = .F.
  1004.    =INKEY(2)
  1005.    RETURN 0
  1006. ENDIF
  1007.  
  1008. m.cstem = UPPER(ALLTRIM(m.cstem))
  1009. m.in_area = SELECT()
  1010.  
  1011. SELECT 0
  1012. USE (SYS(2005)) AGAIN ALIAS rsc
  1013. LOCATE FOR UPPER(ALLTRIM(rsc.type)) == m.rsctype ;
  1014.    AND UPPER(ALLTRIM(rsc.id)) == 'DBFLIST' ;
  1015.    AND UPPER(ALLTRIM(rsc.name)) == m.cstem
  1016. IF !FOUND()
  1017.    APPEND BLANK
  1018. ELSE
  1019.    IF rsc.readonly
  1020.       WAIT WINDOW "Existing resource record is read-only.  Not updated." NOWAIT
  1021.       =INKEY(1)   && wait 1 second
  1022.       USE
  1023.       SELECT (m.in_area)
  1024.       RETURN 0
  1025.    ENDIF
  1026. ENDIF
  1027.  
  1028. * Write out the control panel upper left coordinates first
  1029. m.repl_str = ALLTRIM(STR(m.ctrlrow,7,3))+';';
  1030.    +ALLTRIM(STR(m.ctrlcol,7,3))+CHR(13)+CHR(10)
  1031.  
  1032. * Write the dbflist data for each row/col
  1033. FOR m.i = 1 TO m.numareas
  1034.    FOR m.j = 1 TO m.numcols
  1035.       m.repl_str = m.repl_str +IIF(m.j=1,'',';') ;
  1036.          + IIF(INLIST(TYPE("dbflist[m.i,m.j]"),'U','L'),'',TRIM(dbflist[m.i,m.j]));
  1037.          + IIF(m.j=m.numcols,CHR(13)+CHR(10),'')
  1038.    ENDFOR
  1039. ENDFOR
  1040. REPLACE rsc.data WITH m.repl_str, ;
  1041.    rsc.type      WITH m.rsctype, ;
  1042.    rsc.id        WITH 'DBFLIST',  ;
  1043.    rsc.name      WITH m.cstem,    ;
  1044.    rsc.ckval     WITH VAL(SYS(2007,rsc.data)),;
  1045.    rsc.updated   WITH DATE(),;
  1046.    rsc.readonly  WITH .F.
  1047.  
  1048. * Set the flag that notifies the rest of the program that the 
  1049. * relations have been stored in the resource file.
  1050. rsc_stored = .T.
  1051.  
  1052. USE
  1053. SELECT (m.in_area)
  1054. RETURN 0
  1055.  
  1056. *!*****************************************************************
  1057. *!
  1058. *!      Procedure: MAKECDX
  1059. *!
  1060. *!*****************************************************************
  1061. PROCEDURE makecdx
  1062. parameter filname, tagname
  1063. * Ensure that filename has a CDX file with a tag name of tagname
  1064. PRIVATE m.filname, m.tagname, m.cdxname, m.i, m.justtag
  1065.  
  1066. justtag = m.tagname
  1067. * Strip off alias names from fields like parent.fldname
  1068. IF AT('.',m.justtag) > 0
  1069.    m.justtag = ALLTRIM(UPPER(SUBSTR(m.justtag,AT('.',m.justtag)+1)))
  1070. ENDIF
  1071.  
  1072. cdxname = forceext(m.filname,'CDX')
  1073. =opendbf(m.filname)
  1074. DO CASE
  1075. CASE !FILE(m.cdxname)
  1076.    DO invert WITH m.filname
  1077. OTHERWISE
  1078.    * Cycle through the tags looking for one to match the key field
  1079.    m.i = 1
  1080.    DO WHILE (TAG(m.cdxname,m.i) != m.justtag) ;
  1081.          AND !EMPTY(TAG(m.cdxname,m.i))
  1082.       m.i = m.i + 1
  1083.    ENDDO
  1084.    IF EMPTY(TAG(m.cdxname,m.i))
  1085.       DO invert WITH m.filname
  1086.    ENDIF
  1087. ENDCASE
  1088.  
  1089.  
  1090.  
  1091. *!*****************************************************************
  1092. *!
  1093. *!      Procedure: DEFINEWINDOW
  1094. *!
  1095. *!*****************************************************************
  1096. PROCEDURE definewindow
  1097. * Defines a window for use by the error reporting routines
  1098.  
  1099. parameter m.hight, m.width, m.name, m.scheme
  1100. PRIVATE m.fromrow, m.fromcol, m.torow, m.tocol
  1101.  
  1102. m.fromrow = INT((srow()-m.hight)/2)
  1103. m.fromcol = INT((scol()-m.width)/2)
  1104. m.torow   = m.fromrow + m.hight
  1105. m.tocol   = m.fromcol + m.width
  1106.  
  1107. DEFINE WINDOW (m.name);
  1108.    FROM m.fromrow, m.fromcol TO m.torow, m.tocol;
  1109.    FLOAT NOGROW NOCLOSE NOZOOM SHADOW DOUBLE;
  1110.    COLOR SCHEME (m.scheme)
  1111.  
  1112. RETURN
  1113. *!*****************************************************************
  1114. *!
  1115. *!      Function: Maptochar
  1116. *!
  1117. *!*****************************************************************
  1118. FUNCTION maptochar
  1119. * Maps the numeric values used in SCX files to the string that FONTMETRIC needs
  1120. PARAMETERS stylenum
  1121. DO CASE
  1122. CASE m.stylenum = 0
  1123.    RETURN ""
  1124. CASE m.stylenum = 1
  1125.    RETURN "B"
  1126. CASE m.stylenum = 2
  1127.    RETURN "I"
  1128. CASE m.stylenum = 3
  1129.    RETURN "BI"
  1130. OTHERWISE
  1131.    RETURN ""   
  1132. ENDCASE            
  1133.  
  1134. *!*****************************************************************
  1135. *!
  1136. *!      Function: TRANFONT
  1137. *!
  1138. *!*****************************************************************
  1139. FUNCTION tranfont
  1140. * Translates coordinates from one font to another
  1141. PARAMETERS units, code, fromfont, fromsize, fromstyle, tofont, tosize, tostyle
  1142. * Units is the width/height term
  1143. * code = 1 for height, 6 for width
  1144. PRIVATE strflag, retval
  1145.  
  1146. IF PARAMETERS() < 8
  1147.    m.tostyle = WFONT(3,"")
  1148. ENDIF
  1149. IF PARAMETERS() < 7
  1150.    m.tosize = WFONT(2,"")
  1151. ENDIF
  1152. IF PARAMETERS() < 6
  1153.    m.tofont = WFONT(1,"")
  1154. ENDIF
  1155. m.strflag = .F.
  1156. IF TYPE("units") = "C"
  1157.    m.units = VAL(m.units)
  1158.    m.strflag = .T.
  1159. ENDIF   
  1160. IF TYPE("fromstyle") = "N"
  1161.    m.fromstyle = MapToChar(m.fromstyle)
  1162. ENDIF
  1163. IF TYPE("tostyle") = "N"
  1164.    m.tostyle = MapToChar(m.tostyle)
  1165. ENDIF
  1166. IF TYPE("tosize") = "C"
  1167.    m.tosize = VAL(m.tosize)
  1168. ENDIF
  1169. IF TYPE("fromsize") = "C"
  1170.    m.fromsize = VAL(m.fromsize)
  1171. ENDIF
  1172.     
  1173. m.tofont = FONTMETRIC(m.code,m.tofont, m.tosize, m.tostyle)
  1174. m.fromfont = FONTMETRIC(m.code,m.fromfont,m.fromsize,m.fromstyle)
  1175. IF m.tofont <> 0     && avoid division by zero
  1176.    retval =  m.units *  m.fromfont / m.tofont * 1.00
  1177.    IF strflag
  1178.       retval = ALLTRIM(STR(retval,10))
  1179.    ENDIF
  1180. ELSE
  1181.    retval = IIF(strflag,"0",0)
  1182. ENDIF
  1183. RETURN retval
  1184. *!*****************************************************************
  1185. *!
  1186. *!      Procedure: ARRSAVE
  1187. *!
  1188. *!*****************************************************************
  1189. PROCEDURE arrsave
  1190. * Save arrangement of windows and return to dbfselect screen
  1191.  
  1192. * Set exit flag for READ VALID--can't be PRIVATE
  1193. m.arrexflg = .T.
  1194.  
  1195. * Record window coordinates and release all the application windows
  1196. IF WEXIST('CTRL')
  1197.   m.ctrlrow = WLROW('CTRL')
  1198.   m.ctrlcol = WLCOL('CTRL')
  1199.   RELEASE WINDOW ctrl
  1200. ENDIF
  1201.  
  1202. * Store the coordinates for the main window
  1203. IF !EMPTY(dbflist[1,m.cstemnum]) AND dbflist[1,m.cstemnum] <> '\'
  1204.    dbflist[1,m.srownum] = ALLTRIM(STR(WLROW(dbflist[1,m.cstemnum]),7,3))
  1205.    dbflist[1,m.scolnum] = ALLTRIM(STR(WLCOL(dbflist[1,m.cstemnum]),7,3))
  1206.    dbflist[1,m.erownum] = ALLTRIM(STR(WROWS(dbflist[1,m.cstemnum]),7,3))
  1207.    dbflist[1,m.ecolnum] = ALLTRIM(STR(WCOLS(dbflist[1,m.cstemnum]),7,3))
  1208.    RELEASE WINDOW (dbflist[1,m.cstemnum])
  1209. ENDIF
  1210. dbflist[1,m.arranged] = "Y"
  1211.  
  1212. FOR m.i = 2 TO m.numareas
  1213.    IF !EMPTY(dbflist[m.i,m.cstemnum]) AND dbflist[m.i,m.cstemnum] <> '\'
  1214.       dbflist[m.i,m.srownum] = ALLTRIM(STR(WLROW(dbflist[m.i,m.cstemnum]),7,3))
  1215.       dbflist[m.i,m.scolnum] = ALLTRIM(STR(WLCOL(dbflist[m.i,m.cstemnum]),7,3))
  1216.       * WROWS() reports one more pixel than we want.
  1217.       dbflist[m.i,m.erownum] = ALLTRIM(STR(WROWS(dbflist[m.i,m.cstemnum]) - 1/FONTMETRIC(1),7,3))
  1218.       dbflist[m.i,m.ecolnum] = ALLTRIM(STR(WCOLS(dbflist[m.i,m.cstemnum]),7,3))
  1219.       RELEASE WINDOW (dbflist[m.i,m.cstemnum])
  1220.    ENDIF
  1221.    dbflist[m.i,m.arranged] = "Y"
  1222. ENDFOR
  1223.  
  1224. * Store relations into resource file if needed
  1225. IF TYPE("DBFLIST") <> "U" AND !rsc_stored AND m.storersc
  1226.    WAIT WINDOW "Saving window positions." NOWAIT
  1227.    DO putdbflist WITH dbflist[1,1]
  1228. ENDIF
  1229.  
  1230. * Restore environment 
  1231. POP MENU _msysmenu
  1232. SHOW WINDOW appgen
  1233. ACTIVATE WINDOW appgen
  1234.  
  1235. CLEAR READ
  1236.  
  1237. RETURN
  1238.  
  1239. *!*****************************************************************
  1240. *!
  1241. *!      Function: PUTFONTVAL
  1242. *!
  1243. *!*****************************************************************
  1244. FUNCTION putfontval
  1245. PARAMETER m.value, m.code, m.i
  1246.  
  1247. RETURN TRANFONT(m.value, m.code, WFONT(1,""), WFONT(2,""), WFONT(3,""), ;
  1248.    term(dbflist[m.i,m.thefont],1), VAL(term(dbflist[m.i,m.thefont],2)), ;
  1249.    term(dbflist[m.i,m.thefont],3) )
  1250.  
  1251. *!*****************************************************************
  1252. *!
  1253. *!      Procedure: ARREXIT
  1254. *!
  1255. *!*****************************************************************
  1256. PROCEDURE arrexit
  1257. * Exit without saving window positions
  1258. PRIVATE m.i
  1259. * Set exit flag for READ VALID--can't be PRIVATE
  1260. m.arrexflg = .T.
  1261.  
  1262. * Release all the application windows
  1263. RELEASE WINDOW ctrl
  1264. FOR m.i = 1 TO m.numareas
  1265.    IF !EMPTY(dbflist[m.i,m.cstemnum]) AND dbflist[m.i,m.cstemnum] <> '\'
  1266.       RELEASE WINDOW (dbflist[m.i,m.cstemnum])
  1267.    ENDIF
  1268. ENDFOR
  1269.  
  1270. * Restore environment 
  1271. POP MENU _msysmenu
  1272. SHOW WINDOW appgen
  1273.  
  1274. ACTIVATE WINDOW appgen
  1275.  
  1276. CLEAR READ
  1277.  
  1278. RETURN
  1279.  
  1280. FUNCTION getplat
  1281. DO CASE
  1282. CASE _MAC
  1283.    RETURN "MAC"
  1284. CASE _WINDOWS
  1285.    RETURN "WINDOWS"
  1286. CASE _DOS
  1287.    RETURN "DOS"
  1288. CASE _UNIX
  1289.    RETURN "UNIX"
  1290. OTHERWISE
  1291.    RETURN "UNKNOWN"
  1292. ENDCASE
  1293.  
  1294. *!*****************************************************************
  1295. *!
  1296. *!      Procedure: HASCHILD
  1297. *!
  1298. *!*****************************************************************
  1299. FUNCTION haschild
  1300. * Does the database at position "dbfnum" of DBFLIST have a child
  1301. * table?
  1302. parameter dbfnum
  1303. PRIVATE m.dbfnum, m.i
  1304.  
  1305. * See if another database has this one as its parent
  1306. FOR m.i = 1 TO m.numareas
  1307.    IF ALLTRIM(dbflist[m.i,m.pdbfnum]) ;
  1308.          == ALLTRIM(dbflist[m.dbfnum,m.cstemnum])
  1309.       RETURN .T.
  1310.    ENDIF
  1311. ENDFOR
  1312. RETURN .F.
  1313.  
  1314.  
  1315. *!*****************************************************************
  1316. *!
  1317. *!      Procedure: ACTWIN
  1318. *!
  1319. *!*****************************************************************
  1320. FUNCTION actwin
  1321. * Activate window wind_name
  1322.  
  1323. parameter wind_name
  1324. PRIVATE ALL
  1325. wind_name = UPPER(ALLTRIM(m.wind_name))
  1326. IF !EMPTY(m.wind_name) AND WEXIST(m.wind_name)
  1327.    ACTIVATE WINDOW (m.wind_name)
  1328. ENDIF
  1329. RETURN ''
  1330.  
  1331. *!*****************************************************************
  1332. *!
  1333. *!      Procedure: ERRSHOW
  1334. *!
  1335. *!*****************************************************************
  1336. PROCEDURE errshow
  1337. * Procedure to display an error message 
  1338.  
  1339. parameter m.messg, m.lineno
  1340. PRIVATE ALL
  1341. DO definewindow WITH 4, 70, "ALERT", 7
  1342. ACTIVATE WINDOW alert
  1343.  
  1344. SET CURSOR OFF
  1345. @ 0,0 CLEAR
  1346. @ 1,0 SAY PADC(ALLTRIM(m.messg), WCOLS())
  1347. WAIT ""
  1348. SET CURSOR ON
  1349.  
  1350. RELEASE WINDOW alert
  1351. RETURN
  1352.  
  1353. *!*****************************************************************
  1354. *!
  1355. *!      Procedure: ALERT
  1356. *!
  1357. *!*****************************************************************
  1358. PROCEDURE alert
  1359. * Display an error message, automatically sizing the message window
  1360. *    as necessary.  Semicolons in "strg" mean "new line".
  1361. PARAMETERS strg
  1362. PRIVATE m.in_talk, m.numlines, m.i, m.remain, m.in_cons
  1363.  
  1364. m.in_talk = SET('TALK')
  1365. SET TALK OFF
  1366. m.in_cons = SET('CONSOLE')
  1367.  
  1368. m.numlines = OCCURS(';',m.strg) + 1
  1369.  
  1370. DIMENSION alert_arry[m.numlines]
  1371. m.remain = m.strg
  1372. m.maxlen = 0
  1373. FOR i = 1 TO m.numlines
  1374.    IF AT(';',m.remain) > 0
  1375.       alert_arry[i] = SUBSTR(m.remain,1,AT(';',m.remain)-1)
  1376.       alert_arry[i] = CHRTRAN(alert_arry[i],';','')
  1377.       m.remain = SUBSTR(m.remain,AT(';',m.remain)+1)
  1378.    ELSE
  1379.       alert_arry[i] = m.remain
  1380.       m.remain = ''
  1381.    ENDIF
  1382.    IF LEN(alert_arry[i]) > my_scols() - 6
  1383.       alert_arry[i] = SUBSTR(alert_arry[i],1,my_scols()-6)
  1384.    ENDIF
  1385.    IF LEN(alert_arry[i]) > m.maxlen
  1386.       m.maxlen = LEN(alert_arry[i])
  1387.    ENDIF
  1388. ENDFOR
  1389.  
  1390. m.top_row = INT( (my_srows() - 4 - m.numlines) / 2)
  1391. m.bot_row = m.top_row + 3 + m.numlines
  1392.  
  1393. m.top_col = INT((my_scols() - m.maxlen - 6) / 2)
  1394. m.bot_col = m.top_col + m.maxlen + 6
  1395.  
  1396. DEFINE WINDOW alert FROM m.top_row,m.top_col TO m.bot_row,m.bot_col;
  1397.    DOUBLE COLOR SCHEME 7
  1398. ACTIVATE WINDOW alert
  1399.  
  1400. FOR m.i = 1 TO m.numlines
  1401.    @ m.i,3 SAY PADC(alert_arry[m.i],m.maxlen)
  1402. ENDFOR
  1403.  
  1404. CLEAR TYPEAHEAD
  1405. SET CONSOLE OFF
  1406. m.keycode = 0
  1407. DO WHILE m.keycode = 0
  1408.    m.keycode = INKEY(0,'HM')
  1409. ENDDO
  1410. SET CONSOLE ON
  1411.  
  1412. RELEASE WINDOW alert
  1413.  
  1414. IF m.in_talk = "ON"
  1415.    SET TALK ON
  1416. ENDIF
  1417. IF m.in_cons = "OFF"
  1418.    SET CONSOLE OFF
  1419. ENDIF
  1420.  
  1421. *!*****************************************************************
  1422. *!
  1423. *!      Procedure: APPERROR
  1424. *!
  1425. *!*****************************************************************
  1426. PROCEDURE apperror
  1427. * Simple ON ERROR routine for FoxApp application
  1428.  
  1429. PARAMETERS e_program,e_message,e_source,e_lineno,e_error
  1430. ON ERROR
  1431. m.e_source = ALLTRIM(m.e_source)
  1432. DO CASE
  1433. CASE m.e_error = 1707     && CDX not found.  Ignore it.
  1434.    RETURN
  1435. OTHERWISE
  1436.    DO alert WITH 'Line No.: '+ALLTRIM(STR(m.e_lineno,5))+';' ;
  1437.       +'Program: '+m.e_program +';' ;
  1438.       +'  Error: '+m.e_message +';' ;
  1439.       +' Source: '+IIF(LEN(m.e_source)<50,;
  1440.       m.e_source,SUBSTR(m.e_source,1,50)+'...')
  1441.  
  1442.    DO close_up
  1443. ENDCASE
  1444. RETURN
  1445.  
  1446. *!*****************************************************************
  1447. *!
  1448. *!      Procedure: APPESCAPE
  1449. *!
  1450. *!*****************************************************************
  1451. PROCEDURE appescape
  1452. * Simple ON ESCAPE routine for FoxApp application
  1453.  
  1454. PARAMETERS e_program,e_message,e_source,e_lineno,e_error
  1455. WAIT WINDOW "Escape pressed.  FoxApp is terminating." NOWAIT
  1456. =INKEY(1.5)
  1457. m.m_quitting = .T.
  1458. * Enable the Window pad
  1459. SET SKIP OF PAD _msm_windo OF _msysmenu .F.
  1460.  
  1461. CLEAR READ
  1462. DO close_up
  1463. RETURN
  1464.  
  1465. *!*****************************************************************************
  1466. *!
  1467. *!       Function: WHATSTYLE
  1468. *!
  1469. *!      Called by: ALLCHARTOGRAPHIC   (procedure in TRANSPRT.PRG)
  1470. *!               : FILLININFO         (procedure in TRANSPRT.PRG)
  1471. *!               : ITEMSINBOXES       (procedure in TRANSPRT.PRG)
  1472. *!               : GETWINDFONT        (procedure in TRANSPRT.PRG)
  1473. *!               : ADJHEIGHTANDWIDTH  (procedure in TRANSPRT.PRG)
  1474. *!
  1475. *!*****************************************************************************
  1476. FUNCTION whatstyle
  1477. PARAMETER m.stylenum
  1478. IF NOT EMPTY(m.stylenum)
  1479.    DO CASE
  1480.    CASE m.stylenum = 1
  1481.       RETURN "B"
  1482.    CASE m.stylenum = 2
  1483.       RETURN "I"
  1484.    CASE m.stylenum = 3
  1485.       RETURN "BI"
  1486.    ENDCASE
  1487. ELSE
  1488.    RETURN ""
  1489. ENDIF
  1490.  
  1491. *!*****************************************************************************
  1492. *!
  1493. *!    Procedure: FNADDQUOTES
  1494. *!
  1495. *!*****************************************************************************
  1496. FUNCTION fnaddquotes
  1497. PARAMETER m.fname
  1498.  
  1499. DO CASE
  1500. CASE INLIST(LEFT(m.fname,1), "'", '"', '[')
  1501.    RETURN m.fname
  1502. CASE AT('"', m.fname) = 0
  1503.    RETURN '"' + m.fname + '"'
  1504. CASE AT("'", m.fname) = 0
  1505.    RETURN "'" + m.fname + "'"
  1506. CASE AT("[", m.fname) = 0 AND AT("]", m.fname) = 0
  1507.    RETURN "[" + m.fname + "]"
  1508. OTHERWISE
  1509.    RETURN m.fname      
  1510. ENDCASE
  1511.  
  1512. *!*****************************************************************************
  1513. *!
  1514. *!    Procedure: MAKEALIAS
  1515. *!
  1516. *!*****************************************************************************
  1517. FUNCTION makealias
  1518. PARAMETER filname
  1519. m.filname = UPPER(ALLTRIM(m.filname))
  1520. m.filname = CHRTRAN(m.filname, ' ', '_')
  1521. m.filname = LEFT(m.filname, 10)
  1522. RETURN m.filname
  1523.  
  1524. *!*****************************************************************************
  1525. *!
  1526. *!    Procedure: ISWIZ
  1527. *!
  1528. *!*****************************************************************************
  1529. FUNCTION iswiz
  1530. PARAMETER strg
  1531. * Was this screen created by a FoxPro wizard?
  1532. RETURN IIF("*~ WIZARDSCREEN" $ UPPER(m.strg), .T., .F.)
  1533.  
  1534. *!*****************************************************************************
  1535. *!
  1536. *!    Function: MY_SROWS
  1537. *!
  1538. *!*****************************************************************************
  1539. FUNCTION my_srows
  1540. IF _MAC
  1541.    RETURN (SYSMETRIC(2) - SYSMETRIC(20) ) / FONTMETRIC(1,m.g_dfltfface, m.g_dfltfsize, m.g_dfltfstyle)
  1542. ELSE
  1543.    RETURN SROWS()
  1544. ENDIF   
  1545.  
  1546. *!*****************************************************************************
  1547. *!
  1548. *!    Function: MY_SCOLS
  1549. *!
  1550. *!*****************************************************************************
  1551. FUNCTION my_scols
  1552. DO CASE
  1553. CASE _MAC
  1554.    RETURN SYSMETRIC(1) / FONTMETRIC(6,m.g_dfltfface, m.g_dfltfsize, m.g_dfltfstyle)
  1555. CASE _DOS
  1556.    RETURN SCOLS()
  1557. OTHERWISE
  1558.    RETURN SROWS()        && ??! Original code...is this intended? -jla
  1559. ENDCASE   
  1560.  
  1561.  
  1562. PROCEDURE DbfNameWhen
  1563. * WHEN clause from m.dbfname get in appscx
  1564. *------------------------------------------------------------------
  1565. m.origname = m.dbfname
  1566. IF !EMPTY(m.dbfname) AND _MAC
  1567.    m.dbfname = SYS(2027, m.dbfname)
  1568. ENDIF   
  1569. m.dbfname  = PADR(m.dbfname,m.apppathlen)
  1570. m.skipdbfbut = .T.
  1571. SHOW GETS
  1572. SET CURSOR ON
  1573. RETURN .T.
  1574.  
  1575.  
  1576. PROCEDURE DbfNameValid
  1577. * VALID clause from m.dbfname get in appscx
  1578. *------------------------------------------------------------------
  1579. *  #NAME dbfvalid
  1580.  
  1581. m.dbfname = UPPER(ALLTRIM(m.dbfname))
  1582. IF m.dbfname == m.origname
  1583.    * do nothing--make sure comparison is "==" however. 
  1584. ELSE
  1585.    * Database name changed.  Check resource file again.
  1586.    rsc_check = .F.
  1587. ENDIF
  1588.  
  1589. SET CURSOR OFF
  1590.  
  1591. IF !EMPTY(m.dbfname)
  1592.    IF _MAC
  1593.      m.dbfname = SYS(2027,FULLPATH(m.dbfname))
  1594.    ELSE
  1595.      m.dbfname = FULLPATH(m.dbfname)
  1596.    ENDIF
  1597. ENDIF
  1598.  
  1599. SHOW GETS
  1600. DO CASE
  1601. CASE EMPTY(juststem(m.dbfname)) AND !EMPTY(m.dbfname)
  1602.    WAIT WINDOW "Invalid database name."
  1603.    RETURN 0
  1604. CASE (EMPTY(justext(m.dbfname)) OR justext(m.dbfname) = 'DBF')   ;
  1605.       AND (justfname(m.dbfname) >= 'A' AND justfname(m.dbfname) <= 'Z') ;
  1606.       AND LEN(justfname(m.dbfname))<=1
  1607.    * Don't allow single letter database names--they get confused with areas
  1608.    WAIT WINDOW "Invalid database name."
  1609.    RETURN 0
  1610. CASE INLIST(justext(m.dbfname),'SCX','SCT','SPR')
  1611.    WAIT WINDOW "A screen file name is not allowed here."
  1612.    RETURN 0
  1613. CASE INLIST(justext(m.dbfname),'MNX','MNT','MPR')
  1614.    WAIT WINDOW "A menu file name is not allowed here."
  1615.    RETURN 0
  1616. OTHERWISE
  1617.    IF !('.' $ justfname(m.dbfname)) AND !EMPTY(m.dbfname)
  1618.       m.dbfname = forceext(m.dbfname,'DBF')
  1619.    ENDIF
  1620.  
  1621.    dbfname = UPPER(ALLTRIM(m.dbfname))
  1622.    IF !EMPTY(m.dbfname)
  1623.       m.dbfalias = opendbf(m.dbfname)
  1624.       IF EMPTY(m.scxname)
  1625.          m.scxname = forceext(m.dbfname,'SCX')
  1626.       ENDIF
  1627.    ENDIF
  1628.  
  1629.    skipdbfbut = .F.
  1630.  
  1631.    * Poke this database into the first position of DBFLIST
  1632.    IF TYPE('DBFLIST') <> 'U'
  1633.       dbflist[1,m.cstemnum] = makealias(juststem(m.dbfname))
  1634.    ENDIF
  1635.  
  1636.    SHOW GETS
  1637.    RETURN .T.
  1638. ENDCASE
  1639.  
  1640.  
  1641. PROCEDURE ListDbfValid
  1642. * VALID clause from m.Listdbf button in appscx
  1643. *------------------------------------------------------------------
  1644.  
  1645. IF UPPER(ALLTRIM(m.dbfname)) <> UPPER(ALLTRIM(m.origname))
  1646.    m.rsc_check = .F.
  1647. ENDIF
  1648.  
  1649. m.origname = m.dbfname
  1650. CLOSE DATABASES
  1651. m.dbfname = GETFILE('DBF','Database name:')
  1652. IF EMPTY(m.dbfname)
  1653.    m.dbfname = m.origname
  1654. ELSE
  1655.     IF _MAC
  1656.         m.dbfname = SYS(2027, m.dbfname)
  1657.     ENDIF
  1658.    =opendbf(m.dbfname)
  1659.    IF EMPTY(m.scxname)
  1660.       IF _MAC
  1661.         m.scxname = SYS(2027,forceext(m.dbfname,'SCX'))
  1662.       ELSE
  1663.         m.scxname = forceext(m.dbfname,'SCX')
  1664.       ENDIF
  1665.    ENDIF
  1666. ENDIF
  1667.  
  1668. * Poke this database into the first position of DBFLIST
  1669. IF TYPE('DBFLIST') <> 'U'
  1670.    dbflist[1,m.cstemnum] = makealias(juststem(m.dbfname))
  1671. ENDIF
  1672.  
  1673. SHOW GETS
  1674. RETURN .T.
  1675.  
  1676.  
  1677. PROCEDURE AddDbfValid
  1678. * VALID clause from m.adddbf button in appscx
  1679. *------------------------------------------------------------------
  1680.  
  1681. IF EMPTY(m.dbfname)
  1682.    m.dbfname = PUTFILE('Database name:','','DBF')
  1683.    IF EMPTY(m.dbfname)
  1684.       RETURN .F.   && don't do anything
  1685.    ENDIF
  1686. ENDIF
  1687. IF !FILE(m.dbfname)
  1688.    * This window controls the colors used by CREATE 
  1689.    DEFINE WINDOW mywin FROM INT((srow()-20)/2),INT((scol()-71)/2);
  1690.       TO INT((srow()-20)/2)+19,INT((scol()-71)/2)+70 ;
  1691.       FLOAT CLOSE SHADOW MINIMIZE SYSTEM COLOR SCHEME 8
  1692.    ACTIVATE WINDOW mywin NOSHOW
  1693.  
  1694.    CREATE (m.dbfname)
  1695.    DEACTIVATE WINDOW mywin
  1696.    RELEASE WINDOW mywin
  1697. ELSE    && this shouldn't be possible since the control should be disabled
  1698.    m.dname = opendbf(m.dbfname)
  1699.    IF !EMPTY(m.dname)
  1700.       MODIFY STRUCTURE
  1701.    ENDIF
  1702.    SHOW GET adddbf DISABLE
  1703.    SHOW GET moddbf ENABLE
  1704. ENDIF
  1705. SHOW GETS
  1706. RETURN .T.
  1707.  
  1708.  
  1709. PROCEDURE ModDbfValid
  1710. * VALID clause from m.moddbf button in appscx
  1711. *------------------------------------------------------------------
  1712.  
  1713. IF !EMPTY(m.dbfname)
  1714.    IF !EMPTY(opendbf(m.dbfname))
  1715.       MODIFY STRUCTURE
  1716.    ELSE
  1717.       SHOW GET moddbf DISABLE
  1718.       RETURN -2
  1719.    ENDIF
  1720. ENDIF
  1721. RETURN .T.
  1722.  
  1723.  
  1724. PROCEDURE OtherValid
  1725. * VALID clause from m.other button in appscx ("Related...")
  1726. *------------------------------------------------------------------
  1727.  
  1728. IF _MAC AND !FILE(m.dbfname)
  1729.    WAIT WINDOW "Could not find "+TRIM(m.dbfname) NOWAIT
  1730.    RETURN
  1731. ENDIF
  1732.  
  1733. DO opendbf WITH m.dbfname
  1734.  
  1735. DO dbfselec.spr
  1736.  
  1737. * Leave the main database open when through with picking subsidiary
  1738. *   databases.
  1739. m.dbfalias = opendbf(m.dbfname)
  1740. IF relateddbfs()
  1741.    SHOW GET arrange ENABLE
  1742. ELSE
  1743.    SHOW GET arrange DISABLE
  1744. ENDIF      
  1745.  
  1746.  
  1747. PROCEDURE ScxNameWhen
  1748. * WHEN clause from m.scxname get in appscx
  1749. *------------------------------------------------------------------
  1750. m.scxname = PADR(m.scxname,m.apppathlen)
  1751. SHOW GET modscx DISABLE
  1752. SHOW GET addscx DISABLE
  1753. SET CURSOR ON
  1754. RETURN .T.
  1755.  
  1756.  
  1757. PROCEDURE ScxNameValid
  1758. * VALID clause from m.scxname get in appscx
  1759. *------------------------------------------------------------------
  1760.  
  1761. SET CURSOR OFF
  1762. m.scxname = UPPER(ALLTRIM(m.scxname))
  1763. IF !EMPTY(m.scxname)
  1764.    m.scxname = FULLPATH(m.scxname)
  1765. ENDIF
  1766.  
  1767. scxname = ALLTRIM(m.scxname)
  1768. IF !('.' $ justfname(m.scxname)) AND !EMPTY(justfname(m.scxname))
  1769.    scxname = forceext(m.scxname,'SCX')
  1770. ENDIF
  1771. m.scxname = UPPER(m.scxname)
  1772.  
  1773. DO CASE
  1774. CASE !EMPTY(m.scxname) AND EMPTY(juststem(m.scxname)) 
  1775.    WAIT WINDOW "Invalid screen name."
  1776.    RETURN 0
  1777. ENDCASE
  1778. IF _MAC
  1779.   m.scxname = SYS(2027, m.scxname)
  1780. ENDIF
  1781. SHOW GETS
  1782.  
  1783.  
  1784. PROCEDURE ListScxValid
  1785. * VALID clause from m.Listscx button in appscx
  1786. *------------------------------------------------------------------
  1787. m.origname = m.scxname
  1788. m.scxname = GETFILE('SCX','Screen file name:')
  1789. IF EMPTY(scxname)
  1790.    m.scxname = m.origname
  1791. ELSE
  1792.    IF _MAC
  1793.      m.scxname = SYS(2027, m.scxname)
  1794.    ENDIF
  1795. ENDIF
  1796. SHOW GETS
  1797. RETURN .T.
  1798.  
  1799.  
  1800. PROCEDURE AddScxValid
  1801. * VALID clause from m.addscx button in appscx
  1802. *------------------------------------------------------------------
  1803. IF EMPTY(m.scxname)
  1804.    m.scxname = PUTFILE('Screen file name','','SCX')
  1805.    IF EMPTY(m.scxname)
  1806.       m.scxname = 'UNTITLED.SCX'
  1807.    ENDIF
  1808. ELSE
  1809.    IF FILE(m.scxname)
  1810.       MODIFY SCREEN (m.scxname)
  1811.    ELSE
  1812.       DO createscx
  1813.    ENDIF
  1814. ENDIF
  1815. SHOW GETS
  1816. RETURN .T.
  1817.  
  1818.  
  1819. PROCEDURE ModScxWhen
  1820. * WHEN clause from m.modscx button in appscx
  1821. *------------------------------------------------------------------
  1822. IF !FILE(m.scxname)
  1823.    WAIT WINDOW 'Creating screen file' NOWAIT
  1824.    DO createscx
  1825. ENDIF
  1826. RETURN .T.
  1827.  
  1828. PROCEDURE ModScxValid
  1829. * VALID clause from m.modscx button in appscx
  1830. *------------------------------------------------------------------
  1831. IF FILE(m.scxname) AND !EMPTY(m.scxname)
  1832.    MODIFY SCREEN (m.scxname)
  1833. ELSE
  1834.    WAIT WINDOW "Creating screen" NOWAIT
  1835.    DO createscx
  1836. ENDIF
  1837. SHOW GET addscx DISABLE
  1838. SHOW GETS
  1839. RETURN .T.
  1840.  
  1841.  
  1842. PROCEDURE ArrangeValid
  1843. * VALID clause from m.arrange button in appscx
  1844. *------------------------------------------------------------------
  1845. PRIVATE m.wiz_screen, m.tree_up, m.arrexflg, m.in_area, m.maxcapt, m.maxlen, m.maxheight, m.start_row, ;
  1846.    m.start_col, m.sheight, m.swidth, m.ws_col, m.ws_row, m.we_row, m.we_col
  1847.  
  1848. DO opendbf WITH m.dbfname
  1849.  
  1850. PUSH MENU _msysmenu
  1851.  
  1852. RELEASE arrexflg   && causes upcoming Foundation read to terminate
  1853. PUBLIC  arrexflg
  1854. m.arrexflg = .F.
  1855.  
  1856. m.tree_up = WVISIBLE('treewind')
  1857.  
  1858. HIDE WINDOW appgen
  1859. IF WEXIST('dbfselec')
  1860.    HIDE WINDOW dbfselec
  1861. ENDIF
  1862. IF WEXIST('treewind')
  1863.    HIDE WINDOW treewind
  1864. ENDIF
  1865.  
  1866. DEFINE PAD a_save OF _msysmenu PROMPT "\<Save Arrangement!" KEY ALT+S,"" COLOR SCHEME 3
  1867. DEFINE PAD a_cancel OF _msysmenu PROMPT "\<Cancel!" KEY ALT+C,"" COLOR SCHEME 3
  1868. ON SELECTION PAD a_save   OF _msysmenu DO arrsave
  1869. ON SELECTION PAD a_cancel OF _msysmenu DO arrexit
  1870.  
  1871. RELEASE PAD _MSM_SYSTM  OF _msysmenu
  1872. RELEASE PAD _MSM_FILE   OF _msysmenu
  1873. RELEASE PAD _MSM_EDIT   OF _msysmenu
  1874. RELEASE PAD _MSM_DATA   OF _msysmenu
  1875. RELEASE PAD _MSM_RECRD  OF _msysmenu
  1876. RELEASE PAD _MSM_PROG   OF _msysmenu
  1877. RELEASE PAD _MSM_WINDO  OF _msysmenu
  1878. RELEASE PAD RUN         OF _msysmenu
  1879.  
  1880. * Save the screen and start the arranging from a blank screen
  1881. SAVE SCREEN TO arr_scrn
  1882. ACTIVATE SCREEN
  1883. CLEAR
  1884.  
  1885. m.wiz_screen = .F.
  1886. m.in_area = SELECT()
  1887. SELECT 0
  1888. USE (m.scxname) AGAIN
  1889. LOCATE FOR platform = m.app_platform AND objtype = 1
  1890. IF FOUND()
  1891.    m.wiz_screen = iswiz(setupcode)
  1892. ENDIF
  1893. USE
  1894. SELECT (m.in_area)
  1895.  
  1896. IF !m.wiz_screen
  1897.    * See how wide and tall the actual control panel is.
  1898.    m.dname = addbs(m.foxappdir)+'screens\appctrl.scx'
  1899.    IF FILE(m.dname)
  1900.       m.in_area = SELECT()
  1901.       SELECT 0
  1902.       USE (dname) AGAIN ALIAS ctrl
  1903.       LOCATE FOR platform = m.app_platform AND objtype = 1
  1904.       IF FOUND()
  1905.          m.ctrl_width     = ctrl.width
  1906.          m.ctrl_height    = ctrl.height
  1907.       ELSE
  1908.          m.ctrl_width = 73.167    && go with default values then
  1909.          m.ctrl_height = 3.846
  1910.       ENDIF
  1911.       USE
  1912.       SELECT (m.in_area)
  1913.    ELSE
  1914.       m.ctrl_width = 73.167
  1915.       m.ctrl_height = 3.846
  1916.    ENDIF
  1917.    m.ctrlrow = MAX(0,m.ctrlrow)
  1918.    m.ctrlcol = MAX(0,m.ctrlcol)
  1919.  
  1920.    * Define window for control panel
  1921.    DEFINE WINDOW ctrl ;
  1922.       AT m.ctrlrow,m.ctrlcol ;
  1923.       SIZE m.ctrl_height, m.ctrl_width ;
  1924.       TITLE "Control panel" ;
  1925.       HALF ;
  1926.       FONT m.g_dfltfface, m.g_dfltfsize ;
  1927.       STYLE m.g_dfltfstyle ;
  1928.       FLOAT NOZOOM NOCLOSE
  1929.    ACTIVATE WINDOW ctrl
  1930. ENDIF
  1931.  
  1932. * Figure out how tall and wide the main database screen will be
  1933. IF EMPTY(m.scxname) OR !FILE(m.scxname)
  1934.    * If a screen hasn't been defined yet, look at the database fields
  1935.    SELECT (dbflist[1,m.cstemnum])
  1936.    m.maxlen  = 0
  1937.    m.maxheight = FCOUNT() + 4
  1938.    m.maxcapt = 0
  1939.    FOR m.i = 1 TO FCOUNT()
  1940.       m.maxlen  = MAX(m.maxlen,FSIZE(FIELD(m.i)))  && max field length
  1941.       m.maxcapt = MAX(m.maxcapt,LEN(FIELD(m.i))+2) && max field name length
  1942.    ENDFOR
  1943.    m.maxlen = m.maxlen + m.maxcapt + 4   && allow for borders
  1944.    m.sheight   = m.maxheight
  1945.    m.swidth    = m.maxlen
  1946. ELSE         && otherwise, look to the SCX itself
  1947.    SELECT 0
  1948.    USE (m.scxname) AGAIN ALIAS fxscxnme
  1949.    LOCATE FOR platform = m.app_platform AND Objtype = 1
  1950.    IF FOUND()
  1951.       m.dbf_fontface  = fxscxnme.fontface
  1952.       m.dbf_fontsize  = fxscxnme.fontsize
  1953.       m.dbf_fontstyle = fxscxnme.fontstyle
  1954.       m.sheight       = fxscxnme.height
  1955.       m.swidth        = fxscxnme.width
  1956.    ELSE
  1957.       m.platformword = IIF(_MAC,"Macintosh", IIF(_DOS,"DOS","Windows"))
  1958.       WAIT WINDOW "FoxApp couldn't find any " + m.platformword + ;
  1959.                   " records for this screen."
  1960. *      WAIT WINDOW "FoxApp couldn't find any " + ;
  1961. *       IIF(_MAC,"Macintosh","Windows"  + " records for this screen.")
  1962.  
  1963.       m.sheight = 21    && was 23, changed by J. Alden for DOS port
  1964.       m.swidth = 74
  1965.    ENDIF
  1966.    USE
  1967. ENDIF
  1968.  
  1969. * Determine position for main database window and define window
  1970. DO CASE
  1971. CASE UPPER(dbflist[1,m.arranged]) = "N"
  1972.    * No screen position yet defined for the main database.  Center it,
  1973.    * unless there are lots of related databases.  If there are, put
  1974.    * it closer to the top of the screen.
  1975.    IF m.nextdbf < 3  && just one database used in app
  1976.       m.start_row = MAX(INT(my_srows()/2-m.sheight/2),0)
  1977.       m.start_col = MAX(INT(my_scols()/2-m.swidth/2),0)
  1978.    ELSE
  1979.       m.start_row = 1
  1980.       m.start_col = MAX(INT(my_scols()/2-m.swidth/2),0)
  1981.    ENDIF
  1982. OTHERWISE   && show it where the user put it last
  1983.    m.start_row    = VAL(dbflist[1,m.srownum])
  1984.    m.start_col    = VAL(dbflist[1,m.scolnum])
  1985. ENDCASE
  1986. m.start_row = MAX(0,m.start_row)
  1987. m.start_col = MAX(0,m.start_col)
  1988.  
  1989. * Define the blank window for the main database
  1990. DEFINE WINDOW (dbflist[1,m.cstemnum]) ;
  1991.    AT m.start_row,m.start_col ;
  1992.    SIZE m.sheight,m.swidth ;
  1993.    TITLE dbflist[1,m.cstemnum] ;
  1994.    FONT m.g_dfltfface, m.g_dfltfsize ;
  1995.    STYLE m.g_dfltfstyle ;
  1996.    NOGROW FLOAT NOZOOM NOCLOSE ;
  1997.    COLOR SCHEME 1
  1998.  
  1999. * Define windows for child databases
  2000. FOR m.i = 2 TO m.numareas
  2001.    IF !EMPTY(dbflist[m.i,m.cstemnum]) AND dbflist[m.i,m.cstemnum] <> '\'
  2002.       IF dbflist[m.i,m.arranged] = "N"
  2003.          * Try to place browse windows immediately beneath main screen
  2004.          m.win_height = 8      && minimum height of a BROWSE window
  2005.          IF m.start_row + m.sheight + (m.i-2)*(m.win_height+1) + 2 < my_srows() - 3
  2006.             m.ws_row = m.start_row + m.sheight + (m.i-2)*(m.win_height+1) + 2
  2007.             m.ws_col = 1
  2008.             m.we_row = m.win_height
  2009.             m.we_col = 74                     && width
  2010.          ELSE     && put the browse windows in the upper left of the screen
  2011.             m.ws_row = m.i
  2012.             m.ws_col = m.i
  2013.             m.we_row = MIN(m.win_height,my_srows()-m.ws_row-1)   && height
  2014.             m.we_col = 74                     && width
  2015.          ENDIF
  2016.       ELSE
  2017.          m.fontstrg = dbflist[m.i,m.thefont]
  2018.          m.ws_row = VAL(dbflist[m.i,m.srownum])
  2019.          m.ws_col = VAL(dbflist[m.i,m.scolnum])
  2020.          m.we_row = VAL(dbflist[m.i,m.erownum])
  2021.          m.we_col = VAL(dbflist[m.i,m.ecolnum])
  2022.  
  2023.       ENDIF
  2024.       DEFINE WINDOW (dbflist[m.i,m.cstemnum]) ;
  2025.          AT m.ws_row,m.ws_col ;
  2026.          SIZE m.we_row,m.we_col ;
  2027.          SYSTEM ;
  2028.          TITLE dbflist[m.i,m.cstemnum] ;
  2029.          GROW FLOAT NOZOOM NOCLOSE ;
  2030.          HALF ;
  2031.          FONT m.g_dfltfface, m.g_dfltfsize ;
  2032.          STYLE m.g_dfltfstyle ;
  2033.          COLOR SCHEME 10
  2034.       ACTIVATE WINDOW (dbflist[m.i,m.cstemnum])
  2035.    ENDIF
  2036. ENDFOR
  2037.  
  2038. * Activate the main window and let user move things around.
  2039. ACTIVATE WINDOW (dbflist[1,m.cstemnum])
  2040.  
  2041. * The foundation read terminates when the user selects "Save" or "Exit" from the menu
  2042. READ VALID m.arrexflg
  2043.  
  2044. IF m.tree_up AND WEXIST('treewind')
  2045.    SHOW WINDOW treewind
  2046. ENDIF
  2047. RELEASE arrexflg, ws_row, ws_col, we_row, we_col, i, tree_up, win_height, sheight, swidth
  2048.  
  2049. RESTORE SCREEN FROM arr_scrn
  2050.  
  2051.  
  2052. PROCEDURE GenerateValid
  2053. * VALID clause from m.generate button in appscx
  2054. *------------------------------------------------------------------
  2055. #define fa_european 0
  2056. PRIVATE m.win_string, m.dname, m.quoted, m.sc_file, m.i, m.j, m.wizscreen, m.dest, m.msg, ;
  2057.    m.c_path, m.userapp_dir, m.valid_name
  2058. m.wizscreen = .F.   && assume it isn't a screen wizard screen--they have their own ctrl panel
  2059. IF m.generate = 1
  2060.  
  2061.    IF !FILE(m.dbfname) OR EMPTY(m.dbfname)
  2062.       DO CASE
  2063.       CASE EMPTY(m.dbfname)
  2064.          m.msg = "No table name entered.  Enter one and try again."
  2065.          m.dest = -9
  2066.       CASE !FILE(m.dbfname)
  2067.          m.msg = "Could not find "+justfname(m.dbfname)
  2068.          m.dest = -9
  2069.       OTHERWISE
  2070.          * This code shouldn't exectute
  2071.          m.dest = -9
  2072.          m.msg = "Error generating application"
  2073.       ENDCASE
  2074.       WAIT WINDOW m.msg NOWAIT
  2075.       SHOW GETS
  2076.       RETURN m.dest   && bounce out of generate and return to the dbfname field
  2077.    ENDIF
  2078.  
  2079.    SET CURSOR OFF
  2080.  
  2081.    * Create a default input screen if the one the user specified doesn't
  2082.    * exist.
  2083.    IF EMPTY(m.scxname)
  2084.       m.scxname = forceext(m.dbfname,'SCX')
  2085.    ENDIF
  2086.    IF !FILE(m.scxname)
  2087.       DO createscx
  2088.    ENDIF
  2089.  
  2090.    CLOSE DATABASES
  2091.    m.scxname  = UPPER(ALLTRIM(m.scxname))
  2092.    m.dbfname  = UPPER(ALLTRIM(m.dbfname))
  2093.    m.mnuname  = UPPER(ALLTRIM(m.mnuname))
  2094.  
  2095.    SET CURSOR ON
  2096.  
  2097.    * Note the current directory and path
  2098.    m.c_path = SET('DEFAULT') + CURDIR()
  2099.  
  2100.    m.appfile = forceext(m.scxname,'APP')
  2101.    m.userapp_dir = addcolon(justpath(m.scxname))
  2102.    SET DEFAULT TO (m.userapp_dir)
  2103.    RELEASE m.userapp_dir
  2104.  
  2105.    m.mpoint = SET("POINT")
  2106.    SET POINT TO "."
  2107.  
  2108.    m.valid_name = .F.
  2109.    DO WHILE !m.valid_name
  2110.       m.appfile = PUTFILE('Name your application:',forceext(m.appfile,'APP'),'APP')
  2111.       DO CASE
  2112.       CASE UPPER(ALLTRIM(justfname(m.appfile))) == 'FOXAPP.APP'
  2113.          DO ALERT WITH "I named my program FoxApp.  You have to name yours something else."
  2114.          m.valid_name = .F.
  2115.       OTHERWISE
  2116.          m.valid_name = .T.
  2117.       ENDCASE
  2118.    ENDDO
  2119.    RELEASE m.valid_name
  2120.  
  2121.    IF EMPTY(m.appfile)   && user pressed 'cancel'.  Return to top screen.
  2122.       SHOW GETS
  2123.    ELSE                  && time to create the APP
  2124.       SET CONSOLE OFF
  2125.  
  2126.       * Store relations into resource file if needed
  2127.       IF TYPE("DBFLIST") <> "U" AND !m.rsc_stored AND m.storersc
  2128.          WAIT WINDOW "Saving database relations and window positions." NOWAIT
  2129.          DO putdbflist WITH dbflist[1,1]
  2130.       ENDIF
  2131.  
  2132.       m.win_string = "Generating application "+PROPER(juststem(m.appfile))+'.'
  2133.       WAIT WINDOW m.win_string NOWAIT
  2134.       HIDE WINDOW (WOUTPUT())
  2135.       RELEASE m.win_string
  2136.  
  2137.       * tmfname is the name of the scaffolding program that pulls all the
  2138.       * FoxApp application modules together.
  2139.       m.tmfname = addbs(justpath(m.appfile))+'scaffold.prg'
  2140.       SET TEXTMERGE TO (m.tmfname)
  2141.  
  2142.       SET TEXTMERGE ON
  2143.       IF _MAC OR _WINDOWS
  2144.          \\*      +---------------------------------------------------------+
  2145.          \*       |                                                         |
  2146.          \*       | <<DATE()>>               scaffold.prg            <<TIME()>> |
  2147.          \*       |                                                         |
  2148.          \*       +---------------------------------------------------------+
  2149.          \*       |                                                         |
  2150.          \*       | Description:                                            |
  2151.          \*       | This program was automatically generated by FoxApp.     |
  2152.          \*       |                                                         |
  2153.          \*       +---------------------------------------------------------+
  2154.       ELSE
  2155.          \\*       â•“─────────────────────────────────────────────────────────╖
  2156.          \*       â•‘                                                         â•‘
  2157.          \*       â•‘ <<DATE()>>               scaffold.prg            <<TIME()>> â•‘
  2158.          \*       â•‘                                                         â•‘
  2159.          \*       â•Ÿâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•¢
  2160.          \*       â•‘                                                         â•‘
  2161.          \*       â•‘ Description:                                            â•‘
  2162.          \*       â•‘ This program was automatically generated by FoxApp.     â•‘
  2163.          \*       â•‘                                                         â•‘
  2164.          \*       â•™â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•œ
  2165.       ENDIF
  2166.       \*
  2167.       \*       To run this application, type DO <<UPPER(justfname(m.appfile))>>
  2168.       \*
  2169.       \* Set up runtime environment
  2170.       \CREATE VIEW appview
  2171.       \SET TALK OFF
  2172.       \PUSH MENU _msysmenu
  2173.       \PUSH KEY CLEAR
  2174.       \fxapp_error = ON('ERROR')
  2175.       \fxapp_esc   = ON('ESCAPE')
  2176.  
  2177.       \SET SAFETY OFF
  2178.       \SAVE MACROS TO foxapp
  2179.       \SET SAFETY ON
  2180.       \SET DELETED ON
  2181.       \SET ESCAPE OFF
  2182.       \SET STEP OFF
  2183.       \SET ECHO OFF
  2184.       \SET PROCEDURE TO appproc.prg
  2185.       \SET CURSOR ON
  2186.  
  2187.       \m.set_point = SET("POINT")
  2188.  
  2189.       #IF fa_european
  2190.       \SET POINT TO ","
  2191.       #endif
  2192.  
  2193.       \CLOSE DATABASES
  2194.       \ON ERROR DO apperror WITH PROGRAM(),MESSAGE(),MESSAGE(1),LINENO(),ERROR()
  2195.       \
  2196.       \IF _WINDOWS OR _MAC
  2197.       \   * Store current screen font and set it to something reasonable.
  2198.       \   m.scrn_font   = WFONT(1,"")
  2199.       \   m.scrn_fsize  = WFONT(2,"")
  2200.       \   m.scrn_fstyle = WFONT(3,"")
  2201.       \   MODIFY WINDOW SCREEN FONT "<<m.g_dfltfface>>",<<m.g_dfltfsize>> STYLE "<<m.g_dfltfstyle>>"
  2202.       \ENDIF
  2203.       \
  2204.       \IF TYPE("BAILOUT") <> "U"
  2205.       \   RELEASE m.bailout
  2206.       \ENDIF
  2207.       \IF TYPE("DBFNAME") <> "U"
  2208.       \   RELEASE m.dbfname
  2209.       \ENDIF
  2210.       \IF TYPE("WIN_NAME") <> "U"
  2211.       \   RELEASE m.win_name
  2212.       \ENDIF
  2213.       \IF TYPE("FILT_EXPR") <> "U"
  2214.       \   RELEASE m.filt_expr
  2215.       \ENDIF
  2216.       \IF TYPE("SRCHTERM") <> "U"
  2217.       \   RELEASE m.srchterm
  2218.       \ENDIF
  2219.       IF m.regen
  2220.          \regen = .T.   && use SPR/MPR files instead of PRGs
  2221.          \EXTERNAL SCREEN    getdest, getorder, appabout, ;
  2222.          \                    appsrch, prtopts, prtsetup
  2223.       ELSE
  2224.          \regen = .F.
  2225.          \EXTERNAL PROCEDURE getdest, getorder, appabout, ;
  2226.          \                    appsrch, prtopts, prtsetup
  2227.       ENDIF
  2228.       \
  2229.       \PUBLIC bailout, dbfname, win_name, wiz_screen, filt_expr, srchterm
  2230.       \m.bailout = .F.
  2231.       \m.dbfname = "<<m.dbfname>>"     && database name
  2232.       \m.qprpath = justpath(m.dbfname) && query file path
  2233.       \m.filt_expr = ""                && filter expression, if any
  2234.       \m.srchterm = SPACE(60)          && search term
  2235.       \m.win_name = ""                 && name assigned below
  2236.       \m.wiz_screen = .F.              && assume false for now
  2237.       \
  2238.       \* Define constants for addressing DBFLIST
  2239.       \m.numareas   = <<m.numareas>>
  2240.       \m.numcols    = <<m.numcols>>
  2241.       \m.cstemnum   = <<m.cstemnum>>
  2242.       \m.relstrnum  = <<m.relstrnum>>
  2243.       \m.pfldnum    = <<m.pfldnum>>
  2244.       \m.cfldnum    = <<m.cfldnum>>
  2245.       \m.cdbfnum    = <<m.cdbfnum>>
  2246.       \m.pdbfnum    = <<m.pdbfnum>>
  2247.       \m.srownum    = <<m.srownum>>
  2248.       \m.scolnum    = <<m.scolnum>>
  2249.       \m.erownum    = <<m.erownum>>
  2250.       \m.ecolnum    = <<m.ecolnum>>
  2251.       \m.arranged   = <<m.arranged>>
  2252.       \m.thefont    = <<m.thefont>>
  2253.       \m.cascadenum = <<m.cascadenum>>
  2254.       \m.ctrlrow    = <<INT(m.ctrlrow)>>
  2255.       \m.ctrlcol    = <<INT(m.ctrlcol)>>
  2256.       \m.nextdbf    = <<m.nextdbf>>
  2257.       \DO DefineDbf                    && define the DBFLIST array
  2258.       \
  2259.       \
  2260.       \* Summon the main application menu
  2261.       m._mname = FNAddQuotes(forceext(juststem(m.mnuname),IIF(regen,'MPR','PRG')))
  2262.       \DO <<m._mname>>
  2263.       \
  2264.       \* Open the main database
  2265.       \m.stem = makealias(juststem(m.dbfname))
  2266.       \IF USED(m.stem)
  2267.       \   SELECT (m.stem)
  2268.       \ELSE
  2269.       \   SELECT 0
  2270.       \   IF !FILE(m.dbfname)
  2271.       \      m.dbfname = GETFILE('DBF','Please locate the '+JustStem(m.dbfname)+' database')
  2272.       \   ENDIF
  2273.       \   IF EMPTY(m.dbfname) OR !FILE(m.dbfname)
  2274.       \      DO alert WITH "The "+m.stem+" database could not be found."
  2275.       \      DO cleanup
  2276.       \      RETURN
  2277.       \   ELSE
  2278.       \      USE (m.dbfname)
  2279.       \   ENDIF
  2280.       \ENDIF
  2281.       \* Make sure the index exists and is hooked up
  2282.       \IF EMPTY(CDX(1))
  2283.       \   IF !FILE(forceext(m.dbfname,'CDX'))
  2284.       \      DO invert WITH m.dbfname
  2285.       \   ELSE
  2286.       \      SET INDEX TO (forceext(m.dbfname,'CDX'))
  2287.       \   ENDIF
  2288.       \ENDIF
  2289.       \SET ORDER TO 1
  2290.       \
  2291.       \IF RECCOUNT() = 0
  2292.       \   APPEND BLANK
  2293.       \ELSE
  2294.       \   IF RECCOUNT() < 10
  2295.       \      COUNT FOR !DELETED() TO notdel
  2296.       \      IF m.notdel = 0
  2297.       \         APPEND BLANK  && all records were deleted!
  2298.       \      ENDIF
  2299.       \   ENDIF
  2300.       \ENDIF
  2301.       \GOTO TOP
  2302.       \
  2303.       \CLEAR
  2304.  
  2305.       m.sc_file = LOWER(forceext(juststem(m.scxname),'SPR'))
  2306.  
  2307.       * Force user screen into a window and figure out its size
  2308.       m.vcoord = 0
  2309.       m.hcoord = 0
  2310.       IF FILE(m.scxname)
  2311.          SELECT 0
  2312.          USE (m.scxname) ALIAS scrnfile
  2313.          COUNT FOR UPPER(ALLTRIM(platform)) == m.app_platform TO m.platcnt
  2314.          IF platcnt = 0
  2315.             m.platword = IIF(_MAC,"Macintosh",IIF(_DOS,"DOS","Windows"))
  2316.             WAIT WINDOW m.scxname + " does not contain " ;
  2317.                + m.platword + " records."
  2318. *            WAIT WINDOW m.scxname + " does not contain " ;
  2319. *               +IIF(_MAC,"Macintosh","Windows")+" records."
  2320.             RETURN .F.
  2321.          ENDIF
  2322.  
  2323.          LOCATE FOR objtype == 1 ;
  2324.             AND UPPER(ALLTRIM(platform)) == m.app_platform
  2325.          IF FOUND()
  2326.             m.win_name = makealias(UPPER(ALLTRIM(scrnfile.name)))
  2327.             m.wizscreen = iswiz(setupcode)
  2328.             IF !m.wizscreen
  2329.                * Make sure that user screen goes into a window
  2330.                IF EMPTY(scrnfile.name)
  2331.                   win_msg = "Putting "+juststem(m.scxname)+" screen into window."
  2332.                   WAIT WINDOW win_msg TIMEOUT 1
  2333.                   m.scrn_face  = scrnfile.fontface
  2334.                   m.scrn_size  = scrnfile.fontsize
  2335.                   m.scrn_style = scrnfile.fontstyle
  2336.                   REPLACE scrnfile.name WITH juststem(m.appfile), ;
  2337.                      scrnfile.style WITH 2,                  ;
  2338.                      scrnfile.border WITH 1,                 ;
  2339.                      scrnfile.center WITH .F.,               ;
  2340.                      scrnfile.vpos WITH 1,                   ;
  2341.                      scrnfile.hpos WITH 3
  2342.                   WAIT CLEAR
  2343.                ENDIF
  2344.  
  2345.                * Figure out where to put the screen and control panel
  2346.                IF relateddbfs()
  2347.                   m.scrn_face  = scrnfile.fontface
  2348.                   m.scrn_size  = scrnfile.fontsize
  2349.                   m.scrn_style = scrnfile.fontstyle
  2350.  
  2351.                   m.vcoord = m.ctrlrow   && bottom of the screen
  2352.                   m.hcoord = m.ctrlcol
  2353.                   REPLACE scrnfile.center   WITH .F.
  2354.                   IF dbflist[1,m.arranged] = 'Y'
  2355.                      REPLACE scrnfile.vpos WITH VAL(dbflist[1,m.srownum])
  2356.                      REPLACE scrnfile.hpos WITH VAL(dbflist[1,m.scolnum])
  2357.                   ELSE
  2358.                      * Set default placement of browse windows if user hasn't arranged them
  2359.                      FOR m.i = 2 to m.numareas
  2360.                         * Position it below the previous browse or screen
  2361.                         m.rnum = MIN(VAL(dbflist[m.i-1,m.srownum]);
  2362.                            + VAL(dbflist[m.i-1,m.erownum]) + 2.5, my_srows())
  2363.                         dbflist[m.i,m.srownum] = ALLTRIM(STR(m.rnum,4))
  2364.                         * Center it horizontally
  2365.                         m.cnum = (my_scols() - VAL(dbflist[m.i,m.ecolnum])) / 2
  2366.                         dbflist[m.i,m.scolnum] = ALLTRIM(STR(m.cnum,4))
  2367.                      ENDFOR
  2368.                   ENDIF
  2369.                ELSE
  2370.                   * Use the screen coordinates in the SCX file to figure out
  2371.                   * where to put the control panel
  2372.                   IF scrnfile.center
  2373.                      m.vcoord = (my_srows() + scrnfile.height) / 2 + 3
  2374.                   ELSE
  2375.                      m.vcoord = scrnfile.vpos + scrnfile.height + 1
  2376.                   ENDIF
  2377.                   m.hcoord = INT((my_scols()-tranfont(73,6,m.g_dfltfface,m.g_dfltfsize,m.g_dfltfstyle))/2)
  2378.                   IF m.vcoord + 3 > my_srows()
  2379.                      m.vcoord = my_srows()-3
  2380.                   ENDIF
  2381.                ENDIF
  2382.                REPLACE FLOAT WITH .T., CLOSE WITH .T.
  2383.  
  2384.                * Force a select of the dbfname database whenever the screen
  2385.                * is activated.  This is necessary for the 1-to-many operations,
  2386.                * where clicking on a browse window will select some other
  2387.                * database.  We have to reselect dbfname when the user clicks in
  2388.                * on the dbfname screen.  This code stuffs a "SELECT dbfname"
  2389.                * into the activate snippet of the user screen, but only if there
  2390.                * isn't one there already.
  2391.                m.found_line = .F.
  2392.  
  2393.                * First scan for a previous FoxApp inserted line
  2394.                _MLINE = 0
  2395.                m.numlines = MEMLINES(scrnfile.activate)
  2396.                m.i = 1
  2397.                m.newact = ""
  2398.                DO WHILE m.i <= m.numlines
  2399.                   m.theline   = MLINE(scrnfile.activate,1,_MLINE)
  2400.                   m.theline = ALLTRIM(UPPER(m.theline))
  2401.                   DO CASE
  2402.                   CASE UPPER("SELECT ") $ theline AND "**FOXAPP**" $ theline
  2403.                      * We found a previous FoxApp 2.5 insert.  Is it the right one?
  2404.                      * It might not be if the user renamed the database.
  2405.                      IF UPPER("SELECT "+makealias(juststem(m.dbfname)))+" " $ m.theline
  2406.                         m.found_line = .T.
  2407.                         m.newact = m.newact + CHR(13) + CHR(10) + m.theline
  2408.                      ELSE
  2409.                         * FoxApp statement, but the wrong one.  Ignore it.
  2410.                      ENDIF
  2411.                   CASE "THE FOLLOWING LINE WAS ADDED BY FOXAPP" $ theline
  2412.                      * FoxApp 2.0 insert.  Drop this comment and the line that
  2413.                      * follows it, unless the following line doesn't look like
  2414.                      * one of mine.  The insert should always be a SELECT
  2415.                      * statement.
  2416.                      m.theline   = MLINE(scrnfile.activate,1,_MLINE)
  2417.                      m.theline = ALLTRIM(UPPER(m.theline))
  2418.                      IF !("SELECT " $ m.theline)
  2419.                         m.newact = m.newact + CHR(13) + CHR(10) + m.theline
  2420.                      ENDIF
  2421.                   OTHERWISE   && not a FoxApp statement
  2422.                      m.newact = m.newact + CHR(13) + CHR(10) + m.theline
  2423.                   ENDCASE
  2424.                   m.i = m.i + 1
  2425.                ENDDO
  2426.                IF !m.found_line
  2427.                   m.newact = m.newact  ;
  2428.                      + CHR(13) + CHR(10) + "SELECT "+makealias(juststem(m.dbfname))+"   "+CHR(38)+CHR(38)+" Added by **FOXAPP**"
  2429.                ENDIF
  2430.                REPLACE scrnfile.activate WITH m.newact
  2431.                USE
  2432.             ENDIF   && not wizard screen
  2433.          ELSE
  2434.             * This should never happen
  2435.             WAIT WINDOW "Screen heading record could not be found."
  2436.             RETURN .F.
  2437.          ENDIF
  2438.       ELSE
  2439.          * This should never happen
  2440.          WAIT WINDOW "Screen could not be opened."
  2441.          RETURN .F.
  2442.       ENDIF
  2443.       RELEASE newact, found_line, theline, i, numlines
  2444.  
  2445.       \m.win_name = "<<m.win_name>>"
  2446.       \m.wiz_screen = <<IIF(m.wizscreen,".T.", ".F.")>>
  2447.       * This is the main loop to display the screen and any related browses.
  2448.       \DO WHILE !m.bailout
  2449.       \   * Set up any related databases
  2450.       \   DO setrelat
  2451.       \   * Display the main screen file
  2452.       \   DO <<FNAddQuotes(m.sc_file)>>
  2453.       \   * Make sure nothing closed the database unexpectedly
  2454.       \   m.stem = makealias(juststem(m.dbfname))
  2455.       \   IF !USED(m.stem)
  2456.       \      SELECT 0
  2457.       \      USE (m.dbfname)
  2458.       \   ENDIF
  2459.       \ENDDO
  2460.       \DO cleanup
  2461.       \RETURN
  2462.       \
  2463.       \
  2464.       \*******************************************************************
  2465.       \PROCEDURE cleanup
  2466.       \* Clean up after the application
  2467.       \SET PROCEDURE TO
  2468.       \CLOSE DATABASES
  2469.       \CLEAR WINDOWS
  2470.       \IF _WINDOWS OR _MAC
  2471.       \   MODIFY WINDOW SCREEN FONT m.scrn_font, m.scrn_fsize STYLE m.scrn_fstyle
  2472.       \ENDIF
  2473.  
  2474.       \IF SET('TALK') = 'ON'
  2475.       \   SET TALK OFF
  2476.       \   m.t_stat = 'ON'
  2477.       \ELSE
  2478.       \   m.t_stat = 'OFF'
  2479.       \ENDIF
  2480.       \SET TALK OFF
  2481.       \* Restore databases, indexes and environment
  2482.       \IF FILE("appview.vue")
  2483.       \   SET VIEW TO appview
  2484.       \   SET TALK OFF
  2485.       \   DELETE FILE appview.vue
  2486.       \ENDIF
  2487.  
  2488.       \IF FILE("foxapp.fky")
  2489.       \   RESTORE MACROS FROM foxapp
  2490.       \   DELETE FILE foxapp.fky
  2491.       \ENDIF
  2492.       \IF m.t_stat = "ON"
  2493.       \   SET TALK ON
  2494.       \ENDIF
  2495.  
  2496.       \SET POINT TO "&set_point"
  2497.       \POP KEY ALL
  2498.       \POP MENU _msysmenu
  2499.       \CLEAR PROGRAM
  2500.       \
  2501.       \*Restore original error and escape routines
  2502.       \IF TYPE('fxapp_error') = 'C'
  2503.       \   ON ERROR &fxapp_error
  2504.       \ENDIF
  2505.       \
  2506.       \IF TYPE('fxapp_esc') = 'C'
  2507.       \   ON ESCAPE &fxapp_esc
  2508.       \ENDIF
  2509.       \
  2510.  
  2511.       \SET SAFETY ON
  2512.       \RELEASE m.bailout, m.dbfname, m.win_name, m.wiz_screen, m.filt_expr, m.srchterm, m.skipvar, m.act3
  2513.       \RELEASE dbflist
  2514.       \RETURN
  2515.  
  2516.       \
  2517.       \*******************************************************************
  2518.       \PROCEDURE setrelat
  2519.       \* This procedure opens subsidiary databases (if any) and establishes
  2520.       \* the relations between the main database and the subsidiary
  2521.       \* databases.  It will be empty if there are no subsidiary databases.
  2522.       IF TYPE("DBFLIST") <> "U"
  2523.          m.i = 2
  2524.          DO WHILE !EMPTY(dbflist[m.i,m.cstemnum]) AND dbflist[m.i,m.cstemnum] <> '\'
  2525.             m.b_font = dbflist[m.i,m.thefont]
  2526.             \SELECT <<m.i>>
  2527.             tagname = SUBSTR(dbflist[m.i,m.cfldnum],AT('.',dbflist[m.i,m.cfldnum])+1)
  2528.             \dname = "<<dbflist[m.i,m.cdbfnum]>>"
  2529.             \IF !FILE(m.dname)
  2530.             \   m.dname = GETFILE('DBF','Please locate the '+Juststem(m.dname)+ ' database:')
  2531.             \   IF EMPTY(m.dname) OR !FILE(m.dname)
  2532.             \      DO alert WITH "The "+ALLTRIM(m.dname+" database could not be found.")
  2533.             \      DO cleanup
  2534.             \      CANCEL
  2535.             \   ELSE
  2536.             \      SET PATH TO (SET('PATH') + ';' + Justpath(m.dname))
  2537.             \      dbflist[<<m.i>>,m.cdbfnum]  = m.dname
  2538.             \      dbflist[<<m.i>>,m.cstemnum] = makealias(juststem(m.dname))
  2539.             \   ENDIF
  2540.             \ENDIF
  2541.             \USE (m.dname) ALIAS <<dbflist[m.i,m.cstemnum]>> ;
  2542.             \   ORDER TAG <<m.tagname>>
  2543.             \DEFINE WINDOW <<"W_"+dbflist[m.i,m.cstemnum]>> ;
  2544.             \   AT   <<CHRTRAN(dbflist[m.i,m.srownum],",",".")>>, ;
  2545.             \        <<CHRTRAN(dbflist[m.i,m.scolnum],",",".")>>  ;
  2546.             \   SIZE <<CHRTRAN(dbflist[m.i,m.erownum],",",".")>>, ;
  2547.             \        <<CHRTRAN(dbflist[m.i,m.ecolnum],",",".")>> ;
  2548.             \   FLOAT GROW ZOOM NOCLOSE MINIMIZE ;
  2549.             \   FONT "<<m.g_dfltfface>>",<<m.g_dfltfsize>> ;
  2550.             \   STYLE "<<m.g_dfltfstyle>>" ;
  2551.             \   HALF ;
  2552.             \   COLOR SCHEME 10
  2553.             \BROWSE LAST NOWAIT;
  2554.             \   WINDOW <<"W_"+dbflist[m.i,m.cstemnum]>> ;
  2555.             \   NOAPPEND ;
  2556.             \   <<IIF(m.nextdbf>1,"NODELETE","")>> ;
  2557.             \   COLOR SCHEME 10
  2558.  
  2559.             m.i = m.i + 1
  2560.          ENDDO
  2561.  
  2562.          m.i = 2
  2563.          DO WHILE !EMPTY(dbflist[m.i,m.cstemnum]) AND dbflist[m.i,m.cstemnum] <> '\'
  2564.             \SELECT <<makealias(Juststem(dbflist[m.i,m.pdbfnum]))>>
  2565.             \<<dbflist[m.i,m.relstrnum]>> ADDITIVE
  2566.             \
  2567.             \* Restore the following line if you only want to see records in the
  2568.             \* parent file that have related records in the child file.
  2569.             \*SET FILTER TO FOUND('<<dbflist[m.i,m.cstemnum]>>')
  2570.             \
  2571.             m.i = m.i + 1
  2572.          ENDDO
  2573.          \SELECT <<makealias(Juststem(m.dbfname))>>
  2574.       ENDIF
  2575.       \RETURN
  2576.       \
  2577.       \
  2578.       \*******************************************************************
  2579.       \PROCEDURE definedbf
  2580.       \* Define the dbflist array
  2581.       \PUBLIC dbflist[m.numareas,m.numcols]
  2582.       FOR m.i = 1 TO m.numareas
  2583.          FOR m.j = 1 TO m.numcols
  2584.             IF TYPE("DBFLIST") <> "U"
  2585.                IF TYPE("dbflist[m.i,m.j]") = "C"
  2586.                   \DBFLIST[<<m.i>>,<<m.j>>] = <<'"'+dbflist[m.i,m.j]+'"'>>
  2587.                ELSE
  2588.                   \DBFLIST[<<m.i>>,<<m.j>>] = <<dbflist[m.i,m.j]>>
  2589.                ENDIF
  2590.             ELSE
  2591.                \DBFLIST[<<m.i>>,<<m.j>>] = ''
  2592.             ENDIF
  2593.          ENDFOR
  2594.       ENDFOR
  2595.       \
  2596.       \
  2597.       \*******************************************************************
  2598.  
  2599.       SET TEXTMERGE TO
  2600.       SET TEXTMERGE OFF
  2601.       SET CONSOLE ON
  2602.       SET NOTIFY OFF
  2603.  
  2604.       SET POINT TO &mpoint
  2605.  
  2606.       * Release the large dbflist array so that we don't run out of
  2607.       * memory and/or other system resources during project generation
  2608.       RELEASE dbflist, i, j, m.b_font
  2609.  
  2610.       m.appname  = UPPER(ALLTRIM(m.appfile))
  2611.       m.projname = forceext(m.appname,'PJX')
  2612.  
  2613.       * Compute the mimimum path between the project home directory
  2614.       * and the SCX file. We'll want the mimimum path stored in the
  2615.       * project file we are about to build so that the project will
  2616.       * be portable across directories.
  2617.       m.sc_name = SYS(2014,m.scxname,m.appname)
  2618.  
  2619.       m.p_path = addcolon(justpath(m.projname))
  2620.       SET DEFAULT TO (m.p_path)
  2621.  
  2622.       * Clear any existing project files.  Start with a clean slate.
  2623.       IF FILE(m.projname)
  2624.          DELETE FILE (m.projname)
  2625.       ENDIF
  2626.       pjtname = forceext(m.projname,'PJT')
  2627.       IF FILE(m.pjtname)
  2628.          DELETE FILE (m.pjtname)
  2629.       ENDIF
  2630.  
  2631.       * One last check to make sure that the user didn't leave a
  2632.       * poisonous MPR hanging around.
  2633.       m.mpr_name = FULLPATH(addbs(justpath(m.projname))+'APPMENU.MPR')
  2634.       IF FILE(m.mpr_name)
  2635.          DELETE FILE (mpr_name)
  2636.          m.mpx_name = FULLPATH(addbs(justpath(m.projname))+'APPMENU.MPX')
  2637.          IF FILE(m.mpx_name)
  2638.             DELETE FILE (mpx_name)
  2639.          ENDIF
  2640.       ENDIF
  2641.       RELEASE mpr_name, mpx_name
  2642.  
  2643.       * Build the actual application project file and APP now
  2644.       SET MESSAGE TO "Building project"
  2645.       IF m.regen
  2646.          DO copypiece   && copy FoxApp pieces to project directory
  2647.          BUILD PROJECT (m.projname) FROM ;
  2648.             (m.tmfname),    ;
  2649.             (m.scxname),    ;
  2650.             appproc.prg,    ;
  2651.             appmenu.mnx,    ;
  2652.             prtsetup.scx,   ;
  2653.             getdest.scx,    ;
  2654.             getorder.scx,   ;
  2655.             appabout.scx,   ;
  2656.             appsrch.scx
  2657.       ELSE
  2658.          prg1 = addbs(m.foxappdir)+'PRGS\appproc.prg'
  2659.          prg2 = addbs(m.foxappdir)+'MENUS\appmenu.prg'
  2660.          prg3 = addbs(m.foxappdir)+'SCREENS\prtsetup.prg'
  2661.          prg4 = addbs(m.foxappdir)+'SCREENS\getdest.prg'
  2662.          prg5 = addbs(m.foxappdir)+'SCREENS\getorder.prg'
  2663.          prg6 = addbs(m.foxappdir)+'SCREENS\appabout.prg'
  2664.          prg7 = addbs(m.foxappdir)+'SCREENS\appsrch.prg'
  2665.       
  2666.          BUILD PROJECT (m.projname) FROM              ;
  2667.             (m.tmfname),                              ;
  2668.             (prg1),    ;
  2669.             (prg2),   ;
  2670.             (prg3),;
  2671.             (prg4), ;
  2672.             (prg5),;
  2673.             (prg6),;
  2674.             (prg7), ;
  2675.             (m.sc_name)
  2676.       ENDIF
  2677.  
  2678.       IF !m.wizscreen
  2679.          * Modify the new project to merge the FoxApp control panel
  2680.          * with the user screen (SCXNAME) into one screen set.
  2681.          SET MESSAGE TO "Adding control panel"
  2682.  
  2683.          DO mergectrl WITH m.projname, m.scxname, m.vcoord, m.hcoord
  2684.       ENDIF
  2685.       SET MESSAGE TO "Building application"
  2686.       BUILD APP (m.appname) FROM (m.projname)
  2687.  
  2688.       * Set the default path back to what it was
  2689.       SET DEFAULT TO (c_path)
  2690.  
  2691.       SET NOTIFY ON
  2692.  
  2693.       CLEAR READ
  2694.    ENDIF
  2695. ENDIF
  2696. RETURN .T.
  2697.  
  2698.  
  2699. PROCEDURE AppScxShow
  2700. * READ-level SHOW clause for appscx screen
  2701. *------------------------------------------------------------------
  2702. DO CASE
  2703. CASE EMPTY(m.dbfname) OR skipdbfbut
  2704.     IF !_MAC
  2705.       SHOW GET generate DISABLE
  2706.       SHOW GET other    DISABLE
  2707.    ENDIF
  2708.    SHOW GET adddbf   DISABLE
  2709.    SHOW GET moddbf   DISABLE
  2710. CASE !FILE(m.dbfname)
  2711.     IF !_MAC
  2712.       SHOW GET generate DISABLE
  2713.       SHOW GET other    DISABLE
  2714.   ENDIF
  2715.    SHOW GET adddbf   ENABLE
  2716.    SHOW GET moddbf   DISABLE
  2717. OTHERWISE   && everything is ok
  2718.    SHOW GET generate ENABLE
  2719.    SHOW GET other    ENABLE
  2720.    SHOW GET adddbf   DISABLE
  2721.    SHOW GET moddbf   ENABLE
  2722. ENDCASE
  2723.  
  2724. DO CASE
  2725. CASE EMPTY(m.scxname)
  2726.    SHOW GET addscx   DISABLE
  2727.    SHOW GET modscx   DISABLE
  2728.    SHOW GET arrange  DISABLE
  2729. CASE !FILE(m.scxname)
  2730.    SHOW GET addscx   ENABLE
  2731.    SHOW GET modscx   DISABLE
  2732.    SHOW GET arrange  DISABLE
  2733. OTHERWISE   && everything is ok
  2734.    SHOW GET addscx   DISABLE
  2735.    SHOW GET modscx   ENABLE
  2736.    SHOW GET arrange  ENABLE
  2737. ENDCASE
  2738.  
  2739. * See if there is a stored resource for this database in the current
  2740. *    resource file.  This is in the SHOW snippet instead of in the
  2741. *    VALID for the "related" button since we want to get this information
  2742. *    even if the user never presses "related" in this session.
  2743. IF !EMPTY(m.dbfname) AND !m.rsc_check AND m.retrieversc
  2744.    IF !EMPTY(ALIAS())
  2745.       m.nextdbf = getdbflist(ALIAS())
  2746.       * Only check the resource file once
  2747.       m.rsc_check = .T.
  2748.    ENDIF
  2749. ENDIF
  2750.  
  2751. IF relateddbfs() AND !EMPTY(m.scxname) AND FILE(m.scxname)
  2752.    SHOW GET arrange  ENABLE
  2753. ELSE
  2754.    SHOW GET arrange  DISABLE
  2755. ENDIF   
  2756.  
  2757.  
  2758. PROCEDURE BrResValid
  2759. * Browse FoxApp resource file entries
  2760. * VALID clause for from Browse Resources button on Advance screen
  2761. *------------------------------------------------------------------
  2762. PRIVATE m.in_area, m.in_del
  2763. m.in_del  = SET("DELETED")
  2764. SET DELETED ON
  2765. m.in_area = SELECT()
  2766. SELECT 0
  2767. USE (SYS(2005)) AGAIN ALIAS app_rsc
  2768. DO CASE
  2769. CASE _MAC
  2770.    DEFINE WINDOW rsc_brow FROM 4,my_scols()/2-35/2 TO 14,my_scols()/2+35/2 ;
  2771.       CLOSE GROW FLOAT ZOOM MINIMIZE ;
  2772.       TITLE "FoxApp Resource File Entries" ;
  2773.       FONT "Monaco",9
  2774.  
  2775. CASE _DOS
  2776.    DEFINE WINDOW rsc_brow FROM 4,my_scols()/2-35/2 TO 14,my_scols()/2+35/2 ;
  2777.       TITLE "FoxApp Resource File Entries" ;
  2778.       SYSTEM ;
  2779.       FLOAT ;
  2780.       CLOSE ;
  2781.       SHADOW ;
  2782.       MINIMIZE 
  2783.  
  2784. OTHERWISE
  2785.    DEFINE WINDOW rsc_brow FROM 4,my_scols()/2-35/2 TO 14,my_scols()/2+35/2 ;
  2786.       CLOSE GROW FLOAT ZOOM MINIMIZE ;
  2787.       TITLE "FoxApp Resource File Entries" ;
  2788.       FONT "FoxFont",9
  2789.  
  2790. ENDCASE
  2791.  
  2792. BROWSE LAST ;
  2793.    WINDOW rsc_brow ;
  2794.    FIELD app_rsc.type, app_rsc.id, app_rsc.name ;
  2795.    FOR UPPER(ALLTRIM(app_rsc.type)) == UPPER(ALLTRIM(m.rsctype))
  2796. USE
  2797. RELEASE WINDOW rsc_brow
  2798. SELECT (m.in_area)
  2799. SET DELETED &in_del
  2800. return