home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / FOXP-WIN.300 / DISK5 / VFP5.CAB / 30UPDATE.PRG next >
Encoding:
Text File  |  1995-01-11  |  87.6 KB  |  2,984 lines

  1. #define c_debug    .t.
  2.  
  3. #define FOXPRO_BUILD_ID        344
  4.     
  5. #define MB_OK                0
  6. #define MB_OKCANCEL            1
  7. #define MB_ABORTRETRYIGNORE 2
  8. #define MB_YESNOCANCEL        3
  9. #define MB_YESNO            4
  10. #define MB_RETRYCANCEL        5
  11. #define MB_TYPEMASK            15
  12.  
  13. #define MB_ICONHAND            16
  14. #define MB_ICONQUESTION        32
  15. #define MB_ICONEXCLAMATION  48
  16. #define MB_ICONASTERISK     64
  17. #define MB_ICONMASK            240
  18.  
  19. #define MB_ICONINFORMATION  64
  20. #define MB_ICONSTOP         16
  21.  
  22. #define MB_DEFBUTTON1        0
  23. #define MB_DEFBUTTON2        256
  24. #define MB_DEFBUTTON3        512
  25. #define MB_DEFMASK            3840
  26.  
  27. #define MB_APPLMODAL        0
  28. #define MB_SYSTEMMODAL        4096
  29. #define MB_TASKMODAL        8192
  30.  
  31. #define MB_NOFOCUS            32768
  32.  
  33. #define m_MsgBoxTitle        'FoxPro 3.0 Updater'
  34. #define m_Not30Scx            ' is not a 3.0 .SCX!'
  35. #define m_Not30Dbc            ' is not a 3.0 .DBC!'
  36. #define m_Not30Pjx            ' is not a 3.0 .PJX!'
  37. #define m_NotComment        'Record #1 is not a COMMENT record.'
  38.  
  39. #define c_crlf                chr(13)+chr(10)
  40.  
  41. #define e_InvalidParameter    'Invalid argument type.'
  42. #define e_ScxNotFound        ' not found.'
  43.  
  44. parameters m.cScxName
  45. private aEnvironment
  46. dimension aEnvironment[1]
  47. clear
  48.  
  49. do ScxUpdtrSetup
  50. do ScxUpdtrMain
  51. do ScxUpdtrCleanup
  52.  
  53. *******************
  54. procedure UpdatePjx
  55. *******************
  56. parameters m.cPjxName, m.lNotify
  57.  
  58. private cPath, lIs30Pjx
  59.  
  60. m.cPath=justpath(m.cPjxName)
  61. set default to (m.cPath)
  62.  
  63. use (m.cPjxName) alias PjxFile
  64.  
  65. m.lIs30Pjx=.f.
  66. do case
  67. case type('PjxFile.name')<>'M'
  68. case type('PjxFile.type')<>'C'
  69. case type('PjxFile.timestamp')<>'N'
  70. case type('PjxFile.outfile')<>'M'
  71. case type('PjxFile.homedir')<>'M'
  72. case type('PjxFile.exclude')<>'L'
  73. case type('PjxFile.mainprog')<>'L'
  74. case type('PjxFile.savecode')<>'L'
  75. case type('PjxFile.debug')<>'L'
  76. case type('PjxFile.encrypt')<>'L'
  77. case type('PjxFile.nologo')<>'L'
  78. case type('PjxFile.cmntstyle')<>'N'
  79. case type('PjxFile.objrev')<>'N'
  80. case type('PjxFile.commands')<>'M'
  81. case type('PjxFile.devinfo')<>'M'
  82. case type('PjxFile.symbols')<>'M'
  83. case type('PjxFile.object')<>'M'
  84. case type('PjxFile.ckval')<>'N'
  85. case type('PjxFile.cpid')<>'N'
  86. case type('PjxFile.ostype')<>'C'
  87. case type('PjxFile.oscreator')<>'C'
  88. case type('PjxFile.comments')<>'M'
  89. case type('PjxFile.reserved1')<>'M'
  90. case type('PjxFile.reserved2')<>'M'
  91. otherwise
  92.     m.lIs30Pjx=.t.
  93. endcase
  94.  
  95. if !m.lIs30Pjx
  96.     =Alert(m.cPjxName+m_Not30Pjx)
  97. else
  98.     if m.lNotify
  99.         activate screen
  100.         ?'Updating '+m.cPjxName+'...  '
  101.     endif
  102.     CREATE CURSOR PjxFile2 ;
  103.         (name m(10,0), ;
  104.         type c(1,0), ;
  105.         timestamp n(10,0), ;
  106.         outfile m(10,0), ;
  107.         homedir m(10,0), ;
  108.         exclude l(1,0), ;
  109.         mainprog l(1,0), ;
  110.         savecode l(1,0), ;
  111.         debug l(1,0), ;
  112.         encrypt l(1,0), ;
  113.         nologo l(1,0), ;
  114.         cmntstyle n(1,0), ;
  115.         objrev n(5,0), ;
  116.         commands m(10,0), ;
  117.         devinfo m(10,0), ;
  118.         symbols m(10,0), ;
  119.         object m(10,0), ;
  120.         ckval n(6,0), ;
  121.         cpid n(5,0), ;
  122.         ostype c(4,0), ;
  123.         oscreator c(4,0), ;
  124.         comments m(10,0), ;
  125.         reserved1 m(10,0), ;
  126.         reserved2 m(10,0), ;
  127.         key c(32), ;
  128.         user m(10, 0))
  129.  
  130.     use in PjxFile
  131.     select PjxFile2
  132.     
  133.     append from (m.cPjxName) for !deleted()
  134.     
  135.     m.lSuccess = .t.
  136.  
  137.     locate for type = 'H'
  138.     if !found()
  139.         =Alert('Project '+m.cPjxFile+' has no header record.')
  140.         m.lSuccess = .f.
  141.     else
  142.         m.iVersion = objrev
  143.     endif
  144.  
  145.     do while m.lSuccess
  146.         do case
  147.         case m.iVersion = 257 .and. OkToBuild(245)
  148.             delete for type = 'S'
  149.             replace type with 'K' for type = 's'
  150.  
  151.             replace all key with left(justfname(name), 32)
  152.             locate for type = 'H'
  153.             replace objrev with 258
  154.             m.iVersion = 258
  155.         case m.iVersion = 258 .and. OkToBuild(275)
  156.             * Add a USER field to the .PJX structure--the field has been added
  157.             * to the CREATE CURSOR statement above.
  158.             
  159.             locate for type = 'H'
  160.             replace objrev with 259
  161.             m.iVersion = 259
  162.         otherwise
  163.             exit
  164.         endcase
  165.     enddo
  166.     
  167.     if m.lSuccess
  168.         copy to (m.cPjxName) for !deleted()
  169.         use in PjxFile2
  170.         m.cOnError=on('error')
  171.         m.iError=0
  172.         on error m.iError=error()
  173.         * Rebuild project?
  174.         on error &cOnError
  175.         if !empty(m.iError)
  176.             =Alert('Error #'+alltrim(str(m.iError))+' occurred '+ ;
  177.                 'building '+m.cPjxName+'.')
  178.         endif
  179.     else
  180.         use in PjxFile2
  181.     endif
  182.     
  183.     if m.lNotify
  184.         activate screen
  185.         if m.lSuccess
  186.             ??'Complete.'
  187.         else
  188.             ??'Skipped.'
  189.         endif
  190.     endif
  191. endif
  192.  
  193. ********************
  194. procedure UpdateScx
  195. ********************
  196. parameters m.cScxName, m.lNotify
  197. private m.iSelect, m.lIs30Scx, m.cExact, m.i, ;
  198.     m.lTxt2Edt, m.iVersion, m.cProperty, m.cLine, ;
  199.     m.cUpdatedProperties, m.cUpdatedMethods, m.lDeclares
  200.  
  201. m.cPath=justpath(m.cScxName)
  202. set default to (m.cPath)
  203.  
  204. use (m.cScxName) alias ScxFile
  205.  
  206. m.lIs30Scx=.f.
  207. do case
  208. case type('ScxFile.platform')<>'C'
  209. case type('ScxFile.uniqueid ')<>'C'
  210. case type('ScxFile.timestamp')<>'N'
  211. case type('ScxFile.reserved1')<>'M'
  212. case type('ScxFile.reserved2')<>'M'
  213. case type('ScxFile.reserved3')<>'M'
  214. case type('ScxFile.user')<>'M'
  215. case type('ScxFile.comment')<>'M'
  216. case type('ScxFile.class')<>'C' .and. type('ScxFile.class')<>'M'
  217. case type('ScxFile.classloc')<>'M'
  218. case type('ScxFile.objname')<>'M'
  219. case type('ScxFile.parent')<>'M'
  220. case type('ScxFile.properties')<>'M'
  221. case type('ScxFile.methods')<>'M'
  222. case type('ScxFile.objcode')<>'M'
  223. otherwise
  224.     m.lIs30Scx=.t.
  225. endcase
  226.  
  227. if !m.lIs30Scx
  228.     =Alert(m.cScxName+m_Not30Scx)
  229. else
  230.     if m.lNotify
  231.         activate screen
  232.         ?'Updating '+m.cScxName+'...  '
  233.     endif
  234.     
  235.     * RESERVED6 - RESERVED10 added for version .026
  236.     create cursor ScxFile2 ;
  237.         (    platform    c(8), ;
  238.             uniqueid    c(10), ;
  239.             timestamp    n(10), ;
  240.             class        m, ;
  241.             classloc    m, ;
  242.             baseclass    m, ;
  243.             objname        m, ;
  244.             parent        m, ;
  245.             properties    m, ;
  246.             protected    m, ;
  247.             methods        m, ;
  248.             objcode        m, ;
  249.             declares    m, ;
  250.             declares2    m, ;
  251.             ole            m, ;
  252.             ole2        m, ;
  253.             comment        m, ;
  254.             reserved1    m, ;
  255.             reserved2    m, ;
  256.             reserved3    m, ;
  257.             reserved4    m, ;
  258.             reserved5    m, ;
  259.             reserved6    m, ;
  260.             reserved7    m, ;
  261.             reserved8    m, ;
  262.             reserved9    m, ;
  263.             reserved10    m, ;
  264.             user        m)
  265.     select ScxFile
  266.     go top
  267.     if platform='COMMENT' .and. (upper(uniqueid)='SCREEN' .or. ;
  268.         upper(uniqueid)='CLASS')
  269.         m.iVersion=val(setting(reserved1,'version'))
  270.         m.cType=upper(alltrim(uniqueid))
  271.     else
  272.         insert into ScxFile2 ;
  273.             (platform, uniqueid) ;
  274.             values ('COMMENT','Screen')
  275.         m.iVersion=0
  276.         m.cType='SCREEN'
  277.     endif
  278.     
  279.     use in ScxFile
  280.     select ScxFile2
  281.     
  282.     if m.cType='SCREEN'
  283.         append from (m.cScxName)
  284.     else
  285.         append from (m.cScxName) for .not. deleted()
  286.     endif
  287.     
  288.     replace all objcode with ''
  289.     
  290.     m.lSuccess=.t.
  291.     
  292.     do while .t.
  293.         do case
  294.         case m.iVersion < .005
  295.             replace all class with alltrim(class)
  296.             locate for lower(alltrim(class))='fieldbox'
  297.             m.lTxt2Edt=iif(found(),.t.,.f.)
  298.             if type('ScxFile.declares')<>'M'
  299.                 m.lTxt2Edit=.t.
  300.             endif
  301.  
  302.             if m.lTxt2Edt
  303.                 replace class with 'editbox' for lower(alltrim(class))='textbox'
  304.                 replace class with 'textbox' for lower(alltrim(class))='fieldbox'
  305.             endif
  306.             m.cFormSetName=''
  307.             m.cFormName=''
  308.             scan
  309.                 * Fill in Objname if it's empty
  310.                 if empty(ScxFile2.objname)
  311.                     replace objname with setting(properties,'Name')
  312.                 endif
  313.                 * Update current formset and form names
  314.                 if upper(class)='FORMSET'
  315.                     m.cFormSetName=objname
  316.                 endif
  317.                 if upper(class)='FORM'
  318.                     m.cFormName=objname
  319.                 endif
  320.                 * Fill in Parent if it's empty
  321.                 if empty(ScxFile2.parent)
  322.                     do case
  323.                     case upper(class)='FORMSET'
  324.                         * formset doesn't have a parent
  325.                     case upper(class)='FORM'
  326.                         replace parent with m.cFormSetName
  327.                     otherwise
  328.                         replace parent with m.cFormSetName+'.'+m.cFormName
  329.                     endcase
  330.                 endif
  331.             endscan
  332.             
  333.             * write the version number
  334.             =UpdateVersion('VERSION =  0.005')
  335.             m.iVersion = .005
  336.             
  337.         case m.iVersion = .005
  338.             * Apply quotes to DATATEXT properties of .SCX and .VCX files
  339.             m.cDataTextList= ;
  340.                 ',CAPTION,CHILDORDER,CLIP,COLUMNWIDTHS,COLOR,COMMENT,DATASOURCE'+ ;
  341.                 ',DATASOURCEOBJ,DATATYPE,FONT,FONTNAME,FORMAT,FROM<ARRAY>,FUNCTION'+ ;
  342.                 ',INPUTMASK,LINKMASTER,LINKTOPIC,LIST,LISTSOURCE,<MEMVAR>|<FIELD>'+ ;
  343.                 ',OPTIONVALUE,PASSWORDCHAR,PICTURE,SOURCE,STATUSBARTEXT,TAB,TAG,TEXT'+ ;
  344.                 ',VALIDATIONRULE,VALIDATIONTEXT,WINDOW,WINDOWLIST,WINDOWNTILIST,NAME'+ ;
  345.                 ',PALETTESOURCE,XBACKCOLOR,XFORECOLOR,XFORECOLOR,XFONTSIZE,XFONTSTYLE'+ ;
  346.                 ',XALIGNMENT,'
  347.             scan for platform='WINDOWS'
  348.                 _mline=0
  349.                 m.cUpdatedProperties=''
  350.                 for m.i=1 to memlines(properties)
  351.                     m.cLine=mline(properties,1,_mline)
  352.                     if empty(m.cLine)
  353.                         loop
  354.                     endif
  355.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  356.                     if '.'$m.cProperty
  357.                         m.cPropertyName=substr(m.cProperty,rat('.',m.cProperty)+1)
  358.                     else
  359.                         m.cPropertyName=m.cProperty
  360.                     endif
  361.                     if ','+upper(alltrim(m.cPropertyName))+','$m.cDataTextList
  362.                         m.cValue=substr(m.cLine,at('=',m.cLine)+1)
  363.                         if left(m.cValue,1)=' '
  364.                             m.cValue=substr(m.cValue,2)
  365.                         endif
  366.                         do case
  367.                         case ["]$m.cValue .and. [']$m.cValue .and. ;
  368.                             ('['$m.cValue .or. ']'$m.cValue)
  369.                             && TBD
  370.                             && The form tool currently slaps [] around strings like
  371.                             && this--we'll address the issue in a later version.
  372.                             m.cValue='['+m.cValue+']'
  373.                         case .not. ["]$m.cValue
  374.                             m.cValue=["]+m.cValue+["]
  375.                         case .not. [']$m.cValue
  376.                             m.cValue=[']+m.cValue+[']
  377.                         otherwise
  378.                             m.cValue='['+m.cValue+']'
  379.                         endcase
  380.                         m.cUpdatedProperties=m.cUpdatedProperties+ ;
  381.                             m.cProperty+' = '+m.cValue+c_crlf
  382.                     else
  383.                         m.cUpdatedProperties=m.cUpdatedProperties+ ;
  384.                             m.cLine+c_crlf
  385.                     endif
  386.                 endfor
  387.                 replace properties with m.cUpdatedProperties
  388.             endscan
  389.             release aProperties
  390.             =UpdateVersion('VERSION =  0.006')
  391.             m.iVersion = .006
  392.         case m.iVersion = .006 .and. m.cType='CLASS'
  393.             scan for upper(alltrim(parent))=='CLASS'
  394.                 m.iRecno=recno()
  395.                 do case
  396.                 case upper(alltrim(class))=='CONTROLS'
  397.                     skip
  398.                     m.iTimestamp=timestamp
  399.                     m.cUniqueID=sys(2015)
  400.                     do while .t.
  401.                         m.cUniqueID=sys(2015)
  402.                         locate for alltrim(uniqueid)==m.cUniqueID
  403.                         if !found()
  404.                             exit
  405.                         endif
  406.                     enddo
  407.                     go (m.iRecno)
  408.                     replace platform with 'WINDOWS', ;
  409.                         reserved2 with alltrim(str(timestamp+1)), ;
  410.                         reserved1 with 'Class', ;
  411.                         parent with '', ;
  412.                         timestamp with m.iTimestamp, ;
  413.                         uniqueid with m.cUniqueID
  414.                 otherwise
  415.                     m.iCount=timestamp
  416.                     m.cObjname=objname
  417.                     m.cComment=comment
  418.                     skip
  419.                     m.cOldObjname=upper(alltrim(objname))
  420.                     replace reserved1 with 'Class', ;
  421.                         reserved2 with alltrim(str(m.iCount)), ;
  422.                         objname with m.cObjname, ;
  423.                         comment with m.cComment
  424.                     scan while .not. upper(alltrim(parent))=='CLASS'
  425.                         if upper(alltrim(parent))==m.cOldObjname
  426.                             replace parent with m.cObjname
  427.                         endif
  428.                     endscan
  429.                     go (m.iRecno)
  430.                     delete                    
  431.                 endcase
  432.             endscan
  433.             
  434.             =UpdateVersion('VERSION =  0.007')
  435.                m.iVersion = .007
  436.                
  437.         case (m.iVersion = .006 .and. m.cType='SCREEN') .or. ;
  438.             (m.iVersion = .007 .and. m.cType='CLASS')
  439.             
  440.             && Change "Gridcolumn" to "Column" and "Gridcolumnheader" to "Header"
  441.             
  442.             scan for alltrim(class)=='grid'
  443.                 m.cUpdatedProperties=''
  444.                 _mline=0
  445.                 for m.i=1 to memlines(properties)
  446.                     m.cLine=mline(properties,1,_mline)
  447.                     if empty(m.cLine)
  448.                         loop
  449.                     endif
  450.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  451.                     do case
  452.                     case 'Gridcolumn'$m.cProperty
  453.                         m.cProperty=strtran( ;
  454.                             strtran(m.cProperty,'Gridcolumnheader','Header'), ;
  455.                             'Gridcolumn','Column')
  456.                         m.cUpdatedProperties=m.cUpdatedProperties+ ;
  457.                             m.cProperty+' '+substr(m.cLine,at('=',m.cLine))+c_crlf
  458.                     otherwise
  459.                         m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  460.                     endcase
  461.                 endfor
  462.                 replace properties with m.cUpdatedProperties
  463.             endscan
  464.             if m.iVersion = .006
  465.                 m.iVersion=.007
  466.                 =UpdateVersion('VERSION =  0.007')
  467.             else
  468.                 m.iVersion=.008
  469.                 =UpdateVersion('VERSION = 0.008')
  470.             endif
  471.             
  472.         case (m.iVersion = .007 .and. m.cType='SCREEN') .or. ;
  473.             (m.iVersion = .008 .and. m.cType='CLASS')
  474.         
  475.             && combine Grid.HGridLines and Grid.VGridLines into Grid.GridLines and
  476.             && Grid.HScrollBar and Grid.VScrollBar into Grid.ScrollBars
  477.             
  478.             scan for alltrim(class)=='grid'
  479.                 m.cUpdatedProperties=''
  480.                 _mline=0
  481.                 m.VGridLines=.t. && default
  482.                 m.HGridLines=.t. && default
  483.                 m.VScrollBar=.t. && default
  484.                 m.HScrollBar=.t. && default
  485.                 for m.i=1 to memlines(properties)
  486.                     m.cLine=mline(properties,1,_mline)
  487.                     if empty(m.cLine)
  488.                         loop
  489.                     endif
  490.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  491.                     do case
  492.                     case m.cProperty='HScrollBar'
  493.                         m.HScrollBar=evaluate(substr(m.cLine,at('=',m.cLine)+1))
  494.                     case m.cProperty='VScrollBar'
  495.                         m.VScrollBar=evaluate(substr(m.cLine,at('=',m.cLine)+1))
  496.                     case m.cProperty='VGridLines'
  497.                         m.VGridLines=evaluate(substr(m.cLine,at('=',m.cLine)+1))
  498.                     case m.cProperty='HGridLines'
  499.                         m.HGridLines=evaluate(substr(m.cLine,at('=',m.cLine)+1))
  500.                     otherwise
  501.                         m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  502.                     endcase
  503.                 endfor
  504.                 do case
  505.                 case .not. HGridLines .and. .not. VGridLines
  506.                     m.cUpdatedProperties=m.cUpdatedProperties+ ;
  507.                         'GridLines = 0'+c_crlf
  508.                 case HGridLines .and. .not. VGridLines
  509.                     m.cUpdatedProperties=m.cUpdatedProperties+ ;
  510.                         'GridLines = 1'+c_crlf
  511.                 case .not. HGridLines .and. VGridLines
  512.                     m.cUpdatedProperties=m.cUpdatedProperties+ ;
  513.                         'GridLines = 2'+c_crlf
  514.                 otherwise
  515.                     && nothing, both (3) is the default
  516.                 endcase
  517.                 do case
  518.                 case .not. HScrollBar .and. .not. VScrollBar
  519.                     m.cUpdatedProperties=m.cUpdatedProperties+ ;
  520.                         'ScrollBars = 0'+c_crlf
  521.                 case HScrollBar .and. .not. VScrollBar
  522.                     m.cUpdatedProperties=m.cUpdatedProperties+ ;
  523.                         'ScrollBars = 1'+c_crlf
  524.                 case .not. HScrollBar .and. VScrollBar
  525.                     m.cUpdatedProperties=m.cUpdatedProperties+ ;
  526.                         'ScrollBars = 2'+c_crlf
  527.                 otherwise
  528.                     && nothing, both (3) is the default
  529.                 endcase
  530.                 replace properties with m.cUpdatedProperties
  531.             endscan
  532.             if m.iVersion = .007
  533.                 m.iVersion=.008
  534.                 =UpdateVersion('VERSION =  0.008')
  535.             else
  536.                 m.iVersion=.009
  537.                 =UpdateVersion('VERSION = 0.009')
  538.             endif
  539.             
  540.         case (m.iVersion = .008 .and. m.cType='SCREEN') .or. ;
  541.             (m.iVersion = .009 .and. m.cType='CLASS')
  542.             
  543.             && Rename default name of controls:
  544.             &&        Commandbutton    Command
  545.             &&        Optionbutton    Option
  546.             &&        Listbox            List
  547.             &&        Combobox        Combo
  548.             &&        Editbox            Edit
  549.             &&        Textbox            Text
  550.             &&        Checkbox        Check
  551.             
  552.             scan for empty(classloc) .and. !empty(class)
  553.                 m.cUpdatedProperties=''
  554.                 _mline=0
  555.                 for m.i=1 to memlines(properties)
  556.                     m.cLine=mline(properties,1,_mline)
  557.                     if empty(m.cLine)
  558.                         loop
  559.                     endif
  560.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  561.                     m.cProperty=strtran(m.cProperty,'Commandbutton','Command')
  562.                     m.cProperty=strtran(m.cProperty,'Optionbutton','Option')
  563.                     m.cProperty=strtran(m.cProperty,'Listbox','List')
  564.                     m.cProperty=strtran(m.cProperty,'Combobox','Combo')
  565.                     m.cProperty=strtran(m.cProperty,'Editbox','Edit')
  566.                     m.cProperty=strtran(m.cProperty,'Textbox','Text')
  567.                     m.cProperty=strtran(m.cProperty,'Checkbox','Check')
  568.                     m.cUpdatedProperties=m.cUpdatedProperties+ ;
  569.                         m.cProperty+' '+substr(m.cLine,at('=',m.cLine))+c_crlf
  570.                 endfor
  571.                 replace properties with m.cUpdatedProperties
  572.             endscan
  573.             if m.iVersion = .008
  574.                 m.iVersion=.009
  575.                 =UpdateVersion('VERSION =  0.009')
  576.             else
  577.                 m.iVersion=.010
  578.                 =UpdateVersion('VERSION = 0.010')
  579.             endif
  580.             
  581.         case (m.iVersion = .009 .and. m.cType='SCREEN') .or. ;
  582.             (m.iVersion = .010 .and. m.cType='CLASS')
  583.             
  584.             && Update BASECLASS memo field with FoxPro base class
  585.             
  586.             if !used('classes')
  587.                 create cursor classes ;
  588.                     (class m, classloc m, baseclass m)
  589.                 insert into classes values ('checkbox','','')
  590.                 insert into classes values ('combobox','','')
  591.                 insert into classes values ('commandbutton','','')
  592.                 insert into classes values ('commandgroup','','')
  593.                 insert into classes values ('controls','','')
  594.                 insert into classes values ('editbox','','')
  595.                 insert into classes values ('form','','')
  596.                 insert into classes values ('formset','','')
  597.                 insert into classes values ('grid','','')
  598.                 insert into classes values ('image','','')
  599.                 insert into classes values ('label','','')
  600.                 insert into classes values ('line','','')
  601.                 insert into classes values ('listbox','','')
  602.                 insert into classes values ('olecontrol','','')
  603.                 insert into classes values ('optionbutton','','')
  604.                 insert into classes values ('optiongroup','','')
  605.                 insert into classes values ('pageframe','','')
  606.                 insert into classes values ('shape','','')
  607.                 insert into classes values ('spinner','','')
  608.                 insert into classes values ('textbox','','')
  609.                 insert into classes values ('timer','','')
  610.                 replace all baseclass with class
  611.                 select ScxFile2
  612.             endif
  613.             
  614.             scan for !empty(class)
  615.                 m.cClass=class
  616.                 m.cClassLoc=iif(empty(classloc),'',fullpath(classloc))
  617.                 m.cBaseClass=''
  618.                 
  619.                 do while .t.
  620.                     select classes
  621.                     locate for class==m.cClass .and. classloc==m.cClassLoc
  622.                     if found()
  623.                         m.cBaseClass=baseclass
  624.                         exit
  625.                     endif
  626.                     do case
  627.                     case empty(m.cClassLoc)
  628.                         =Alert(m.cScxName+' record #'+alltrim(str(recno('ScxFile2')))+': '+ ;
  629.                             upper(m.cClass)+' is not a FoxPro base class.')
  630.                         m.lSuccess=.f.
  631.                         exit
  632.                     case !file(m.cClassLoc)
  633.                         =Alert(m.cScxName+' record #'+alltrim(str(recno('ScxFile2')))+': '+ ;
  634.                             'file '+m.cClassLoc+' does not exist.')
  635.                         m.lSuccess=.f.
  636.                         exit
  637.                     otherwise
  638.                         select 0
  639.                         m.cOnError=on('error')
  640.                         on error *
  641.                         use (m.cClassLoc) again
  642.                         on error &cOnError
  643.                         if !empty(alias())
  644.                             locate for reserved1='Class' .and. upper(m.cClass)==upper(objname)
  645.                             if found()
  646.                                 if type('baseclass')='M' .and. !empty(baseclass)
  647.                                     m.cClass=ScxFile2.class
  648.                                     m.cClassLoc=iif(empty(classloc),'',fullpath(classloc))
  649.                                     m.cBaseClass=baseclass
  650.                                     insert into classes ; 
  651.                                         values (m.cClass, m.cClassLoc, m.cBaseClass)
  652.                                     use
  653.                                     exit
  654.                                 else
  655.                                     m.cClass=class
  656.                                     m.cClassLoc=iif(empty(classloc),'',fullpath(classloc))
  657.                                     use
  658.                                     loop
  659.                                 endif
  660.                             else
  661.                                 =Alert(m.cScxName+' record #'+alltrim(str(recno('ScxFile2')))+': '+ ;
  662.                                     'unable to locate class '+upper(m.cClass)+' in '+dbf()+'.')
  663.                                 m.lSuccess=.f.
  664.                                 use
  665.                                 exit
  666.                             endif
  667.                         else
  668.                             =Alert(m.cScxName+' record #'+alltrim(str(recno('ScxFile2')))+': '+ ;
  669.                                 'an error occurred opening '+m.cClassLoc+'.')
  670.                             m.lSuccess=.f.
  671.                             exit
  672.                         endif
  673.                     endcase
  674.                 enddo
  675.                 if !m.lSuccess
  676.                     exit
  677.                 endif
  678.                 if empty(m.cBaseClass)
  679.                     =Alert(m.cScxName+' record #'+alltrim(str(recno('ScxFile2')))+': '+ ;
  680.                         'unable to determine BASECLASS.')
  681.                     exit
  682.                     && let the user pick a class?
  683.                 endif
  684.                 select ScxFile2
  685.                 replace baseclass with m.cBaseClass
  686.             endscan
  687.             if !m.lSuccess
  688.                 exit
  689.             endif
  690.             m.iVersion = .011
  691.             =UpdateVersion('VERSION =  0.011')
  692.             
  693.         case m.iVersion = .011
  694.             
  695.             && BASECLASS field in .SCX/.VCX was written with default name, not class name--
  696.             && change default control names to class names.
  697.             
  698.             replace baseclass with 'commandbutton' for 'command'=lower(baseclass)
  699.             replace baseclass with 'listbox' for 'list'=lower(baseclass)
  700.             replace baseclass with 'combobox' for 'combo'=lower(baseclass)
  701.             replace baseclass with 'editbox' for 'edit'=lower(baseclass)
  702.             replace baseclass with 'textbox' for 'text'=lower(baseclass)
  703.             replace baseclass with 'checkbox' for 'check'=lower(baseclass)
  704.             
  705.             scan for empty(classloc) .and. !empty(class)
  706.                 m.cUpdatedProperties=''
  707.                 _mline=0
  708.                 for m.i=1 to memlines(properties)
  709.                     m.cLine=mline(properties,1,_mline)
  710.                     if empty(m.cLine)
  711.                         loop
  712.                     endif
  713.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  714.                     m.cProperty=strtran(m.cProperty,'Commandbutton','Command')
  715.                     m.cProperty=strtran(m.cProperty,'Optionbutton','Option')
  716.                     m.cProperty=strtran(m.cProperty,'Listbox','List')
  717.                     m.cProperty=strtran(m.cProperty,'Combobox','Combo')
  718.                     m.cProperty=strtran(m.cProperty,'Editbox','Edit')
  719.                     m.cProperty=strtran(m.cProperty,'Textbox','Text')
  720.                     m.cProperty=strtran(m.cProperty,'Checkbox','Check')
  721.                     m.cUpdatedProperties=m.cUpdatedProperties+ ;
  722.                         m.cProperty+' '+substr(m.cLine,at('=',m.cLine))+c_crlf
  723.                 endfor
  724.                 replace properties with m.cUpdatedProperties
  725.                 
  726.             endscan
  727.             m.iVersion=.012
  728.             =UpdateVersion('VERSION =  0.012')
  729.         case m.iVersion = .012
  730.             scan for Reserved1<>'Class' .and. !empty(reserved1)
  731.                 replace declares2 with reserved1
  732.                 replace reserved1 with ''
  733.             endscan
  734.             m.iVersion=.013
  735.             =UpdateVersion('VERSION =  0.013')
  736.             
  737.         case m.iVersion = .013 .and. OkToBuild(208)
  738.         
  739.             && rename the CONTROLS class to CONTAINER
  740.             
  741.             replace class with 'container' for lower(class)='controls'
  742.             replace baseclass with 'container' for lower(baseclass)='controls'
  743.             
  744.             m.iVersion=.014
  745.             =UpdateVersion('VERSION =  0.014')
  746.         
  747.         case m.iVersion = .014 .and. OkToBuild(209)
  748.         
  749.             && Rename Bitmap property to Picture
  750.             
  751.             scan for 'Bitmap'$properties
  752.                 m.cUpdatedProperties=''
  753.                 _mline=0
  754.                 for m.i=1 to memlines(properties)
  755.                     m.cLine=mline(properties,1,_mline)
  756.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  757.                     do case
  758.                     case empty(m.cLine)
  759.                         loop
  760.                     case 'Bitmap' $ m.cProperty
  761.                         m.cProperty=strtran(m.cProperty,'Bitmap','Picture')
  762.                         m.cUpdatedProperties = m.cUpdatedProperties + m.cProperty + ' ' + ;
  763.                             substr(m.cLine,at('=',m.cLine)) + c_crlf
  764.                     otherwise
  765.                         m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  766.                     endcase
  767.                 endfor
  768.                 replace properties with m.cUpdatedProperties
  769.             endscan
  770.             
  771.             && Remove Control0 references
  772.             
  773.             scan for inlist(baseclass,'commandgroup','optiongroup','pageframe')
  774.                 m.cUpdatedProperties=''
  775.                 _mline=0
  776.                 for m.i=1 to memlines(properties)
  777.                     m.cLine=mline(properties,1,_mline)
  778.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  779.                     do case
  780.                     case empty(m.cLine)
  781.                         loop
  782.                     case baseclass='commandgroup' .and. 'Command0.'$m.cProperty
  783.                         loop
  784.                     case baseclass='optiongroup' .and. 'Option0.'$m.cProperty
  785.                         loop
  786.                     case baseclass='pageframe' .and. 'Formpage0.'$m.cProperty
  787.                         loop
  788.                     otherwise
  789.                         if baseclass='pageframe'
  790.                             m.cProperty=strtran(m.cProperty,'Formpage','Page')
  791.                             m.cUpdatedProperties=m.cUpdatedProperties+m.cProperty+' '+ ;
  792.                                 substr(m.cLine,at('=',m.cLine))+c_crlf
  793.                         else
  794.                             m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  795.                         endif
  796.                     endcase
  797.                 endfor
  798.                 replace properties with m.cUpdatedProperties
  799.             endscan
  800.             
  801.             m.iVersion = .015
  802.             =UpdateVersion('VERSION =  0.015')
  803.  
  804.         case m.iVersion = .015 .and. OkToBuild(227)
  805.         
  806.             && Rename properties:
  807.             &&        Pageframe.Pages to Pageframe.NumPages
  808.             &&        Grid.Columns to Grid.NumColumns
  809.             &&        Commandgroup.Buttons to Commandgroup.NumButtons
  810.             &&        Optiongroup.Buttons to Optiongroup.Buttons
  811.             
  812.             scan for inlist(baseclass,'pageframe','grid','commandgroup','optiongroup')
  813.                 m.cUpdatedProperties=''
  814.                 _mline=0
  815.                 for m.i=1 to memlines(properties)
  816.                     m.cLine=mline(properties,1,_mline)
  817.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  818.                     do case
  819.                     case empty(m.cLine)
  820.                         loop
  821.                     case baseclass='pageframe' .and. m.cProperty=='Pages'
  822.                         m.cUpdatedProperties=m.cUpdatedProperties+'NumPages '+ ;
  823.                             substr(m.cLine,at('=',m.cLine))+c_crlf
  824.                     case baseclass='grid' .and. m.cProperty=='Columns'
  825.                         m.cUpdatedProperties=m.cUpdatedProperties+'NumColumns '+ ;
  826.                             substr(m.cLine,at('=',m.cLine))+c_crlf
  827.                     case inlist(baseclass,'commandgroup','optiongroup') ;
  828.                         .and. m.cProperty=='Buttons'
  829.                             m.cUpdatedProperties=m.cUpdatedProperties+'NumButtons '+ ;
  830.                                 substr(m.cLine,at('=',m.cLine))+c_crlf
  831.                     otherwise
  832.                         m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  833.                     endcase
  834.                 endfor
  835.                 replace properties with m.cUpdatedProperties
  836.             endscan
  837.             
  838.             m.iVersion = .016
  839.             =UpdateVersion('VERSION =  0.016')
  840.         case m.iVersion = .016 .and. OkToBuild(240)
  841.         
  842.             && Rename methods:
  843.             &&    grid.column.GOTRESIZED is now RESIZED
  844.             &&    grid.column.GOTMOVED is now MOVED
  845.             &&    grid.DELETE is now DELETED
  846.             
  847.             && Rename properties:
  848.             &&    grid.NUMCOLUMNS is now COLUMNCOUNT
  849.  
  850.             scan for baseclass='grid'
  851.                 m.cUpdatedProperties=''
  852.                 _mline=0
  853.                 for m.i=1 to memlines(properties)
  854.                     m.cLine=mline(properties,1,_mline)
  855.                     if empty(m.cLine)
  856.                         loop
  857.                     endif
  858.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  859.                     if m.cProperty=='NumColumns'
  860.                         m.cUpdatedProperties=m.cUpdatedProperties+'ColumnCount '+ ;
  861.                             substr(m.cLine,at('=',m.cLine))+c_crlf
  862.                     else
  863.                         m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  864.                     endif
  865.                 endfor
  866.                 replace properties with m.cUpdatedProperties
  867.                 
  868.                 m.cUpdatedMethods = ''
  869.                 _mline = 0
  870.                 for m.i = 1 to memlines(methods)
  871.                     m.cLine = mline(methods, 1, _mline)
  872.                     if left(m.cLine, 10) == 'PROCEDURE '
  873.                         m.cProcedure = substr(m.cLine, 11)
  874.                         do case
  875.                         case m.cProcedure == 'Delete'
  876.                             m.cUpdatedMethods = m.cUpdatedMethods + ;
  877.                                 'PROCEDURE Deleted' + c_crlf
  878.                         case occurs('.GotMoved', m.cProcedure) = 1
  879.                             m.cUpdatedMethods = m.cUpdatedMethods + ;
  880.                                 strtran(m.cLine, '.GotMoved', '.Moved') + c_crlf
  881.                         case occurs('.GotResized', m.cProcedure) = 1
  882.                             m.cUpdatedMethods = m.cUpdatedMethods + ;
  883.                                 strtran(m.cLine, '.GotResized', '.Resized') + c_crlf
  884.                         otherwise
  885.                             m.cUpdatedMethods = m.cUpdatedMethods + m.cLine + c_crlf
  886.                         endcase
  887.                     else
  888.                         m.cUpdatedMethods = m.cUpdatedMethods + m.cLine + c_crlf
  889.                     endif
  890.                 endfor
  891.                 * strip off extra crlf
  892.                 if right(m.cUpdatedMethods,4) = c_crlf + c_crlf
  893.                     m.cUpdatedMethods = ;
  894.                         left(m.cUpdatedMethods, len(m.cUpdatedMethods) - len(c_crlf))
  895.                 endif
  896.                 replace methods with m.cUpdatedMethods
  897.             endscan
  898.             
  899.     
  900.             m.iVersion = .017
  901.             =UpdateVersion('VERSION =  0.017')
  902.         case m.iVersion = .017 .and. OkToBuild(245)
  903.  
  904.             && Rename the Grid.SourceType property to Grid.DataSourceType
  905.             
  906.             scan for baseclass='grid'
  907.                 m.cUpdatedProperties=''
  908.                 _mline=0
  909.                 for m.i=1 to memlines(properties)
  910.                     m.cLine=mline(properties,1,_mline)
  911.                     if empty(m.cLine)
  912.                         loop
  913.                     endif
  914.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  915.                     if m.cProperty=='SourceType'
  916.                         m.cUpdatedProperties=m.cUpdatedProperties+'DataSourceType '+ ;
  917.                             substr(m.cLine,at('=',m.cLine))+c_crlf
  918.                     else
  919.                         m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  920.                     endif
  921.                 endfor
  922.                 replace properties with m.cUpdatedProperties
  923.                 
  924.             endscan
  925.             m.iVersion = .018
  926.             =UpdateVersion('VERSION =  0.018')
  927.             
  928.         case m.iVersion = .018 .and. OkToBuild(248)
  929.         
  930.             && Drop the DECLARES and DECLARES2 memo fields. Create a
  931.             && file with DEC extension if code is found in DECLARES.
  932.             
  933.             private m.cDeclares, m.lOverwrite
  934.             m.cDeclares = ''
  935.             scan for !empty(declares)
  936.                 m.cDeclares = m.cDeclares + ;
  937.                     '*** code found in ' + objname + ;
  938.                     '.declares' + c_crlf + c_crlf + declares + c_crlf + c_crlf
  939.             endscan
  940.             
  941.             if !empty(m.cDeclares)
  942.                 m.lOverwrite = .t.
  943.                 if file(forceext(m.cScxName, 'TXT'))
  944.                     if Alert('File ' + m.cScxName + ' contains code in the ' + ;
  945.                         'DECLARES memo field and this field is being removed from ' + ;
  946.                         'the .SCX/.VCX structure. ' + c_crlf + c_crlf + ;
  947.                         '30Update would like to write ' + ;
  948.                         'this code to ' + forceext(m.cScxName, 'TXT') + ', but that ' + ;
  949.                         'file exists. Overwrite the file?', ;
  950.                         MB_YESNO+MB_ICONEXCLAMATION) = 'NO'
  951.                         
  952.                         m.lOverwrite = .f.
  953.                         
  954.                         if Alert('Do you want to continue updating this file? ' + ;
  955.                             'If you continue, the code found in the DECLARES memo ' + ;
  956.                             'field will not be saved.', MB_YESNO + MB_ICONEXCLAMATION) = 'NO'
  957.  
  958.                             m.lSuccess = .f.
  959.                             exit
  960.                         endif
  961.                     endif
  962.                 endif
  963.                 if m.lOverwrite = .t.
  964.                     m.iHandle = fcreate(forceext(m.cScxName, 'TXT'))
  965.                     if m.iHandle = -1
  966.                         =Alert('An error occurred opening ' + ;
  967.                             forceext(m.cScxName, 'TXT') + ;
  968.                             '. This file will be skipped.')
  969.                         m.lSuccess = .f.
  970.                         exit
  971.                     endif
  972.                     =fwrite(m.iHandle, m.cDeclares)
  973.                     =fclose(m.iHandle)
  974.                     ??'Code found in DECLARES written to ' + ;
  975.                         forceext(m.cScxName, 'TXT') + '... '
  976.                 endif
  977.                 replace all declares with '', declares2 with ''
  978.             endif
  979.  
  980.             && Rename properties:
  981.             
  982.             &&    Textbox, Editbox:
  983.             &&        HighForeColor to SelectedForeColor
  984.             &&        HighBackColor to SelectedBackColor
  985.  
  986.             scan for inlist(baseclass, 'textbox', 'editbox')
  987.                 m.cUpdatedProperties=''
  988.                 _mline=0
  989.                 for m.i=1 to memlines(properties)
  990.                     m.cLine=mline(properties,1,_mline)
  991.                     if empty(m.cLine)
  992.                         loop
  993.                     endif
  994.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  995.                     do case
  996.                     case m.cProperty == 'HighForeColor'
  997.                         m.cUpdatedProperties = m.cUpdatedProperties + 'SelectedForeColor ' + ;
  998.                             substr(m.cLine, at('=', m.cLine)) + c_crlf
  999.                     case m.cProperty == 'HighBackColor'
  1000.                         m.cUpdatedProperties = m.cUpdatedProperties + 'SelectedBackColor ' + ;
  1001.                             substr(m.cLine, at('=', m.cLine)) + c_crlf
  1002.                     otherwise
  1003.                         m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  1004.                     endcase
  1005.                 endfor
  1006.                 replace properties with m.cUpdatedProperties
  1007.             endscan
  1008.             
  1009.             m.iVersion = .019
  1010.             =UpdateVersion('VERSION =  0.019')
  1011.  
  1012.         case m.iVersion = .019 .and. OkToBuild(261)
  1013.             
  1014.             * Rename the following properties:
  1015.             
  1016.             *    Pageframe.NumPages to PageCount
  1017.             *    Optiongroup.NumButtons to ButtonCount
  1018.             *    Commandgroup.NumButtons to ButtonCount
  1019.  
  1020.             *    Grid.Column2.Header2 to Grid.Column2.Header1
  1021.             *    Grid.Column3.Header3 to Grid.Column3.Header1
  1022.             
  1023.             scan for inlist(baseclass, 'pageframe', 'optiongroup', 'commandgroup', 'grid')
  1024.                 m.cUpdatedProperties=''
  1025.                 _mline=0
  1026.                 for m.i=1 to memlines(properties)
  1027.                     m.cLine=mline(properties,1,_mline)
  1028.                     if empty(m.cLine)
  1029.                         loop
  1030.                     endif
  1031.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  1032.                     do case
  1033.                     case baseclass = 'pageframe' .and. m.cProperty == 'NumPages'
  1034.                         m.cUpdatedProperties = m.cUpdatedProperties + 'PageCount ' + ;
  1035.                             substr(m.cLine, at('=', m.cLine)) + c_crlf
  1036.                     case inlist(baseclass, 'optiongroup', 'commandgroup') .and. ;
  1037.                         m.cProperty == 'NumButtons'
  1038.                         m.cUpdatedProperties = m.cUpdatedProperties + 'ButtonCount ' + ;
  1039.                             substr(m.cLine, at('=', m.cLine)) + c_crlf
  1040.                     case baseclass = 'grid' .and. 'Column' $ m.cProperty .and. ;
  1041.                         '.Header' $ m.cProperty
  1042.                         m.cHeader = substr(m.cProperty, at('.', m.cProperty))
  1043.                         m.cHeader = left(m.cHeader, at('.', m.cHeader, 2))
  1044.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1045.                             strtran(m.cProperty, m.cHeader, '.Header1.') + ' ' +;
  1046.                             substr(m.cLine, at('=', m.cLine)) + c_crlf
  1047.                     otherwise
  1048.                         m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  1049.                     endcase
  1050.                 endfor
  1051.                 replace properties with m.cUpdatedProperties
  1052.             endscan
  1053.  
  1054.             m.iVersion = .020
  1055.             =UpdateVersion('VERSION =  0.020')
  1056.             
  1057.         case m.iVersion = .020 .and. OkToBuild(270)
  1058.             * Remove Cursor.WorkArea and Cursor.SourceType from properties
  1059.             * Remove ClassLibrary property from properties
  1060.             * Rename "datanavigation" class to "dataenvironment"
  1061.             
  1062.             * Default name changed from DataNavigation to DataEnvironment
  1063.             * (existing objects are not renamed--this is information only)
  1064.             
  1065.             replace baseclass with "dataenvironment" for baseclass = "datanavigation"
  1066.             replace class with "dataenvironment" for class = "datanavigation" .and. ;
  1067.                 baseclass = "dataenvironment"
  1068.                 
  1069.             scan for baseclass = "cursor"
  1070.                 m.cUpdatedProperties=''
  1071.                 _mline=0
  1072.                 for m.i=1 to memlines(properties)
  1073.                     m.cLine=mline(properties,1,_mline)
  1074.                     if empty(m.cLine)
  1075.                         loop
  1076.                     endif
  1077.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  1078.                     if inlist(m.cProperty, "WorkArea", "SourceType")
  1079.                         loop
  1080.                     else
  1081.                         m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  1082.                     endif
  1083.                 endfor
  1084.                 replace properties with m.cUpdatedProperties
  1085.             endscan
  1086.  
  1087.             scan for "ClassLocation = " $ properties
  1088.                 m.cUpdatedProperties=''
  1089.                 _mline=0
  1090.                 for m.i=1 to memlines(properties)
  1091.                     m.cLine=mline(properties,1,_mline)
  1092.                     if empty(m.cLine)
  1093.                         loop
  1094.                     endif
  1095.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  1096.                     if m.cProperty = "ClassLocation"
  1097.                         loop
  1098.                     else
  1099.                         m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  1100.                     endif
  1101.                 endfor
  1102.                 replace properties with m.cUpdatedProperties
  1103.             endscan
  1104.  
  1105.             m.iVersion = .021
  1106.             =UpdateVersion('VERSION =  0.021')
  1107.  
  1108.         case m.iVersion = .021 .and. OkToBuild(275)
  1109.             
  1110.             * Rename the Pageframe.ActiveFormPage property to ActivePage
  1111.             
  1112.             scan for inlist(baseclass, 'pageframe')
  1113.                 m.cUpdatedProperties=''
  1114.                 _mline=0
  1115.                 for m.i=1 to memlines(properties)
  1116.                     m.cLine=mline(properties,1,_mline)
  1117.                     if empty(m.cLine)
  1118.                         loop
  1119.                     endif
  1120.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  1121.                     do case
  1122.                     case baseclass = 'pageframe' .and. m.cProperty == 'ActiveFormPage'
  1123.                         m.cUpdatedProperties = m.cUpdatedProperties + 'ActivePage ' + ;
  1124.                             substr(m.cLine, at('=', m.cLine)) + c_crlf
  1125.                     otherwise
  1126.                         m.cUpdatedProperties=m.cUpdatedProperties+m.cLine+c_crlf
  1127.                     endcase
  1128.                 endfor
  1129.                 replace properties with m.cUpdatedProperties
  1130.             endscan
  1131.  
  1132.             * Rename the Grid.ActiveCell method to Grid.ActivateCell
  1133.             
  1134.             scan for baseclass='grid'
  1135.                 m.cUpdatedMethods = ''
  1136.                 _mline = 0
  1137.                 for m.i = 1 to memlines(methods)
  1138.                     m.cLine = mline(methods, 1, _mline)
  1139.                     if left(m.cLine, 10) == 'PROCEDURE '
  1140.                         m.cProcedure = substr(m.cLine, 11)
  1141.                         do case
  1142.                         case m.cProcedure == 'ActiveCell'
  1143.                             m.cUpdatedMethods = m.cUpdatedMethods + ;
  1144.                                 'PROCEDURE ActivateCell' + c_crlf
  1145.                         otherwise
  1146.                             m.cUpdatedMethods = m.cUpdatedMethods + m.cLine + c_crlf
  1147.                         endcase
  1148.                     else
  1149.                         m.cUpdatedMethods = m.cUpdatedMethods + m.cLine + c_crlf
  1150.                     endif
  1151.                 endfor
  1152.                 * strip off extra crlf
  1153.                 if right(m.cUpdatedMethods,4) = c_crlf + c_crlf
  1154.                     m.cUpdatedMethods = ;
  1155.                         left(m.cUpdatedMethods, len(m.cUpdatedMethods) - len(c_crlf))
  1156.                 endif
  1157.                 replace methods with m.cUpdatedMethods
  1158.             endscan
  1159.             
  1160.             m.iVersion = .022
  1161.             =UpdateVersion('VERSION =  0.022')
  1162.             
  1163.         case m.iVersion = .022 .and. OkToBuild(280)
  1164.         
  1165.             * Rename properties:
  1166.             *
  1167.             *    Class                    Old Name        New Name
  1168.             *    =====                    ========        ========
  1169.             *    Listbox, Combobox        ListSource        RowSource
  1170.             *                            ListSourceType    RowSourceType
  1171.             *
  1172.             *    Grid                    DataSource        RecordSource
  1173.             *                            DataSourceType    RecordSourceType
  1174.             *
  1175.             *    All except Grid            DataSource        ControlSource
  1176.             *    (including Column)
  1177.             *
  1178.             *    Combobox, Listbox        BorderForeColor    BorderColor
  1179.                 
  1180.             scan for !empty(properties)
  1181.                 m.cUpdatedProperties=''
  1182.                 _mline=0
  1183.                 for m.i=1 to memlines(properties)
  1184.                     m.cLine=mline(properties,1,_mline)
  1185.                     if empty(m.cLine)
  1186.                         loop
  1187.                     endif
  1188.                     m.cProperty=alltrim(left(m.cLine,at('=',m.cLine)-1))
  1189.                     do case
  1190.                     case 'DataSource' $ m.cProperty
  1191.                         if baseclass = 'grid'
  1192.                             * This should handle both DataSource and DataSourceType renaming
  1193.                             m.cProperty = strtran(m.cProperty, '.DataSource', '.ControlSource')
  1194.                             m.cProperty = strtran(m.cProperty, 'DataSource', 'RecordSource')
  1195.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1196.                                 m.cProperty + ' '+ substr(m.cLine, at('=', m.cLine)) + c_crlf
  1197.                         else
  1198.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1199.                                 strtran(m.cProperty, 'DataSource', 'ControlSource') + ' ' + ;
  1200.                                 substr(m.cLine, at('=', m.cLine)) + c_crlf
  1201.                         endif
  1202.                     case inlist(baseclass, 'listbox', 'combobox') .and. 'ListSource' $ m.cProperty
  1203.                         * This should handle both ListSource and ListSourceType renaming
  1204.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1205.                             strtran(m.cProperty, 'ListSource', 'RowSource') + ' ' + ;
  1206.                             substr(m.cLine, at('=', m.cLine)) + c_crlf
  1207.                     case inlist(baseclass, 'listbox', 'combobox') .and. 'BorderForeColor' $ m.cProperty
  1208.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1209.                             strtran(m.cProperty, 'BorderForeColor', 'BorderColor') + ' ' + ;
  1210.                             substr(m.cLine, at('=', m.cLine)) + c_crlf
  1211.                     otherwise
  1212.                         m.cUpdatedProperties = m.cUpdatedProperties + m.cLine + c_crlf
  1213.                     endcase
  1214.                 endfor
  1215.                 replace properties with m.cUpdatedProperties
  1216.             endscan
  1217.             
  1218.             m.iVersion = .023
  1219.             =UpdateVersion('VERSION =  0.023')
  1220.         case m.iVersion = .023 .and. OkToBuild(285)
  1221.         
  1222.             && Remove the Shape.Shape property
  1223.             && No attempt is made to maintain the shape of the shape
  1224.             
  1225.             scan for baseclass = 'shape'
  1226.                 m.cUpdatedProperties = ''
  1227.                 _mline=0
  1228.                 for m.i=1 to memlines(properties)
  1229.                     m.cLine = mline(properties, 1, _mline)
  1230.                     if empty(m.cLine)
  1231.                         loop
  1232.                     endif
  1233.                     m.cProperty = alltrim(left(m.cLine, at('=', m.cLine) - 1))
  1234.                     do case
  1235.                     case m.cProperty = 'Shape'
  1236.                         loop
  1237.                     otherwise
  1238.                         m.cUpdatedProperties = m.cUpdatedProperties + m.cLine + c_crlf
  1239.                     endcase
  1240.                 endfor
  1241.                 replace properties with m.cUpdatedProperties
  1242.             endscan
  1243.             
  1244.             m.iVersion = .024
  1245.             =UpdateVersion('VERSION =  0.024')
  1246.  
  1247.         case m.iVersion = .024 .and. OkToBuild(296)
  1248.         
  1249.             * Convert control coordinates so they're relative to the container
  1250.             
  1251.             * Process the file in descending Parent order so we adjust children's coordinates
  1252.             * before we adjust parent's coordinates
  1253.             
  1254.             index on recno() tag recno descending
  1255.             
  1256.             m.lIgnoreError = .f.
  1257.             scan for !empty(baseclass) .and. ;
  1258.                 !inlist(baseclass, 'formset', 'form', 'toolbar', 'dataenvironment', 'header')
  1259.                 
  1260.                 m.lUpdated = .f.
  1261.                 
  1262.                 * if this is an optiongroup or commandgroup, update the coordinates of the
  1263.                 * buttons in the group
  1264.                 if inlist(baseclass, 'optiongroup', 'commandgroup')
  1265.                     m.iGroupTop = val(GetProperty(properties, 'Top'))
  1266.                     m.iGroupLeft = val(GetProperty(properties, 'Left'))
  1267.                     for m.i = 1 to val(GetProperty(properties, 'ButtonCount'))
  1268.                         m.cButtonName = ;
  1269.                             iif(baseclass == 'commandgroup', 'Command', 'Option') + alltrim(str(m.i))
  1270.                         replace properties with PutProperty(properties, m.cButtonName + '.Top', ;
  1271.                             alltrim(str(val(GetProperty(properties, m.cButtonName + '.Top')) - m.iGroupTop)))
  1272.                         replace properties with PutProperty(properties, m.cButtonName + '.Left', ;
  1273.                             alltrim(str(val(GetProperty(properties, m.cButtonName + '.Left')) - m.iGroupLeft)))
  1274.                     endfor
  1275.                 endif
  1276.                 
  1277.                 * if this is a container, update the coordinates of the controls in the container
  1278.                 if inlist(baseclass, 'container')
  1279.                     m.iContainerTop = val(GetProperty(properties, 'Top'))
  1280.                     m.iContainerLeft = val(GetProperty(properties, 'Left'))
  1281.                     
  1282.                     m.cUpdatedProperties = ''
  1283.                     _mline = 0
  1284.                     for m.iLine = memlines(properties) to 1 step -1
  1285.                         m.cLine = mline(properties, m.iLine)
  1286.                         if empty(m.cLine)
  1287.                             loop
  1288.                         endif
  1289.                         m.cProperty = alltrim(left(m.cLine, at('=', m.cLine) - 1))
  1290.                         if '.' $ m.cProperty .and. inlist(substr(m.cProperty, rat('.', m.cProperty) + 1), 'Top', 'Left')
  1291.                             m.iCoord = val(substr(m.cLine, at('=', m.cLine) + 1))
  1292.                             m.cControlName = left(m.cProperty, rat('.', m.cProperty) - 1)
  1293.                             m.cParentName = left(m.cControlName, rat('.', m.cControlName) - 1)
  1294.                             m.cProperty = substr(m.cProperty, rat('.', m.cProperty) + 1)
  1295.                             if !empty(m.cParentName)
  1296.                                 m.iParentCoord = val(GetProperty(properties, m.cParentName + '.' + m.cProperty))
  1297.                             else
  1298.                                 m.iParentCoord = m.iContainer&cProperty
  1299.                             endif
  1300.                             m.cUpdatedProperties = m.cControlName + '.' + m.cProperty + ' = ' + ;
  1301.                                 alltrim(str(m.iCoord -  m.iParentCoord)) + c_crlf + m.cUpdatedProperties
  1302.                         else
  1303.                             m.cUpdatedProperties = m.cLine + c_crlf + m.cUpdatedProperties
  1304.                         endif
  1305.                     endfor
  1306.                     replace properties with m.cUpdatedProperties
  1307.                 endif
  1308.                 
  1309.                 * BugBug: Does the same thing have to be done for toolbars that we've done for
  1310.                 * optiongroups, commandgroups, and containers?
  1311.                 
  1312.                 * Record the record number we'll return to
  1313.                 m.iRecord = recno()
  1314.                 
  1315.                 * Store the parent and objname for this record
  1316.                 m.cParent = alltrim(parent)
  1317.                 m.cObjName = alltrim(objname)
  1318.                 
  1319.                 * Peel off the name of the container of this object
  1320.                 m.cContainer = alltrim(iif('.' $ parent, ;
  1321.                     substr(parent, rat('.', parent) + 1), parent))
  1322.                 
  1323.                 * Store the container's parent
  1324.                 m.cContainerParent = left(m.cParent, rat('.', m.cParent) - 1)
  1325.                 
  1326.                 * Peel off the name of the container's container
  1327.                 m.cContainerContainer = alltrim(iif('.' $ m.cContainerParent, ;
  1328.                     substr(m.cContainerParent, rat('.', m.cContainerParent) + 1), ;
  1329.                     m.cContainerParent))
  1330.                 
  1331.                 * Finally, store the container's container's parent
  1332.                 m.cContainerContainerParent = ;
  1333.                     left(m.cContainerParent, rat('.', m.cContainerParent) - 1)
  1334.                 
  1335.                 skip
  1336.                 do while !eof()
  1337.                     * Is this the container?
  1338.                     if m.cContainer == objname .and. m.cContainerParent == parent
  1339.                         exit
  1340.                     endif
  1341.                 
  1342.                     * Is this the container's container?
  1343.                     if m.cContainerContainer == objname .and. m.cContainerContainerParent == parent
  1344.                         * If this is a pageframe, treat it as the control's container
  1345.                         if baseclass == 'pageframe'
  1346.                             exit
  1347.                         endif
  1348.                         
  1349.                         * If this is a grid, nevermind
  1350.                         if baseclass == 'grid'
  1351.                             m.lUpdated = .t.
  1352.                             exit
  1353.                         endif
  1354.                         
  1355.                     endif
  1356. ***********************************                    
  1357. if .f.
  1358.                     if empty(parent)
  1359.                         * We're at the end of the line for this form/class
  1360.                         * Go back and look for the container's Top and Left properties in the
  1361.                         * containers along the parent
  1362.                         go (m.iRecord)
  1363.                         skip
  1364.                         m.cExact = set('exact')
  1365.                         set exact off
  1366.                         do while !eof()
  1367.                             * is this a container along the parent?
  1368.                             if m.cParent = iif(!empty(parent), alltrim(parent) + '.', '') + alltrim(objname)
  1369.                                 * strip off the objname and look for Top and Left properties
  1370.                                 m.cTempParent = ;
  1371.                                     strtran(m.cParent, iif(!empty(parent), alltrim(parent) + '.', '') + alltrim(objname) + '.')
  1372.                                 if m.cTempParent + '.Top =' $ properties .or. ;
  1373.                                     m.cTempParent + '.Left =' $ properties
  1374.                                     
  1375.                                     * get the parent's top and left coordinates
  1376.                                     m.iParentTop = val(GetProperty(properties, m.cTempParent + '.Top'))
  1377.                                     m.iParentLeft = val(GetProperty(properties, m.cTempParent + '.Left'))
  1378.                                     go (m.iRecord)
  1379.                                     
  1380.                                     * update the child's top and left coordinates using the parent's coordinates
  1381.                                     replace properties with PutProperty(properties, 'Top', ;
  1382.                                         alltrim(str(val(GetProperty(properties, 'Top')) - m.iParentTop)))
  1383.                                     replace properties with PutProperty(properties, 'Left', ;
  1384.                                         alltrim(str(val(GetProperty(properties, 'Left')) - m.iParentLeft)))
  1385.                                     m.lUpdated = .t.
  1386.                                     exit
  1387.                                 endif
  1388.                             endif
  1389.                             if empty(parent)
  1390.                                 * Try one more time, stripping off the control's container (it could
  1391.                                 * be a formpage)
  1392.                                 go (m.iRecord)
  1393.                                 skip
  1394.                                 do while !eof()
  1395.                                     * is this a container along the parent?
  1396.                                     if m.cParent = iif(!empty(parent), alltrim(parent) + '.', '') + alltrim(objname)
  1397.                                         * strip off the objname and innermost container and 
  1398.                                         * look for Top and Left properties
  1399.                                         m.cTempParent = ;
  1400.                                             strtran(m.cParent, iif(!empty(parent), alltrim(parent) + '.', '') + alltrim(objname) + '.')
  1401.                                         m.cTempParent = left(m.cTempParent, rat('.', m.cTempParent) - 1)
  1402.                                         
  1403.                                         if m.cTempParent + '.Top =' $ properties .or. ;
  1404.                                             m.cTempParent + '.Left =' $ properties
  1405.                                             
  1406.                                             * get the parent's top and left coordinates
  1407.                                             m.iParentTop = val(GetProperty(properties, m.cTempParent + '.Top'))
  1408.                                             m.iParentLeft = val(GetProperty(properties, m.cTempParent + '.Left'))
  1409.                                             
  1410.                                             go (m.iRecord)    
  1411.                                             
  1412.                                             * update the child's top and left coordinates using the parent's coordinates
  1413.                                             replace properties with PutProperty(properties, 'Top', ;
  1414.                                                 alltrim(str(val(GetProperty(properties, 'Top')) - m.iParentTop)))
  1415.                                             replace properties with PutProperty(properties, 'Left', ;
  1416.                                                 alltrim(str(val(GetProperty(properties, 'Left')) - m.iParentLeft)))
  1417.                                         
  1418.                                             m.lUpdated = .t.
  1419.                                             exit
  1420.                                         endif
  1421.                                     endif
  1422.                                     
  1423.                                     if empty(parent)
  1424.                                         go bottom
  1425.                                         skip
  1426.                                         exit
  1427.                                     endif
  1428.                                     
  1429.                                     if !eof()
  1430.                                         skip
  1431.                                     endif
  1432.                                 enddo
  1433.                                 if m.lUpdated
  1434.                                     exit
  1435.                                 endif
  1436.                             endif
  1437.                             if !eof()
  1438.                                 skip
  1439.                             endif
  1440.                         enddo
  1441.                         set exact &cExact
  1442.                         if m.lUpdated
  1443.                             exit
  1444.                         endif
  1445.                     endif
  1446. endif
  1447. ***********************************
  1448.                     if !eof()
  1449.                         skip
  1450.                     endif
  1451.                 enddo
  1452.                 
  1453.                 if m.lUpdated
  1454.                     m.lUpdated = .f.
  1455.                     loop
  1456.                 endif
  1457.                 
  1458.                 if !eof()
  1459.                     if !inlist(baseclass, 'formset', 'form', 'toolbar')
  1460.                     
  1461.                         * get the parent's top and left coordinates
  1462.                         m.iParentTop = val(GetProperty(properties, 'Top'))
  1463.                         m.iParentLeft = val(GetProperty(properties, 'Left'))
  1464.                         
  1465.                         * if the control is on a formpage, adjust for the tabs if Tabs = .T.
  1466.                         * we're not attempting to account for the bordersize or specialeffect,
  1467.                         * so this will probably be off a few pixels 
  1468.                         if baseclass == 'pageframe'
  1469.                             if GetProperty(properties, 'Tabs') <> '.F.'
  1470.                                 m.iParentTop = m.iParentTop + 23
  1471.                             endif
  1472.                         endif
  1473.                     
  1474.                         go (m.iRecord)
  1475.                         
  1476.                         * update the child's top and left coordinates using the parent's coordinates
  1477.                         replace properties with PutProperty(properties, 'Top', ;
  1478.                             alltrim(str(val(GetProperty(properties, 'Top')) - m.iParentTop)))
  1479.                         replace properties with PutProperty(properties, 'Left', ;
  1480.                             alltrim(str(val(GetProperty(properties, 'Left')) - m.iParentLeft)))
  1481.                     else
  1482.                         go (m.iRecord)
  1483.                     endif
  1484.                 else
  1485.                     * something's wrong!
  1486.                     go (m.iRecord)
  1487.                     if .not. m.lIgnoreError
  1488.                         if 'YES' = Alert('Record #' + alltrim(str(recno())) + ': ' + alltrim(parent) + ;
  1489.                             iif(!empty(parent), '.', '') + alltrim(objname) + ' parent not found. ' + ;
  1490.                             'Continue updating? (If you answer Yes, further errors will not be displayed. If you '+ ;
  1491.                             'answer No, the file will be skipped.)', MB_ICONEXCLAMATION + MB_YESNO)
  1492.                             m.lIgnoreError = .t.
  1493.                         else
  1494.                             m.lSuccess = .f.
  1495.                             exit
  1496.                         endif
  1497.                     endif
  1498.                 endif
  1499.                 
  1500.             endscan
  1501.             delete tag recno
  1502.  
  1503.             m.iVersion = .025
  1504.             =UpdateVersion('VERSION =  0.025')
  1505.  
  1506.         case m.iVersion = .025 .and. OkToBuild(316)
  1507.  
  1508.             *** Version .026 Modifications ***
  1509.             
  1510.             * Add columns RESERVED6 - RESERVED 10
  1511.             * (this change was made to the CREATE CURSOR at the beginning
  1512.             * of this procedure)
  1513.  
  1514.             scan for !empty(baseclass)
  1515.                 * Move class description to RESERVED7
  1516.                 if m.cType == 'CLASS' .and. empty(parent)
  1517.                     replace reserved7 with comment, comment with '', ;
  1518.                         reserved6 with 'Pixels'
  1519.                 endif
  1520.  
  1521.                 m.cUpdatedProperties = ''
  1522.                 _mline=0
  1523.                 for m.i=1 to memlines(properties)
  1524.                     m.cLine = mline(properties, 1, _mline)
  1525.                     if empty(m.cLine)
  1526.                         loop
  1527.                     endif
  1528.                     m.cProperty = alltrim(left(m.cLine, at('=', m.cLine) - 1))
  1529.                     m.cJustProperty = iif('.' $ m.cProperty, ;
  1530.                         substr(m.cProperty, rat('.', m.cProperty) + 1), ;
  1531.                         m.cProperty)
  1532.                     m.cValue = alltrim(substr(m.cLine, at('=', m.cLine) + 1))    
  1533.                     
  1534.                     do case
  1535.                     
  1536.                     case m.cJustProperty = 'FontTransparent'
  1537.                         * Remove all references to FontTransparent
  1538.                         loop
  1539.                     case m.cJustProperty = 'MultiSession'
  1540.                         * Rename MultiSession property to DataSession
  1541.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1542.                             strtran(m.cProperty, 'MultiSession', 'DataSession') + ;
  1543.                             ' = ' + iif('T' $ upper(m.cValue), '2', '1') + c_crlf
  1544.                     case inlist(baseclass, 'form', 'toolbar') .and. ;
  1545.                         m.cProperty = 'ScaleMode'
  1546.                         * Drop this, we'll add it to the top, below
  1547.                         loop
  1548.                     case inlist(baseclass, 'form') .and. m.cProperty = 'Sizable'
  1549.                         * Drop the Sizable property
  1550.                         loop
  1551.                     case m.cJustProperty = 'ScaleMode'
  1552.                         * Force the ScaleMode to 3 (Pixels)
  1553.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1554.                             m.cProperty + ' = 3' + c_crlf
  1555.                     case m.cJustProperty = 'Index'
  1556.                         * Remove all references to Index property
  1557.                         loop
  1558.                     case m.cJustProperty = 'HideColumns'
  1559.                         * Rename HideColumn property to ColumnLines
  1560.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1561.                             strtran(m.cLine, 'HideColumns', 'ColumnLines') + c_crlf
  1562.                     case inlist(baseclass, 'listbox', 'combobox') .and. ;
  1563.                         m.cJustProperty = 'Columns'
  1564.                         * Rename Columns property to ColumnCount
  1565.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1566.                             strtran(m.cLine, 'Columns', 'ColumnCount') + c_crlf
  1567.                     case m.cJustProperty = 'DecimalPoints'
  1568.                         * Remove all references to DecimalPoints property
  1569.                         loop
  1570.                     case m.cJustProperty = 'AllowTabs'
  1571.                         * Remove AllowTabs references--this is textboxes only,
  1572.                         * but do it always to catch classes.
  1573.                         loop
  1574.                     case m.cJustProperty = 'ButtonIndex'
  1575.                         * Remove ButtonIndex references
  1576.                         loop
  1577.                     case inlist(baseclass, 'container', 'control') .and. ;
  1578.                         m.cJustProperty = 'ControlSource'
  1579.                         * Remove ControlSource references
  1580.                         loop
  1581.                     case m.cJustProperty = 'ColorScheme'
  1582.                         * Force the ColorScheme to a valid value
  1583.                         do case
  1584.                         case val(m.cValue) < 1
  1585.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1586.                                 m.cProperty + ' = 1' + c_crlf
  1587.                         case val(m.cValue) > 24
  1588.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1589.                                 m.cProperty + ' = 24' + c_crlf
  1590.                         otherwise
  1591.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1592.                                 m.cLine + c_crlf
  1593.                         endcase
  1594.                     case m.cJustProperty = 'BoundColumn'
  1595.                         * Force the BoundColumn to a valid value
  1596.                         do case
  1597.                         case val(m.cValue) < 1
  1598.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1599.                                 m.cProperty + ' = 1' + c_crlf
  1600.                         otherwise
  1601.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1602.                                 m.cLine + c_crlf
  1603.                         endcase
  1604.                     case m.cJustProperty = 'Margin'
  1605.                         * Force the Margin to a valid value
  1606.                         do case
  1607.                         case val(m.cValue) < 0
  1608.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1609.                                 m.cProperty + ' = 0' + c_crlf
  1610.                         otherwise
  1611.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1612.                                 m.cLine + c_crlf
  1613.                         endcase
  1614.                     case m.cJustProperty = 'ColorSource'
  1615.                         * Force the ColorSource to a valid value (0 - 3)
  1616.                         do case
  1617.                         case val(m.cValue) < 0
  1618.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1619.                                 m.cProperty + ' = 0' + c_crlf
  1620.                         case val(m.cValue) > 3
  1621.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1622.                                 m.cProperty + ' = 3' + c_crlf
  1623.                         otherwise
  1624.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1625.                                 m.cLine + c_crlf
  1626.                         endcase
  1627.                     case m.cJustProperty = 'Stretch'
  1628.                         * Change .F. to 0, .T. to 1
  1629.                         if lower(m.cValue) = '.f.'
  1630.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1631.                                 m.cProperty + ' = 0' + c_crlf
  1632.                         else
  1633.                             m.cUpdatedProperties = m.cUpdatedProperties + ;
  1634.                                 m.cProperty + ' = 1' + c_crlf
  1635.                         endif                        
  1636.                     otherwise
  1637.                         m.cUpdatedProperties = m.cUpdatedProperties + m.cLine + c_crlf
  1638.                     endcase
  1639.                     
  1640.                 endfor
  1641.                 
  1642.                 if inlist(baseclass, 'form', 'toolbar')
  1643.                     * Add "ScaleMode = 3" to the top of the properties
  1644.                     m.cUpdatedProperties = "ScaleMode = 3" + c_crlf + m.cUpdatedProperties
  1645.                 endif
  1646.  
  1647.                 replace properties with m.cUpdatedProperties
  1648.             
  1649.             endscan
  1650.             
  1651.             * Re-format Reserved3 and write Protected properties/methods to Protected
  1652.             scan for !empty(Reserved3)
  1653.                 m.cReserved3 = ''
  1654.                 m.cProtected = ''
  1655.                 
  1656.                 _mline=0
  1657.                 for m.i=1 to memlines(reserved3)
  1658.                     m.cLine = mline(reserved3, 1, _mline)
  1659.                     if empty(m.cLine)
  1660.                         loop
  1661.                     endif
  1662.                     m.lProtected = .f.
  1663.                     if left(m.cLine, 10) == 'PROTECTED '
  1664.                         m.cLine = substr(m.cLine, 11)
  1665.                         m.lProtected = .t.
  1666.                     endif
  1667.                     do case
  1668.                     case left(m.cLine, 1) = '*'
  1669.                     case '=' $ m.cLine
  1670.                         m.cLine = alltrim(left(m.cLine, at('=', m.cLine) - 1))
  1671.                     otherwise
  1672.                         loop
  1673.                     endcase
  1674.                     m.cReserved3 = m.cReserved3 + m.cLine + c_crlf
  1675.                     if m.lProtected
  1676.                         m.cProtected = m.cProtected + m.cLine + c_crlf
  1677.                     endif
  1678.                 endfor
  1679.                 replace reserved3 with m.cReserved3, protected with m.cProtected
  1680.             endscan
  1681.             
  1682.             m.iVersion = .026
  1683.             =UpdateVersion('VERSION =  0.026')
  1684.  
  1685.         case m.iVersion = .026 .and. OkToBuild(336)
  1686.  
  1687.             *** Version .027 Modifications ***
  1688.  
  1689.             scan for !empty(baseclass)
  1690.                 m.cUpdatedProperties = ''
  1691.                 _mline=0
  1692.                 for m.i = 1 to memlines(properties)
  1693.                     m.cLine = mline(properties, 1, _mline)
  1694.                     if empty(m.cLine)
  1695.                         loop
  1696.                     endif
  1697.                     m.cProperty = alltrim(left(m.cLine, at('=', m.cLine) - 1))
  1698.                     m.cJustProperty = iif('.' $ m.cProperty, ;
  1699.                         substr(m.cProperty, rat('.', m.cProperty) + 1), ;
  1700.                         m.cProperty)
  1701.                     m.cValue = alltrim(substr(m.cLine, at('=', m.cLine) + 1))    
  1702.                     
  1703.                     do case
  1704.                     case m.cJustProperty = 'Visible'
  1705.                         * Remove Formpage.Visible property.
  1706.                         * Look for "Page9." preceding the property name
  1707.                         
  1708.                         if '.' $ m.cProperty
  1709.                             m.cControl = left(m.cProperty, rat('.', m.cProperty) - 1)
  1710.                             if '.' $ m.cControl
  1711.                                 m.cControl = substr(m.cControl, rat('.', m.cControl) + 1)
  1712.                             endif
  1713.                             if left(m.cControl, 4) = 'Page' .and. isdigit(substr(m.cControl, 5, 1))
  1714.                                 loop
  1715.                             endif
  1716.                         endif
  1717.                         * Otherwise, keep the property
  1718.                         m.cUpdatedProperties = m.cUpdatedProperties + m.cLine + c_crlf
  1719.                     
  1720.                     case m.cJustProperty = 'ParentIndexExpr'
  1721.                         * Relation property renamed to RelationalExpr (not used elsewhere)
  1722.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1723.                             strtran(m.cLine, 'ParentIndexExpr = ', 'RelationalExpr = ') + ;
  1724.                             c_crlf
  1725.  
  1726.                     case m.cJustProperty = 'ChildIndexTag'
  1727.                         * Relation property renamed to ChildOrder (not used elsewhere)
  1728.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1729.                             strtran(m.cLine, 'ChildIndexTag = ', 'ChildOrder = ') + ;
  1730.                             c_crlf
  1731.  
  1732.                     otherwise
  1733.                         m.cUpdatedProperties = m.cUpdatedProperties + m.cLine + c_crlf
  1734.                     endcase
  1735.                     
  1736.                 endfor
  1737.                 
  1738.                 replace properties with m.cUpdatedProperties
  1739.  
  1740.             endscan
  1741.             
  1742.             scan for baseclass='grid'
  1743.                 m.cUpdatedMethods = ''
  1744.                 _mline = 0
  1745.                 for m.i = 1 to memlines(methods)
  1746.                     m.cLine = mline(methods, 1, _mline)
  1747.                     if left(m.cLine, 10) == 'PROCEDURE '
  1748.                         m.cProcedure = substr(m.cLine, 11)
  1749.                         do case
  1750.                         case m.cProcedure == 'ActiveCell'
  1751.                             m.cUpdatedMethods = m.cUpdatedMethods + ;
  1752.                                 'PROCEDURE ActivateCell' + c_crlf
  1753.                         otherwise
  1754.                             m.cUpdatedMethods = m.cUpdatedMethods + m.cLine + c_crlf
  1755.                         endcase
  1756.                     else
  1757.                         m.cUpdatedMethods = m.cUpdatedMethods + m.cLine + c_crlf
  1758.                     endif
  1759.                 endfor
  1760.                 * strip off extra crlf
  1761.                 if right(m.cUpdatedMethods,4) = c_crlf + c_crlf
  1762.                     m.cUpdatedMethods = ;
  1763.                         left(m.cUpdatedMethods, len(m.cUpdatedMethods) - len(c_crlf))
  1764.                 endif
  1765.                 replace methods with m.cUpdatedMethods
  1766.             endscan
  1767.  
  1768.             m.iVersion = .027
  1769.             =UpdateVersion('VERSION =  0.027')
  1770.  
  1771.         case m.iVersion = .027 .and. OkToBuild(344)
  1772.             
  1773.             m.cExact = set('exact')
  1774.             set exact on
  1775.             
  1776.             *** Version .028 Modifications ***
  1777.  
  1778.             scan for !empty(baseclass)
  1779.                 m.cUpdatedProperties = ''
  1780.                 _mline=0
  1781.                 for m.i = 1 to memlines(properties)
  1782.                     m.cLine = mline(properties, 1, _mline)
  1783.                     if empty(m.cLine)
  1784.                         loop
  1785.                     endif
  1786.                     m.cProperty = alltrim(left(m.cLine, at('=', m.cLine) - 1))
  1787.                     m.cJustProperty = iif('.' $ m.cProperty, ;
  1788.                         substr(m.cProperty, rat('.', m.cProperty) + 1), ;
  1789.                         m.cProperty)
  1790.                     m.cValue = alltrim(substr(m.cLine, at('=', m.cLine) + 1))    
  1791.                     
  1792.                     do case
  1793.                     
  1794.                     * Form Changes
  1795.                     *         Delete method dropped
  1796.                     *        PrintForm method dropped
  1797.                     case inlist(m.cJustProperty, 'AutoRedraw', 'RecordSelector', ;
  1798.                         'RecordLocks', 'GoFirst', 'GoLast', 'Skip', 'SkipForm', 'Window')
  1799.                         
  1800.                         * The AutoRedraw, RecordSelector, RecordLocks, and
  1801.                         * Window properties are dropped.
  1802.                         * The GoFirst, GoLast, Skip, and SkipForm properties are hidden
  1803.                         * and shouldn't appear in the form/class.
  1804.                         
  1805.                         loop
  1806.  
  1807.                     * Cursor Changes
  1808.                     *        FilterCondition (Property or Method?) dropped
  1809.                     *        Add NoDataOnLoad property
  1810.                     case m.cJustProperty = 'FilterCondition' && in case it's a property
  1811.                         loop
  1812.                     case m.cJustProperty = 'Updateable'
  1813.                         * Rename to ReadOnly and reverse value
  1814.                         if m.cValue = '.F.'
  1815.                             m.cValue = '.T.'
  1816.                         else
  1817.                             m.cValue = '.F.'
  1818.                         endif
  1819.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1820.                             left(m.cProperty, rat('Updateable', m.cProperty) - 1) + ;
  1821.                             'ReadOnly = ' + m.cValue + c_crlf
  1822.                     
  1823.                     * Data Environment Changes
  1824.                     *         Add DEUnload event
  1825.                     case m.cJustProperty = 'AutoLoadEnv'
  1826.                         * Rename to AutoOpenTables
  1827.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1828.                             left(m.cProperty, rat('AutoLoadEnv', m.cProperty) - 1) + ;
  1829.                             'AutoOpenTables = ' + m.cValue + c_crlf
  1830.                     case m.cJustProperty = 'AutoUnloadEnv'
  1831.                         * Rename to AutoCloseTables
  1832.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1833.                             left(m.cProperty, rat('AutoUnloadEnv', m.cProperty) - 1) + ;
  1834.                             'AutoCloseTables = ' + m.cValue + c_crlf
  1835.                     
  1836.                     * Relation Changes
  1837.                     *        Add OneToMany property
  1838.                     case m.cJustProperty = 'ChildIndexTag'
  1839.                         * Rename to ChildOrder
  1840.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1841.                             left(m.cProperty, rat('ChildIndexTag', m.cProperty) - 1) + ;
  1842.                             'ChildOrder = ' + m.cValue + c_crlf
  1843.                     case m.cJustProperty = 'ParentIndexExpr'
  1844.                         * Rename to RelationalExpr
  1845.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1846.                             left(m.cProperty, rat('ParentIndexExpr', m.cProperty) - 1) + ;
  1847.                             'RelationalExpr = ' + m.cValue + c_crlf
  1848.                     
  1849.                     * Spinner Changes
  1850.                     *         Clear method dropped
  1851.                     
  1852.                     * Shape Changes
  1853.                     *        Add FillColor property
  1854.                     *         Add BackColor property
  1855.                     *        Add Enabled property
  1856.                     
  1857.                     * Grid Changes
  1858.                     *         Add AfterRowColChange(cColName) method
  1859.                     *        Add DynamicFontOutline, DynamicFontShadow, DynamicFontStrikethru, 
  1860.                     *            DynamicFontUnderline, and ReadOnly properties
  1861.                     *        Add DynamicFontBold and DynamicFontItalic properties
  1862.                     case m.cJustProperty = 'Relation'
  1863.                         * Rename to RelationalExpr
  1864.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1865.                             left(m.cProperty, rat('Relation', m.cProperty) - 1) + ;
  1866.                             'RelationalExpr = ' + m.cValue + c_crlf
  1867.                     case m.cJustProperty = 'DynamicFontStyle'
  1868.                         * Dropped
  1869.                         loop
  1870.                         
  1871.                     * Column Changes
  1872.                     *         Add ColumnOrder,  DynamicFontOutline, DynamicFontShadow, 
  1873.                     *            DynamicFontStrikethru, and DynamicFontUnderline properties
  1874.                     
  1875.                     * Textbox Changes
  1876.                     *        Add PasswordChar and Style properties
  1877.                     
  1878.                     * Image Changes
  1879.                     *        Add Enabled property
  1880.                     case m.cJustProperty = 'Stretch'
  1881.                         * Changing from logical to numeric. Actually changed prior to build 343,
  1882.                         * so leave alone if it's not a logical.
  1883.                         do case
  1884.                         case m.cValue = '.T.'
  1885.                             m.cValue = '2'
  1886.                         case m.cValue = '.F.'
  1887.                             m.cValue = '0'
  1888.                         endcase
  1889.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1890.                             m.cProperty + ' = ' + m.cValue + c_crlf
  1891.                         
  1892.                     * Line Changes
  1893.                     *         Add Enabled property
  1894.                     case m.cJustProperty = 'ForeColor' .and. baseclass = 'line'
  1895.                         * Rename to BorderColor. Since we're doing this only for
  1896.                         * line controls, subclassed lines may get broken.
  1897.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1898.                             left(m.cProperty, rat('ForeColor', m.cProperty) - 1) + ;
  1899.                             'BorderColor = ' + m.cValue + c_crlf
  1900.                     case m.cJustProperty = 'LineSlant'
  1901.                         * Change from numeric to character
  1902.                         if m.cValue = '0'
  1903.                             m.cValue = '"/"'
  1904.                         else
  1905.                             m.cValue = '"\"'
  1906.                         endif
  1907.                         m.cUpdatedProperties = m.cUpdatedProperties + ;
  1908.                             m.cProperty + ' = ' + m.cValue + c_crlf
  1909.                     
  1910.                     * Label Changes
  1911.                     *         Add Enabled property
  1912.                     
  1913.                     * Pageframe Changes
  1914.                     case m.cJustProperty = 'TabWidth'
  1915.                         * Dropped
  1916.                         loop
  1917.                         
  1918.                     otherwise
  1919.                         m.cUpdatedProperties = m.cUpdatedProperties + m.cLine + c_crlf
  1920.                     endcase
  1921.                     
  1922.                 endfor
  1923.                 
  1924.                 replace properties with m.cUpdatedProperties
  1925.             
  1926.                 m.cUpdatedMethods = ''
  1927.                 _mline=0
  1928.                 for m.i = 1 to memlines(methods)
  1929.                     m.cLine = mline(methods, 1, _mline)
  1930.                     if empty(m.cLine) .or. upper(left(m.cLine, 10)) <> 'PROCEDURE '
  1931.                         * Maintain blank lines in code
  1932.                         m.cUpdatedMethods = m.cUpdatedMethods + m.cLine + c_crlf
  1933.                         loop
  1934.                     endif
  1935.                     m.cMethod = alltrim(substr(m.cLine, at(' ', m.cLine) + 1))
  1936.                     m.cJustMethod = iif('.' $ m.cMethod, ;
  1937.                         substr(m.cMethod, rat('.', m.cMethod) + 1), ;
  1938.                         m.cMethod)
  1939.                     
  1940.                     do case
  1941.                     
  1942.                     * Column Changes
  1943.                     case m.cJustMethod = 'Move' .and. baseclass = 'grid'
  1944.                         * Rename to Moved--since we're renaming just the grid control,
  1945.                         * there will be some errors in subclassed controls.
  1946.                         m.cUpdatedMethods = m.cUpdatedMethods + 'PROCEDURE ' + ;
  1947.                             left(m.cMethod, rat('Move', m.cMethod) - 1) + ;
  1948.                             'Moved' + c_crlf
  1949.                     
  1950.                     * Grid Changes
  1951.                     case m.cJustMethod = 'RowColChange'
  1952.                         * Rename to BeforeRowColChange and add required 
  1953.                         * Parameters nColIndex statement
  1954.                         m.cUpdatedMethods = m.cUpdatedMethods + 'PROCEDURE ' + ;
  1955.                             left(m.cMethod, rat('RowColChange', m.cMethod) - 1) + ;
  1956.                             'BeforeRowColChange' + c_crlf + ;
  1957.                             'Parameters nColIndex' + c_crlf
  1958.                     case m.cJustMethod = 'Deleted'
  1959.                         * Now requires nRecNo parameter
  1960.                         m.cUpdatedMethods = m.cUpdatedMethods + ;
  1961.                             m.cLine + c_crlf + 'Parameters nRecNo' + c_crlf
  1962.                     
  1963.                     * DataEnvironment Changes
  1964.                     case m.cJustMethod = 'AfterAllTablesOpened'
  1965.                         * Rename to DELoad
  1966.                         m.cUpdatedMethods = m.cUpdatedMethods + 'PROCEDURE ' + ;
  1967.                             left(m.cMethod, rat('AfterAllTablesOpened', m.cMethod) - 1) + ;
  1968.                             'DELoad' + c_crlf
  1969.                     case m.cJustMethod = 'LoadEnv'
  1970.                         * Rename to LoadDE
  1971.                         m.cUpdatedMethods = m.cUpdatedMethods + 'PROCEDURE ' + ;
  1972.                             left(m.cMethod, rat('LoadEnv', m.cMethod) - 1) + ;
  1973.                             'LoadDE' + c_crlf
  1974.                     case m.cJustMethod = 'UnloadEnv'
  1975.                         * Rename to UnloadDE
  1976.                         m.cUpdatedMethods = m.cUpdatedMethods + 'PROCEDURE ' + ;
  1977.                             left(m.cMethod, rat('UnloadEnv', m.cMethod) - 1) + ;
  1978.                             'UnloadDE' + c_crlf
  1979.                     
  1980.                     otherwise
  1981.                         m.cUpdatedMethods = m.cUpdatedMethods + m.cLine + c_crlf
  1982.                     endcase
  1983.                 endfor
  1984.                 
  1985.                 * strip off extra crlf
  1986.                 if right(m.cUpdatedMethods,4) = c_crlf + c_crlf
  1987.                     m.cUpdatedMethods = ;
  1988.                         left(m.cUpdatedMethods, len(m.cUpdatedMethods) - len(c_crlf))
  1989.                 endif
  1990.                 replace methods with m.cUpdatedMethods
  1991.                 
  1992.             endscan
  1993.  
  1994.             set exact &cExact
  1995.             
  1996.             m.iVersion = .028
  1997.             =UpdateVersion('VERSION =  0.028')
  1998.         
  1999. * Insert next update here
  2000.  
  2001.         otherwise
  2002.             exit
  2003.         endcase
  2004.     enddo
  2005.     
  2006.     if m.lSuccess
  2007.     
  2008.         copy to (m.cScxName) for !deleted()
  2009.         use in ScxFile2
  2010.  
  2011.         if m.iVersion >= .019
  2012.             && drop columns declares and declares2
  2013.             use (m.cScxName)
  2014.             if type('declares') = 'M'
  2015.                 alter table (m.cScxName) drop column declares
  2016.             endif
  2017.             if type('declares2') = 'M'
  2018.                 alter table (m.cScxName) drop column declares2
  2019.             endif
  2020.             use 
  2021.         endif
  2022.  
  2023.         m.cOnError=on('error')
  2024.         m.iError=0
  2025.         on error m.iError=error()
  2026.         compile form (m.cScxName)
  2027.         on error &cOnError
  2028.         if !empty(m.iError)
  2029.             =Alert('Error #'+alltrim(str(m.iError))+' occurred '+ ;
  2030.                 'compiling '+m.cScxName+'.')
  2031.         endif
  2032.     else
  2033.         use in ScxFile2
  2034.     endif
  2035.     
  2036.     if m.lNotify
  2037.         activate screen
  2038.         if m.lSuccess
  2039.             ??'Complete.'
  2040.         else
  2041.             ??'Skipped.'
  2042.         endif
  2043.     endif
  2044. endif
  2045.  
  2046. *********************
  2047. procedure GetProperty
  2048. *********************
  2049. * This procedure accepts a properties memo field string and the name a property. It
  2050. * returns the value of the property if it's found, or an empty string if it's not found.
  2051.  
  2052. parameters m.cProperties, m.cPropertyName
  2053. local i, cLine
  2054.  
  2055. _mline = 0
  2056. for m.i = 1 to memlines(m.cProperties)
  2057.     m.cLine = mline(m.cProperties, 1, _mline)
  2058.     if alltrim(left(m.cLine, at('=', m.cLine) - 1)) == m.cPropertyName
  2059.         return alltrim(substr(m.cLine, at('=', m.cLine) + 1))
  2060.     endif
  2061. endfor
  2062. return ''
  2063.  
  2064. *********************
  2065. procedure PutProperty
  2066. *********************
  2067. * This procedure accepts a properties memo field string, the name of a property, and the
  2068. * string containing the value to which the property should be set. It returns the properties
  2069. * memo field string which reflects the new property value.
  2070.  
  2071. parameters m.cProperties, m.cPropertyName, m.cNewValue
  2072. local i, cLine, cUpdatedProperties, cProperty
  2073.  
  2074. _mline = 0
  2075. m.cUpdatedProperties = ''
  2076. for m.i = 1 to memlines(m.cProperties)
  2077.     m.cLine = mline(m.cProperties, 1, _mline)
  2078.     if empty(m.cLine)
  2079.         loop
  2080.     endif
  2081.     if alltrim(left(m.cLine, at('=', m.cLine) - 1)) == m.cPropertyName
  2082.         m.cUpdatedProperties = m.cUpdatedProperties + m.cPropertyName + ' = ' + m.cNewValue + c_crlf
  2083.     else
  2084.         m.cUpdatedProperties = m.cUpdatedProperties + m.cLine + c_crlf
  2085.     endif
  2086. endfor
  2087. return m.cUpdatedProperties
  2088.  
  2089. ***********************
  2090. procedure UpdateVersion
  2091. ***********************
  2092. parameters m.cVersionString
  2093.  
  2094. go top
  2095. if !platform='COMMENT'
  2096.     =ScxUpdtrError(-1,m_NotComment)
  2097. endif
  2098. replace reserved1 with m.cVersionString
  2099.  
  2100. *******************
  2101. procedure UpdateDbc
  2102. *******************
  2103. parameters m.cDbcName, m.lNotify
  2104. private m.cError, m.lError, m.cOnError
  2105.  
  2106. if .not. file(forceext(m.cDbcName,'dbf')) .and. ;
  2107.     .not. file(forceext(m.cDbcName,'dct')) .and. ;
  2108.     file(forceext(m.cDbcName,'fpt'))
  2109.     rename (forceext(m.cDbcName,'fpt')) to (forceext(m.cDbcName,'dct'))
  2110.     erase (forceext(m.cDbcName,'cdx'))
  2111.     m.cOnError=on('error')
  2112.     on error *
  2113.     use (m.cDbcName)
  2114.     on error &cOnError
  2115. endif
  2116.  
  2117. use (m.cDbcName) alias dbcfile
  2118.  
  2119. m.lIsDbc=.f.
  2120. do case
  2121. case type('objectid')<>'N'
  2122. case type('parentid')<>'N'
  2123. case type('objecttype')<>'C'
  2124. case type('objectname')<>'C'
  2125. case type('property')<>'M'
  2126. otherwise
  2127.     m.lIsDbc=.t.
  2128. endcase
  2129.  
  2130. if !m.lIsDbc
  2131.     =Alert(m.cDbcName+m_Not30Dbc)
  2132.     use
  2133.     return
  2134. endif
  2135.  
  2136. if m.lNotify
  2137.     activate screen
  2138.     ?'Updating '+m.cDbcName+'...  '
  2139. endif
  2140.  
  2141. m.iBuildNo=val(substr(version(1),24,4))
  2142. m.iVersion=sys(4001)
  2143. do while .t.
  2144.     do case
  2145.     case m.iVersion<4
  2146.         if m.iVersion=1
  2147.             use
  2148.             alter table (m.cDbcName) ;
  2149.                 alter column objectname c(128) not null
  2150.             use (m.cDbcName) alias dbcfile
  2151.         endif
  2152.  
  2153.         =sys(4000)
  2154.  
  2155.         use
  2156.         open database (m.cDbcName)
  2157.         close database
  2158.         use (m.cDBCName) alias dbcfile
  2159.         m.iVersion=4
  2160.     case m.iVersion = 4
  2161.         if m.iBuildNo<226 .and. OkToBuild(226)
  2162.             =Alert("DBC files cannot be updated beyond the build you're currently using.")
  2163.             exit
  2164.         endif
  2165.         && delete all entries from .DBC except those of type System, Table, Column,
  2166.         && Index, or Relation
  2167.         
  2168.         use (m.cDbcName) alias dbcfile
  2169.         m.cExact=set('exact')
  2170.         set exact on
  2171.         delete for !inlist(alltrim(objecttype),'System','Table','Column','Index','Relation')
  2172.         set exact &cExact
  2173.         
  2174.         pack
  2175.  
  2176.         if !type('dbcfile.code')='M'
  2177.             alter table dbcfile add column code m
  2178.             calculate max(objectid) to m.iMaxObjId
  2179.             insert into (m.cDbcName) (objectid, parentid, objecttype, objectname) ;
  2180.                 values (m.iMaxObjId+1, 1, 'System', 'StoredProceduresSource')
  2181.             insert into (m.cDbcName) (objectid, parentid, objecttype, objectname) ;
  2182.                 values (m.iMaxObjId+2, 1, 'System', 'StoredProceduresObject')
  2183.         endif
  2184.         
  2185.         m.iVersion=5
  2186.     case m.iVersion = 5
  2187.         if m.iBuildNo < 248 .and. OkToBuild(248)
  2188.             =Alert("DBC files cannot be updated beyond the build you're currently using.")
  2189.             exit
  2190.         endif
  2191.         
  2192.         replace objecttype with 'Database' for objecttype = 'System'
  2193.         reindex
  2194.         
  2195.         m.iVersion = 6
  2196.     case m.iVersion = 6
  2197.         if m.iBuildNo < 270 .and. OKToBuild(270)
  2198.             =Alert("DBC files cannot be updated beyond the build you're currently using.")
  2199.             exit
  2200.         endif
  2201.  
  2202.         * Rename objecttype "Column" to "Field" and add User memo field
  2203.         * Build 269 creates objecttype "Field" objects, but doesn't
  2204.         * add User memo field.
  2205.         replace objecttype with 'Field' for objecttype = 'Column'
  2206.         alter table (dbf()) add column user m
  2207.         reindex
  2208.         
  2209.         m.iVersion = 7
  2210.     case m.iVersion = 7
  2211.         * Modification to how relations are stored
  2212.         if m.iBuildNo < 275 .and. OKToBuild(275)
  2213.             =Alert("DBC files cannot be updated beyond the build you're currently using.")
  2214.             exit
  2215.         endif
  2216.  
  2217.         scan for objecttype = 'Relation'
  2218.             =sys(4010)
  2219.         endscan
  2220.         m.iVersion = 8
  2221.     case m.iVersion = 8
  2222.         
  2223.         if m.iBuildNo < 336 .and. OKToBuild(336)
  2224.             =Alert("DBC files cannot be updated beyond the build you're currently using.")
  2225.             exit
  2226.         endif
  2227.         copy to _xxxtemp.dbc
  2228.         zap
  2229.         alter table (dbf()) drop column user
  2230.         alter table (dbf()) add column riinfo c(6)
  2231.         alter table (dbf()) add column user m
  2232.         append from _xxxtemp.dbc
  2233.         use _xxxtemp.dbc in 0
  2234.         set relation to recno() into _xxxtemp
  2235.         delete ALL for deleted('_xxxtemp')
  2236.         use in _xxxtemp
  2237.         erase _xxxtemp.dbc
  2238.         erase _xxxtemp.dct
  2239.         erase _xxxtemp.dcx
  2240.         
  2241.         m.iVersion = 9
  2242.  
  2243. * Insert next update here
  2244.  
  2245.     otherwise
  2246.         && stamp the file current
  2247.         use (m.cDbcName) alias dbcfile
  2248.         =sys(4000)
  2249.         use
  2250.         exit
  2251.     endcase
  2252. enddo
  2253.  
  2254. if m.lNotify
  2255.     activate screen
  2256.     ??'Complete.'
  2257. endif
  2258.  
  2259. ***********************
  2260. procedure ScxUpdtrSetup
  2261. ***********************
  2262. parameters m.lCleanup
  2263.  
  2264. if empty(m.lCleanup)
  2265.     dimension aEnvironment[20]
  2266.     if set('talk')='ON'
  2267.         set talk off
  2268.         aEnvironment[1]='ON'
  2269.     else
  2270.         aEnvironment[1]='OFF'
  2271.     endif
  2272.     aEnvironment[2]=on('error')
  2273.     on error do ScxUpdtrError with error(), message()
  2274.     push key clear
  2275.     erase '26759970.vue'
  2276.     create view 26759970.vue
  2277.     close all
  2278.     aEnvironment[4]=set('safety')
  2279.     set safety off
  2280.     aEnvironment[5]=set('exact')
  2281.     set exact off
  2282.     aEnvironment[6]=_mline
  2283.     aEnvironment[7]=set('memowidth')
  2284.     set memowidth to 256
  2285.     aEnvironment[8]=set('notify')
  2286.     set notify off
  2287.     aEnvironment[3]=sys(5)+curdir()
  2288.     aEnvironment[9] = set('exclusive')
  2289.     set exclusive on
  2290. else
  2291.     set exclusive &aEnvironment[9]
  2292.     set notify &aEnvironment[8]
  2293.     set memowidth to (aEnvironment[7])
  2294.     _mline=aEnvironment[6]
  2295.     set exact &aEnvironment[5]
  2296.     set safety &aEnvironment[4]
  2297.     set talk &aEnvironment[1]
  2298.     pop key
  2299.     set default to (aEnvironment[3])
  2300.     close all
  2301.     set view to 26759970.vue
  2302.     erase 26759970.vue
  2303.     on error &aEnvironment[2]
  2304. endif
  2305.  
  2306. *******************
  2307. procedure UpdateAll
  2308. *******************
  2309. private iBuildID
  2310. m.iBuildID=val(substr(version(1),24,4))
  2311. if m.iBuildID < FOXPRO_BUILD_ID
  2312.     if Alert('You are running Build '+str(m.iBuildID,3)+ ;
  2313.         ' and 30Update is prepared to update to Build '+ ;
  2314.         str(FOXPRO_BUILD_ID,3)+'. Do you want to update to '+ ;
  2315.         'Build '+str(FOXPRO_BUILD_ID,3)+'? (If you answer '+ ;
  2316.         'No, files will be updated to Build '+str(m.iBuildID,3)+'.)', ;
  2317.         MB_ICONEXCLAMATION+MB_YESNO) = 'NO'
  2318.         return .f.
  2319.     endif
  2320. endif
  2321.  
  2322. *******************
  2323. procedure OkToBuild
  2324. *******************
  2325. parameters m.iBuildNo
  2326. private m.iBuildID
  2327. m.iBuildID=val(substr(version(1),24,4))
  2328. do case
  2329. case m.iBuildNo > FOXPRO_BUILD_ID
  2330.     return .f.
  2331. case m.iBuildID < m.iBuildNo
  2332.     return m.lUpdateAll
  2333. otherwise
  2334.     return .t.
  2335. endcase
  2336.  
  2337. **********************
  2338. procedure ScxUpdtrMain
  2339. **********************
  2340. private m.lUpdateAll
  2341. m.lUpdateAll=UpdateAll()
  2342.  
  2343. if empty(m.cScxName)
  2344.     frmScxUpdtr=createobj('ScxUpdater')
  2345.     frmScxUpdtr.show
  2346.     read events
  2347.     release frmScxUpdtr
  2348. else
  2349.     do case
  2350.     case type('m.cScxName')<>'C'
  2351.         =ScxUpdtrError(-1,e_InvalidParameter)
  2352.     case !file(m.cScxName)
  2353.         =ScxUpdtrError(-1,m.cScxName+e_ScxNotFound)
  2354.     otherwise
  2355.         do UpdateScx with m.cScxName
  2356.     endcase
  2357. endif
  2358.  
  2359. *************************
  2360. procedure ScxUpdtrCleanup
  2361. *************************
  2362. do ScxUpdtrSetup with 'CLEANUP'
  2363.  
  2364. **********************
  2365. procedure ScxUpdtrError
  2366. **********************
  2367. parameters m.iError, m.cMessage, m.cAction
  2368. if c_debug
  2369.     m.cAction=Alert(m.cMessage,MB_ICONEXCLAMATION+MB_ABORTRETRYIGNORE, ;
  2370.         m_MsgBoxTitle)
  2371.     do case
  2372.     case m.cAction='RETRY'
  2373.         set step on
  2374.         retry
  2375.     case m.cAction='IGNORE'
  2376.         return
  2377.     endcase
  2378. else
  2379.     =Alert(m.cMessage,MB_ICONEXCLAMATION+MB_OK,m_MsgBoxTitle)
  2380. endif
  2381. if type('m.iPrgHandle')='N'
  2382.     =fclose(m.iPrgHandle)
  2383. endif
  2384. if type('m.cTmpFil')='C'
  2385.     erase (m.cTmpFil)
  2386. endif
  2387. release frmScxUpdtr
  2388. return to ScxUpdtr
  2389.  
  2390. ********************
  2391. procedure Alert
  2392. ********************
  2393. parameters m.cMessage, m.cOptions, m.cTitle
  2394. private m.cTalk, m.cOptions, m.cResponse
  2395.  
  2396. if set('talk')='ON'
  2397.     set talk off
  2398.     m.cTalk='ON'
  2399. else
  2400.     m.cTalk='OFF'
  2401. endif
  2402.  
  2403. m.cOptions=iif(empty(m.cOptions),0,m.cOptions)
  2404. if !empty(m.cTitle)
  2405.     m.cResponse=MessageBox(m.cMessage,m.cOptions, m.cTitle)
  2406. else
  2407.     m.cResponse=MessageBox(m.cMessage,m.cOptions)
  2408. endif
  2409. do case
  2410. case m.cResponse=1
  2411.     m.cResponse='OK'
  2412. case m.cResponse=6
  2413.     m.cResponse='YES'
  2414. case m.cResponse=7
  2415.     m.cResponse='NO'
  2416. case m.cResponse=2
  2417.     m.cResponse='CANCEL'
  2418. case m.cResponse=3
  2419.     m.cResponse='ABORT'
  2420. case m.cResponse=4
  2421.     m.cResponse='RETRY'
  2422. case m.cResponse=5
  2423.     m.cResponse='IGNORE'
  2424. endcase
  2425.  
  2426. set talk &cTalk
  2427. return m.cResponse
  2428.  
  2429. ********************
  2430. procedure DirTree
  2431. ********************
  2432. parameters m.cDirName, m.aDirTree
  2433. private m.aTemp, m.cTalk, m.i
  2434. if set('talk')='ON'
  2435.     set talk off
  2436.     m.cTalk='ON'
  2437. else
  2438.     m.cTalk='OFF'
  2439. endif
  2440. dimension aDirTree[1,max(1,alen(aDirTree,2))]
  2441. aDirTree[1,1]=addbs(m.cDirName)
  2442. m.i=0
  2443. do while m.i<alen(aDirTree,1)
  2444.     m.i=m.i+1
  2445.     if !empty(adir(aTemp,aDirTree[m.i,1]+'*.*','D'))
  2446.         for m.j=1 to alen(aTemp,1)
  2447.             if !'D'$aTemp[m.j,5] .or. inlist(aTemp[m.j,1],'.','..')
  2448.                 loop
  2449.             endif
  2450.             dimension aDirTree[alen(aDirTree,1)+1,alen(aDirTree,2)]
  2451.             aDirTree[alen(aDirTree,1),1]=addbs(aDirTree[m.i,1]+aTemp[m.j,1])
  2452.         endfor
  2453.     endif
  2454. enddo
  2455. =asort(aDirTree)
  2456. if m.cTalk='ON'
  2457.     set talk on
  2458. endif
  2459. endproc
  2460.  
  2461. ********************
  2462. procedure AddBS
  2463. ********************
  2464. * Adds a backslash character to the string. 
  2465. * Called before FoxTools is loaded.
  2466.  
  2467. parameters m.wzsString
  2468. if right(alltrim(m.wzsString),1)='\'
  2469.     return alltrim(m.wzsString)
  2470. else
  2471.     return alltrim(m.wzsString)+'\'
  2472. endif
  2473. endproc
  2474.  
  2475. ********************
  2476. procedure ascanner
  2477. ********************
  2478.  
  2479. * This procedure returns the element number (not the row number)
  2480. * of the first match, verified to be in column m.column
  2481.  
  2482. PARAMETERS m.thearray, m.expression, m.column, m.start, m.howmany, ;
  2483.     m.wzlReturnRow
  2484.  
  2485. m.start=IIF(EMPTY(m.start),1,m.start)
  2486. m.element=IIF(TYPE('m.start')='N',m.start-1,0)
  2487. m.column=IIF(EMPTY(m.column),1,m.column)
  2488. m.howmany=IIF(EMPTY(m.howmany),ALEN(thearray),m.howmany)
  2489. DO WHILE .T.
  2490.     m.element=ASCAN(thearray,expression,m.element+1,m.howmany)
  2491.     IF m.element=0 .OR. ASUBSCRIPT(thearray,m.element,2)=m.column
  2492.         EXIT
  2493.     ELSE
  2494.         m.howmany=m.howmany-m.element-1
  2495.         m.howmany=max(m.howmany,1)
  2496.     ENDIF
  2497. ENDDO
  2498. if m.wzlReturnRow
  2499.     if !empty(m.element)
  2500.         m.element=asubscript(thearray,m.element,1)
  2501.     endif
  2502. endif
  2503. RETURN m.element
  2504.  
  2505. ********************
  2506. procedure Setting
  2507. ********************
  2508. parameters m.cMemo, m.cSetting
  2509. private m.i_mline, m.cLine, m.cReturn
  2510. m.i_mline=_mline
  2511. _mline=0
  2512. m.cReturn=''
  2513. for m.i=1 to memlines(m.cMemo)
  2514.     m.cLine=mline(m.cMemo,1,_mline)
  2515.     if upper(alltrim(left(m.cLine,at('=',m.cLine)-1)))== ;
  2516.         upper(alltrim(m.cSetting))
  2517.         
  2518.         m.cReturn=ltrim(substr(m.cLine,at('=',m.cLine)+1))
  2519.         exit
  2520.     endif
  2521. endfor
  2522. _mline=m.i_mline
  2523.  
  2524. return m.cReturn
  2525.  
  2526. *!*****************************************************************************
  2527. *!
  2528. *!       Function: FORCEEXT
  2529. *!
  2530. *!          Calls: JUSTPATH()         (function  in GENSCRN.PRG)
  2531. *!               : JUSTFNAME()        (function  in GENSCRN.PRG)
  2532. *!               : ADDBS()            (function  in GENSCRN.PRG)
  2533. *!
  2534. *!*****************************************************************************
  2535. FUNCTION forceext
  2536. *)
  2537. *) FORCEEXT - Force filename to have a particular extension.
  2538. *)
  2539. PARAMETERS m.filname,m.ext
  2540. PRIVATE m.ext
  2541. IF SUBSTR(m.ext,1,1) = "."
  2542.    m.ext = SUBSTR(m.ext,2,3)
  2543. ENDIF
  2544.  
  2545. m.pname = justpath(m.filname)
  2546. m.filname = justfname(UPPER(ALLTRIM(m.filname)))
  2547. IF AT('.',m.filname) > 0
  2548.    m.filname = SUBSTR(m.filname,1,AT('.',m.filname)-1) + '.' + m.ext
  2549. ELSE
  2550.    m.filname = m.filname + '.' + m.ext
  2551. ENDIF
  2552. RETURN addbs(m.pname) + m.filname
  2553.  
  2554. *!*****************************************************************************
  2555. *!
  2556. *!       Function: JUSTPATH
  2557. *!
  2558. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  2559. *!
  2560. *!*****************************************************************************
  2561. FUNCTION justpath
  2562. *)
  2563. *) JUSTPATH - Returns just the pathname.
  2564. *)
  2565. PARAMETERS m.filname
  2566. m.filname = ALLTRIM(UPPER(m.filname))
  2567. IF '\' $ m.filname
  2568.    m.filname = SUBSTR(m.filname,1,RAT('\',m.filname))
  2569.    IF RIGHT(m.filname,1) = '\' AND LEN(m.filname) > 1 ;
  2570.             AND SUBSTR(m.filname,LEN(m.filname)-1,1) <> ':'
  2571.          filname = SUBSTR(m.filname,1,LEN(m.filname)-1)
  2572.    ENDIF
  2573.    RETURN m.filname
  2574. ELSE
  2575.    RETURN ''
  2576. ENDIF
  2577.  
  2578. *!*****************************************************************************
  2579. *!
  2580. *!       Function: JUSTFNAME
  2581. *!
  2582. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  2583. *!
  2584. *!*****************************************************************************
  2585. FUNCTION justfname
  2586. *)
  2587. *) JUSTFNAME - Return just the filename (i.e., no path) from "filname"
  2588. *)
  2589. PARAMETERS m.filname
  2590. IF RAT('\',m.filname) > 0
  2591.    m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
  2592. ENDIF
  2593. IF AT(':',m.filname) > 0
  2594.    m.filname = SUBSTR(m.filname,AT(':',m.filname)+1,255)
  2595. ENDIF
  2596. RETURN ALLTRIM(UPPER(m.filname))
  2597.  
  2598. *!*****************************************************************************
  2599. *!
  2600. *!       Function: JUSTEXT
  2601. *!
  2602. *!*****************************************************************************
  2603. FUNCTION justext
  2604. * Return just the extension from "filname"
  2605. PARAMETERS m.filname
  2606. PRIVATE m.ext
  2607. filname = justfname(m.filname)   && prevents problems with ..\ paths
  2608. m.ext = ""
  2609. IF AT('.',m.filname) > 0
  2610.    m.ext = SUBSTR(m.filname,AT('.',m.filname)+1,3)
  2611. ENDIF
  2612. RETURN UPPER(m.ext)
  2613.  
  2614. ********************
  2615. procedure FileType
  2616. ********************
  2617. parameters m.cFileName
  2618. private m.cOnError, m.iError, m.iSelect, m.cFileType
  2619. m.iSelect=select()
  2620. select 0
  2621. m.cOnError=on('error')
  2622. on error m.iError=error()
  2623. use (m.cFileName)
  2624. on error &cOnError
  2625. if type('m.iError')='N' .and. m.iError=41 && memo file missing or invalid
  2626.     if justext(m.cFileName)='DBC'
  2627.         if .not. file(forceext(m.cFileName,'dbf')) .and. ;
  2628.             .not. file(forceext(m.cFileName,'dct')) .and. ;
  2629.             file(forceext(m.cFileName,'fpt'))
  2630.             rename (forceext(m.cFileName,'fpt')) to (forceext(m.cFileName,'dct'))
  2631.             erase (forceext(m.cFileName,'cdx'))
  2632.             m.cOnError=on('error')
  2633.             on error m.iError=error()
  2634.             use (m.cFileName)
  2635.             on error &cOnError
  2636.             if empty(dbf())
  2637.                 rename (forceext(m.cFileName,'dct')) to (forceext(m.cFileName,'fpt'))
  2638.             else
  2639.                 erase (forceext(m.cFileName,'cdx'))
  2640.             endif
  2641.         endif
  2642.     endif
  2643. endif
  2644. if !empty(dbf())
  2645.     do case
  2646.     case type('platform')='C' .and. ;
  2647.         type('uniqueid ')='C' .and. ;
  2648.         type('timestamp')='N' .and. ;
  2649.         type('reserved1')='M' .and. ;
  2650.         type('reserved2')='M' .and. ;
  2651.         type('reserved3')='M' .and. ;
  2652.         type('user')='M' .and. ;
  2653.         type('comment')='M' .and. ;
  2654.         (type('class')='C' .or. type('class')='M') .and. ;
  2655.         type('classloc')='M' .and. ;
  2656.         type('objname')='M' .and. ;
  2657.         type('parent')='M' .and. ;
  2658.         type('properties')='M' .and. ;
  2659.         type('methods')='M' .and. ;
  2660.         type('objcode')='M'
  2661.         m.cFileType='SCX'
  2662.         * could be VCX, but doesn't matter right now
  2663.     case type('objectid')='N' .and. ; 
  2664.         type('parentid')='N' .and. ;
  2665.         type('objecttype')='C' .and. ;
  2666.         type('objectname')='C' .and. ;
  2667.         type('property')='M'
  2668.         m.cFileType='DBC'
  2669.     case type('name') = 'M' .and. ;
  2670.         type('type') = 'C' .and. ;
  2671.         type('timestamp') = 'N' .and. ;
  2672.         type('outfile') = 'M' .and. ;
  2673.         type('homedir') = 'M' .and. ;
  2674.         type('exclude') = 'L' .and. ;
  2675.         type('mainprog') = 'L' .and. ;
  2676.         type('savecode') = 'L' .and. ;
  2677.         type('debug') = 'L' .and. ;
  2678.         type('encrypt') = 'L' .and. ;
  2679.         type('nologo') = 'L' .and. ;
  2680.         type('cmntstyle') = 'N' .and. ;
  2681.         type('objrev') = 'N' .and. ;
  2682.         type('commands') = 'M' .and. ;
  2683.         type('devinfo') = 'M' .and. ;
  2684.         type('symbols') = 'M' .and. ;
  2685.         type('object') = 'M' .and. ;
  2686.         type('ckval') = 'N' .and. ;
  2687.         type('cpid') = 'N' .and. ;
  2688.         type('ostype') = 'C' .and. ;
  2689.         type('oscreator') = 'C' .and. ;
  2690.         type('comments') = 'M' .and. ;
  2691.         type('reserved1') = 'M' .and. ;
  2692.         type('reserved2') = 'M'
  2693.         m.cFileType = 'PJX'
  2694.     otherwise
  2695.         m.cFileType='UNKNOWN'
  2696.     endcase
  2697.     use
  2698. else
  2699.     m.cFileType='UNKNOWN'
  2700. endif
  2701. select (m.iSelect)
  2702. return m.cFileType
  2703.  
  2704. ********************************************************************************
  2705. ******************************* CLASS DEFINTIONS *******************************
  2706. ********************************************************************************
  2707.  
  2708. define class ScxUpdater as form
  2709.     Backcolor = rgb(192,192,192)
  2710.     ScaleMode = 3
  2711.     Height = 325
  2712.     Width = 445
  2713.     Caption = 'FoxPro 3.0 Updater'
  2714.     AutoCenter = .t.
  2715.     
  2716.     add object txtHelp as editbox with ;
  2717.         Value = ;
  2718.             '30Update is a utility for updating .SCX, .VCX, .DBC, '+ ;
  2719.             'and .PJX files to reflect changes made during the '+ ;
  2720.             'development of FoxPro 3.0.'+ ;
  2721.             chr(13)+chr(13)+ ;
  2722.             '30Update does not make backup copies of the files it updates. '+ ;
  2723.             'Make a backup of your files before using this utility.' + ;
  2724.             chr(13) + chr(13) + ;
  2725.             '30Update Revision #03.00.00.0' + alltrim(str(FOXPRO_BUILD_ID)), ;
  2726.         Height = 130, ;
  2727.         Left = 18, ;
  2728.         Top = 13, ;
  2729.         Width = 410, ;
  2730.         BorderStyle = 0, ;
  2731.         ReadOnly = .t., ;
  2732.         TabStop = .f., ;
  2733.         ScrollBars = 0, ;
  2734.         BackColor = rgb(192,192,192)
  2735.         
  2736.     add object cmdFile as commandbutton with ;
  2737.         Caption = 'File...', ;
  2738.         Height = 23, ;
  2739.         Left = 18, ;
  2740.         Top = 156, ;
  2741.         Width = 75
  2742.         
  2743.     add object cmdDir as commandbutton with ;
  2744.         Caption = 'Directory...', ;
  2745.         Height = 23, ;
  2746.         Left = 18, ;
  2747.         Top = 188, ;
  2748.         Width = 75
  2749.         
  2750.     add object chkSubdirs as checkbox with ;
  2751.         Caption = 'Include Subdirectories', ;
  2752.         Height = 16, ;
  2753.         Left = 105, ;
  2754.         Top = 219, ;
  2755.         Width = 160, ;
  2756.         Enabled = .f., ;
  2757.         BackStyle = 0
  2758.         
  2759.     add object chkScxFiles as checkbox with ;
  2760.         Caption = '.SCX Files', ;
  2761.         Height = 16, ;
  2762.         Left = 288, ;
  2763.         Top = 219, ;
  2764.         Width = 85, ;
  2765.         Value = 1, ;
  2766.         Enabled = .f., ;
  2767.         BackStyle = 0
  2768.         
  2769.     add object chkVcxFiles as checkbox with ;
  2770.         Caption = '.VCX Files', ;
  2771.         Height = 16, ;
  2772.         Left = 288, ;
  2773.         Top = 234, ;
  2774.         Width = 85, ;
  2775.         Value = 1, ;
  2776.         Enabled = .f., ;
  2777.         BackStyle = 0
  2778.         
  2779.     add object chkDbcFiles as checkbox with ;
  2780.         Caption = '.DBC Files', ;
  2781.         Height = 16, ;
  2782.         Left = 288, ;
  2783.         Top = 249, ;
  2784.         Width = 85, ;
  2785.         Value = 1, ;
  2786.         Enabled = .f., ;
  2787.         BackStyle = 0
  2788.     
  2789.     add object chkPjxFiles as checkbox with ;
  2790.         Caption = '.PJX Files', ;
  2791.         Height = 16, ;
  2792.         Left = 288, ;
  2793.         Top = 264, ;
  2794.         Width = 85, ;
  2795.         Value = 1, ;
  2796.         Enabled = .f., ;
  2797.         BackStyle = 0
  2798.         
  2799.     add object lblFileName as label with ;
  2800.         Caption = '', ;
  2801.         Height = 15, ;
  2802.         Left = 104, ;
  2803.         Top = 160, ;
  2804.         Width = 320
  2805.         
  2806.         * BugBug:        BackColor = rgb(192,192,192)
  2807.         
  2808.     add object lblDirName as label with ;
  2809.         Caption = '', ;
  2810.         Height = 15, ;
  2811.         Left = 104, ;
  2812.         Top = 192, ;
  2813.         Width = 320
  2814.  
  2815.         * BugBug:        BackColor = rgb(192,192,192)
  2816.         
  2817.     add object cmdUpdate as commandbutton with ;
  2818.         Caption = 'Update', ;
  2819.         Default = .T., ;
  2820.         Enabled = .F., ;
  2821.         Height = 23, ;
  2822.         Left = 135, ;
  2823.         Top = 293, ;
  2824.         Width = 75
  2825.         
  2826.     add object cmdCancel as commandbutton with ;
  2827.         Caption = 'Exit', ;
  2828.         Height = 23, ;
  2829.         Left = 224, ;
  2830.         Top = 293, ;
  2831.         Width = 75
  2832.     
  2833.     procedure cmdFile.Click
  2834.         thisform.lblFileName.Caption=getfile('scx;vcx;dbc;pjx', ;
  2835.             'Select file to update:')
  2836.         if !empty(thisform.lblFileName.Caption)
  2837.             thisform.lblDirName.Caption=''
  2838.         endif
  2839.         thisform.Refresh
  2840.     endproc
  2841.     
  2842.     procedure cmdDir.Click
  2843.         thisform.lblDirName.Caption=getdir('', ;
  2844.             'Select directory to update:')
  2845.         if !empty(thisform.lblDirName.Caption)
  2846.             thisform.lblFileName.Caption=''
  2847.         endif
  2848.         thisform.Refresh
  2849.     endproc
  2850.     
  2851.     procedure chkScxFiles.Click
  2852.         thisform.Refresh
  2853.     endproc
  2854.     
  2855.     procedure chkVcxFiles.Click
  2856.         thisform.Refresh
  2857.     endproc
  2858.     
  2859.     procedure chkDbcFiles.Click
  2860.         thisform.Refresh
  2861.     endproc
  2862.  
  2863.     procedure chkPjxFiles.Click
  2864.         thisform.Refresh
  2865.     endproc
  2866.     
  2867.     procedure Destroy
  2868.         clear events
  2869.     endproc
  2870.     
  2871.     procedure Init
  2872. *        this.txtHelp.BackStyle = 0 && bug
  2873.     endproc
  2874.     
  2875.     procedure Refresh
  2876.         if !empty(this.lblDirName.Caption)
  2877.             this.chkSubdirs.Enabled=.t.
  2878.             this.chkScxFiles.Enabled=.t.
  2879.             this.chkVcxFiles.Enabled=.t.
  2880.             this.chkDbcFiles.Enabled=.t.
  2881.             this.chkPjxFiles.Enabled = .t.
  2882.         else
  2883.             this.chkSubdirs.Enabled=.f.
  2884.             this.chkScxFiles.Enabled=.f.
  2885.             this.chkVcxFiles.Enabled=.f.
  2886.             this.chkDbcFiles.Enabled=.f.
  2887.             this.chkPjxFiles.Enabled = .f.
  2888.         endif
  2889.             
  2890.         do case
  2891.         case !empty(this.lblFileName.Caption)
  2892.             this.cmdUpdate.Enabled=.t.
  2893.         case !empty(this.lblDirName.Caption) .and. ;
  2894.             (this.chkScxFiles.Value=1 .or. ;
  2895.             this.chkVcxFiles.Value=1 .or. ;
  2896.             this.chkDbcFiles.Value=1 .or. ;
  2897.             this.chkPjxFiles.Value = 1)
  2898.             this.cmdUpdate.Enabled=.t.
  2899.         otherwise
  2900.             this.cmdUpdate.Enabled=.f.
  2901.         endcase
  2902.     endproc
  2903.     
  2904.     procedure cmdUpdate.Click
  2905.         m.cResponse=Alert('30Update overwrites existing files. '+ ;
  2906.             'You should make a backup before running this utility. '+ ;
  2907.             'Do you want to continue?',MB_ICONEXCLAMATION+MB_YESNO)
  2908.         if m.cResponse='NO'
  2909.             return
  2910.         endif
  2911.         if !empty(thisform.lblFileName.Caption)
  2912. *            do UpdateScx with thisform.lblFileName.Caption, .t.
  2913. * This is a workaround--the preceding call doesn't properly pass the parameter.
  2914.             private m.cFileName
  2915.             m.cFileName=thisform.lblFileName.Caption
  2916.             m.cFileType=FileType(m.cFileName)
  2917.             do case
  2918.             case inlist(m.cFileType,'SCX','VCX')
  2919.                 do UpdateScx with m.cFileName, .t.
  2920.             case m.cFileType='DBC'
  2921.                 do UpdateDbc with m.cFileName, .t.
  2922.             case m.cFileType = 'PJX'
  2923.                 do UpdatePJX with m.cFileName, .t.
  2924.             otherwise
  2925.                 =Alert(m.cFileName+' is not a SCX, VCX, DBC, or PJX file.')
  2926.             endcase
  2927.             thisform.lblFileName.Caption=''
  2928.             thisform.Refresh
  2929.         else
  2930. * Same workaround here, also.
  2931.             private m.aDirs, m.cDirName, m.i, m.aScxFiles
  2932.             dimension aDirs[1,1]
  2933.             if thisform.chkSubDirs.value=1
  2934.                 m.cDirName=thisform.lblDirName.Caption
  2935.                 do dirtree with cDirName, aDirs
  2936.             else
  2937.                 aDirs[1,1]=thisform.lblDirName.Caption
  2938.             endif
  2939.             do while !empty(aDirs[1,1])
  2940.                 if thisform.chkVcxFiles.Value=1
  2941.                     if !empty(adir(aScxFiles,addbs(aDirs[1,1])+'*.Vcx'))
  2942.                         =asort(aScxFiles)
  2943.                         for m.i=1 to alen(aScxFiles,1)
  2944.                             do UpdateScx with addbs(aDirs[1,1])+aScxFiles[m.i,1], .t.
  2945.                         endfor
  2946.                     endif
  2947.                 endif
  2948.                 if thisform.chkScxFiles.Value=1
  2949.                     if !empty(adir(aScxFiles,addbs(aDirs[1,1])+'*.Scx'))
  2950.                         =asort(aScxFiles)
  2951.                         for m.i=1 to alen(aScxFiles,1)
  2952.                             do UpdateScx with addbs(aDirs[1,1])+aScxFiles[m.i,1], .t.
  2953.                         endfor
  2954.                     endif
  2955.                 endif
  2956.                 if thisform.chkDbcFiles.Value=1
  2957.                     if !empty(adir(aScxFiles,addbs(aDirs[1,1])+'*.dbc'))
  2958.                         =asort(aScxFiles)
  2959.                         for m.i=1 to alen(aScxFiles,1)
  2960.                             do UpdateDbc with addbs(aDirs[1,1])+aScxFiles[m.i,1], .t.
  2961.                         endfor
  2962.                     endif
  2963.                 endif
  2964.                 if thisform.chkPjxFiles.Value = 1
  2965.                     if !empty(adir(aScxFiles,addbs(aDirs[1,1])+'*.pjx'))
  2966.                         =asort(aScxFiles)
  2967.                         for m.i=1 to alen(aScxFiles,1)
  2968.                             do UpdatePjx with addbs(aDirs[1,1])+aScxFiles[m.i,1], .t.
  2969.                         endfor
  2970.                     endif
  2971.                 endif
  2972.                 =adel(aDirs,1)
  2973.             enddo
  2974.             thisform.lblDirName.Caption=''
  2975.             thisform.Refresh
  2976.         endif
  2977.     endproc
  2978.         
  2979.     procedure cmdCancel.Click
  2980.         clear events
  2981.     endproc
  2982. enddefine
  2983.  
  2984.