VM4UPGRD

Embed Size (px)

Citation preview

  • 7/15/2019 VM4UPGRD

    1/72

    VISUAL MAXFRAME

    PROFESSIONAL version 4.0 upgrade information, revision history

    Copyright 1999 Metamor Industry Solutions All Rights Reserved.

    This document contains information that is essential to your success in upgrading an existing VisualMaxFrame Professional application running under VMP v3.01 to the current v4.0. Read it carefully, payingparticular attention to the indicated Retrofitting Instructions.

    The following is a list of features, enhancements, and modifications to the Visual MaxFrame Professional framework thatconstitute the difference between v3.01 and v4.0.

    This document is provided in Word97.DOC format so that you can do text search on specific files/classes/PEMs/etc., and sothat you can cut-and-paste example code when necessary.

    At times this document refers to "Visual MaxFrame Professional only" features because some new features, enhancements,and modifications required modifications to class libraries or other files that are in both the public domain Visual MaxFramesuperset, and the Visual MaxFrame Professional comprehensive product.

    If v4.0 is your first purchase of VMPYou can probably skip the contents of this document, since you have no v3.0 background or existing code.

    If you have VMP 3.0/3.01 but are not migrating existing apps toVMP 4.0

    If you have an existing set of "intermediate" classes based on the VMP 3.01 framework from which youhave created application-specific subclasses for existing VMP 3.01 apps

    You should review the contents of this document and make any necessary retrofits. Your VMP 3.01 classes are notcompatible with your VMP 4.0 classes, so you should install VMP 4.0 in a new directory/folder structure and keep yourexisting VMP 3.01 code base separate. Copy your existing "intermediate" classes to your new VMP 4.0 directory/folderstructure, and follow the retrofitting instructions in this document as they apply to your "intermediate" classes. See the If youare upgrading an existing app from VMP 3.01 to VMP 4.0 section below.

    If you have no existing VMP 3.0 code/classes you will be using for VMP 4.0 projects

    You should review the contents of this document to familiarize yourself with the enhancements, modifications, and newfeatures of VMP 4.0.

    If you are upgrading an existing app from VMP 3.01 to VMP 4.0You must follow the retrofitting instructions listed in this document. Each modification, enhancement, and new feature islisted in this document, along with the retrofitting implications to existing VMP 3.01 apps, if any.

    Prepare

    Read the entire contents of this document to familiarize yourself with the new features and enhancements, paying attention tothe retrofitting instructions and the implications for your existing applications.

  • 7/15/2019 VM4UPGRD

    2/72

    Please note that although we have made every effort to determine any retrofitting modifications youre likely to have to make,you should review each item carefully because you may have implemented subclasses in such a way that you will have tomodify/maintain code/PEMs in a manner we cannot anticipate. We have made every effort to ensure that new features,enhancements, and modifications require a minimum retrofit effort (we have to perform such retrofits on our existingapplications, too!).

    Make a backup of your entire existing application(s) before retrofitt ing. The backup should be available, running inv3.01 during the retrofit process.

    Install

    Install Visual MaxFrame Professional 4.0 files into a new directory/folder structure separate from your existing VMP 3.0installation. Installation instructions are listed in the VMP 4.0 Reference Guide.

    Be sure to keep your current v3.01 VMP files intact, along with the backup copy of your existing application. During theentire migration process, you should keep the VMP 3.01 version of your app in working order as a reference point. Once youare completely satisfied that your app(s) have been successfully migrated to VMP 4.0, you may delete your VMP 3.01framework files and your VMP 3.01 application if you wish.

    Retrofit

    Perform any needed retrofitting activities on your existing applications as described in the remainder of this document.

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 2

  • 7/15/2019 VM4UPGRD

    3/72

    ENHANCEMENTSREQUIRINGSIGNIFICANTRETROFITTING

    This section lists the major VMP 3.01 VMP 4.0 enhancements that require retrofitting when upgrading an existing VMP3.01 app.

    If you're not upgrading/migrating an existing VMP 3.0 app to VMP 4.0, it is still important to review this information if youhave used VMP 3.01, since these items have changed in the latest version.

    You should perform the following retrofitting modifications in the order they are listed here.

    MODIFICATION: X3 prefix replaced with XXThe naming convention we've been using for years, wherein the first character is an "X" and the 2 nd character is an integerindicating the oldest FoxPro version with which the library file is compatible doesn't work well with .VCX files. Therefore,we have renamed all the X3*.VCX files to corresponding XX*.VCX files. Also, X3*.PRG programs that are only useful inthe context of the Visual MaxFrame/Visual MaxFrame Professional framework have been renamed to correspondingXX*.PRG files.Here is a list of the files that have been renamed from X3 to XX. Of course, .VCXs and .SCXs have an accompanying.VCT/.SCT.

    Visual MaxFrame

    XXFW.VCX *XXFWLIBS.VCX *XXFWPPOP.VCX *

    XXFWDATA.PRGXXFWMAIN.PRGXXERROR.PRG *XXAPPINF.PRG *

    XXFWMAIN.MNX *

    XXFWBLNK.ICO *

    * indicates those files that are likely to be referenced in app-specific code

    Visual MaxFrame ProfessionalXXFWCTRL.VCX *XXFWFRM.VCX *XXFWGRD.VCX *XXFWMISC.VCX *XXFWPICK.VCX *XXTOOLS.VCXXXWB.VCX

    XXBUILDR.PRGXXDT.PRGXXDTDBFL.PRGXXDTEPEM.PRG

    XXDTHACK.PRGXXDTMEST.PRGXXDTNEWF.PRGXXDTPOPC.PRGXXDTSRCH.PRGXXDTSUBC.PRGXXWB.PRG (2 changes -- formerly X3WZ.PRG)XXWBAPPS.PRG (2 changes -- formerly X3WZAPPS.PRG)

    XXWBCFPW.BMPXXWBDIR.BMP

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 3

  • 7/15/2019 VM4UPGRD

    4/72

    XXWBFNSH.BMPXXWBMFSM.BMPXXWBMP.BMPXXWBSHCT.BMP

    XXERROR.FRX *XXFWUSR.FRX *

    * indicates those files that are likely to be referenced in app-specific code

    Retrofitting Instructions

    Retrofitting requires that any/all references to the X3 version of the above files be removed from your existing VMP 3.01application(s). The required retrofitting is included in the Retrofitting Instructions in the next MODIFICATION: MajorPEM reorganization section, items 3 and 5.

    MODIFICATION: Major PEM reorganizationThis modification migrates the PEMs previously contained in the following X3FWCTRL.VCX commandbutton classes

    cmdDataAddcmdDataDeletecmdDataFind

    cmdDataPrintcmdDataOKcmdDataSavecmdDataCancel

    to the containing form level, mostly to corresponding PEMs in XXFWFRM.VCX/frmDataEntry.

    This modification is fairly extensive, although the retrofitting is nowhere near as difficult as it looks by reading this listing; Iwas able to retrofit the entire VM example application in less than one hour. The only time there is actual retrofitting to do iswhen you have explicit method code/property settings that have been moved. Also, a utility program VM34UTL1.PRG has

    been provided to help determine what retrofitting you'll have to make.

    If you're retrofitting an existing application, your best bet is to install VMP 4.0 while leaving your VMP 3.0/3.01 installationintact, and copy your application to a new directory/folder structure where it can run under VMP 4.0 in parallel with youroriginal VMP 3.0/3.01 app. Once the migration/retrofitting to VMP 4.0 is complete and fully tested, then it is safe to delete

    the VMP 3.01 version if you wish. By having the existing application available, it is easier to check for the currentlocation/value of existing PEMs, and to copy/paste when advantageous. Be sure to fully complete the retrofitting instructionsfor this item before trying to run the app or even open forms/classes in the Form/Class Designer.

    While a significant number of PEMs (mostly methods) have been migrated from the commandbutton classes tofrmDataEntry, they have been grouped together according to type all the Save-specific methods start with "Save", all theDelete-specific methods start with "Delete", etc.

    This modification is a definite enhancement, for the following reasons:

    To get the Add/Delete/Save/Cancel/etc. behaviors, you don't have to use the XXFWCTRL.VCX/cmdData.. buttons

    any mechanism that calls the data-entry-form-based ..Action() methods works instead

    Seven (button) classes were replaced by a single class

    One data-entry form class, frmDataEntrySCADO, was eliminated (the fewer the classes, the better)

    Subclassing the "action" behaviors is easier, since they're at the form level rather than in a form member (see Chapter16: The Trouble With Composites in the Reference Guide.

    Toolbar coordination is significantly improved you no longer need an action/navigation commandbutton on the form,

    since the behaviors are no longer in the commandbutton classes themselves (see the new VMDECUSX.SCX exampleform)

    On the down side, forms inheriting from frmDataEntry have more PEMs to wade through on the Properties Sheet. But atleast the ones dealt with here are grouped together according to their "action"

    XXFWCTRL.VCX

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 4

  • 7/15/2019 VM4UPGRD

    5/72

    cmdData

    Init() modified to set a default ToolTipText based on the new icType property, default ilCallSecurityFromRefreshRefresh() added default codeicType new public property, default to SPACE(0)ilCallSecurityFromRefresh new public property, default to .NULL.SetUserSecurity() added default codezReadMe() updatedcmdDataMovePointerRefresh() modified to conditionally call THISFORM.ActionButtonRefreshLogic()

    icType reset to defaultSetUserSecurity() overriddenAfterClick() removedClick() modified to defer the actual form.Refresh() to the Form.MovePointer() methodcmdDataCallMemoEditFormicType set to "M" in the Properties SheetcmdDataAction NEW CLASSClick() call the THISFORM.Action() method corresponding to THIS.icTypecmdDataAdd -- REMOVEDcmdDataCancel -- REMOVEDcmdDataDelete -- REMOVEDcmdDataFind -- REMOVEDcmdDataPrint -- REMOVEDcmdDataOK -- REMOVED

    cmdDataSave -- REMOVEDXXFWFRM.VCX

    frmDataEntrySCADO -- REMOVEDfrmDEOne2Many -- REMOVEDfrmDataEntry

    Activate() modified logic to go into "AddOnTheFly" mode even if there's no buttonActionButtonRefreshLogic() new public method with code migrated from the individual cmdData.. buttonsAddAction() new public method corresponding to the old cmdDataAdd.Click()AddBeforeAppendBlank() new public method corresponding to the old cmdDataAdd.ShellBeforeAppendBlank(),

    can RETURN a logical .F. to bring the to a haltAddAfterAppendBlank() new public method corresponding to the old cmdDataAdd.ShellAfterAppendBlank()BoundControlsInteractiveChange() renamed to EditAction()DeleteAction() modified to incorporate the code from the old cmdDataDelete.Click(), eliminates the old

    cmdDataDelete.TakeActionOnFailure user-messaging by calling the new THISFORM.SaveMessageOnFailure(),which also required updating the wording of several MSGSVC.DBF records for "Save, unable"

    DeleteConfirmation() new public method corresponding to the old cmdDataDelete.UserConfirmation() andthe old cmdDataDelete.MessageText()

    DeleteAdditionalAction() new public method corresponding to the old frmDataEntry.ShellAdditionalDeleteAction()DeleteBeforeAnything() new public empty/shell methodDeleteAfterSuccess() new public empty/shell methodDeleteAfterFailure() new public empty/shell methodEditAction() the old BoundControlsInteractiveChange() method, simply renamedFindAction() new public method corresponding to the old cmdDataFind.Click()FindUI() new public method corresponding to the old cmdDataFind.DoTheFind()icFindActionTag new public property, default to SPACE(0), corresponds to the old cmdDataFind.icFreeTableTagSaveAction() new public method corresponding to the old cmdDataSave.Click()SaveBeforeAnything() new public method corresponding to the old cmdDataSave.ShellBeforePreSave()

    SaveGenAndPopPK() new public method corresponding to the old cmdDataSave.PreSave()SaveBeforeUpdateBuffers() new public method corresponding to the old cmdDataSave.ShellAfterPreSave()SaveAfterSuccess() new public method corresponding to the old cmdDataSave.AfterUltimateSuccess()SaveAfterFailure() new public method corresponding to the old cmdDataSave.AfterUltimateFailure()SaveUpdateAddOnTheFlyRecord() new public method corresponding to the oldcmdDataSave.UpdateAddOnTheFlyRecord()SaveCheckRequiredFields() new public method corresponding to the old cmdDataSave.CheckRequiredFields()SaveMessageOnFailure() new public method corresponding to the old cmdDataSave.SaveMessageOnFailure()SaveODBCMessageOnFailure() new public method corresponding to the old cmdDataSave.ODBCErrorMessage()PushMainAliasRecno() the old SaveMainAliasRecno() method renamed, also modifiedPopMainAliasRecno() the old RestoreMainAliasRecno() method renamed

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 5

  • 7/15/2019 VM4UPGRD

    6/72

    inSaveMainAliasRecno removed, as per the warning in the VMP 3.0 property description. The equivalent value canbe queried via THISFORM.ioSaveMainAliasRecno.GetPProp("inSaveRecno")

    iaSaveFailureInfo actually added to frmData but used throughout frmDataEntry, to hold information regarding a failedSaveAction() and give the user a default or explicit message in SaveMessageOnFailure().

    frmDEGridNav

    Redefined to inherit from frmDataEntry, now that frmDataEntrySCADO has been eliminated. Manual scope resolutionoperator callbacks updated accordingly.

    Added six instances of XXFWCTRL.VCX/cmdDataAction, now that this form class inherits the action buttons fromfrmDataEntrySCADO: Add, Delete, Save, Cancel, Print, OK (no Find). Each button has its icType,

    Caption, and Name properties set accordingly, yielding the same effect as frmDEGridNav when it inheritedfrom frmDataEntrySCADO.frmEventLogHack the record for the cmdDeleteAll member to redefine it to inherit from cmdDataAction (replace the Class field with

    "cmdDataAction". Also set the icType property to "D".cmdDelete.Click() -- modifiedfrmDEGridNav2PagesDeleteAction() modified to incorporate the logic formerly in the old cmdDelete.Click()UpdateFormOnAdd() modified to incorporate the logic formerly in the old cmdAdd.Click()tbrGen

    BeforeFormControlMethod() removedAfterFormControlMethod() removedControlSelection() modifiedtbrSCADONav

    Click() modified to add/insert the new 1st

    parameter passed to THISFORM.ControlSelection()OnTimer() modified to call _Screen.ActiveForm.ActionButtonRefreshLogic() when indicatedcmdFind.Click() modifiedLinkedMenu() modified to update the SKIP FOR logic, also required updating the STRINGS.DBF records for \

  • 7/15/2019 VM4UPGRD

    7/72

    4. Update your existing VMP-required main database and ZZCONFIG.DBF free table.

    If you have Stored Procedures of your own (not the VMP-created ones), save them to a file because this step will deletethe existing stored procedures.

    DO XXFWDATA WITH "ZZ","MIN",.T. to replace the APPCONFIG (ZZCONFIG.DBF) and APPINFO tables, replacethe USERS table, and replace the V_USERS view with the V_USERSLIST view. For those APPINFO/APPCONFIGrecords where your application uses non-default values, update those tables in the new ZZ.DBC database. If yourexisting application adds records to the APPCONFIG/APPINFO tables, add those to the new ZZ.DBC database. Update

    the USERS table in the new ZZ.DBC database with the equivalent records in the existing application.

    DO XXFWDATA WITH "ZZ","USERPREFS",.T. to replace the USERPREFS table. All existing user preferences willbe lost, which is generally no big deal, but if you want you can append the records from the existing USERPREFS table the only changes in VMP 4.0 is larger field sizes.

    DO XXFWDATA WITH "ZZ","SECURITY",.T. if you want to implement the optional VMP user security system in theapplication (and you have Visual MaxFrameProfessional)

    DO XXFWDATA WITH "ZZ","RI",.T. to add necessary VMP-specific Referential Integrity meta data, whether youintend to use the VMP RI engine or not we use it to enforce RI on the VMP tables in the .DBC database.

    Copy any Stored Procedures you saved above into the Stored Procedures of the updated .DBC database.

    5. All your existing classes point to/inherit from classes that no are no longer valid they have either been renamed(X3*.VCX to XX*.VCX) and/or have been copied to a new folder. For each class you've subclassed directly from theVMP framework (typically the ZZFW*.VCX class libraries at the app-specific level), the ClassLibrary property (indicateswhere the ParentClass is located) has to be updated. You can accomplish this in the Class Browser or by attempting toopen the class in the Class Designer, and locating the parent class library in the Locate dialog; or you can hack each app-specific .VCX and update the ClassLoc field, which displays in the Class Designer as the ClassLibrary property:use

  • 7/15/2019 VM4UPGRD

    8/72

    11. If you have a frmZZDataEntrySCADO form class but do not have one or more of the following button classes in yourZZFWCTRL.VCX, create them now, with the following property settings:

    ClassName Caption icType Cancel cmdZZDataFind \

  • 7/15/2019 VM4UPGRD

    9/72

    22. Delete your ZZ.PJX project file. Create a new one and add ZZMAIN.PRG as the main calling program. Rebuild theproject, and ignore all the complaints about not being able to find files (you can just select the first time youget the dialog). Review the log of errors the Project Manager creates, and modify the problem code, which should mainlyconsist of X3*.*calls that need to be changed to XX*.* references, usually those files that are marked with an asterisk inthe listings in the previous MODIFICATION: X3 prefix changed to XX section. You may have to Rebuild theZZ.PJX project several times to find all the now-invalid references.

    23. Review the project and add any other files that were not pulled in automatically, including the .DBC, free tables,MSGSVC.DBF (and STRINGS.DBF if it's an INTL-Toolkit app), FLLs, etc. It's particularly important to make sure

    your .DBC(s) are added to the project, because they can contain Stored Procedure code that needs to be checked forreferences to X3*.* files that have been renamed to XX*.* counterparts.

    24. Find any remaining references to the renamed VMP framework files by DOing XXDTSRCH WITH foreach of the files marked with an asterisk in the listings in the previous MODIFICATION: X3 prefix changed to XXsection. For class libraries, note that you should DO XXDTSRCH WITH the filename minus the ".VCX" extension

    because some class library references don't include the extension (for example, when calling X3SETCLS(), the extensionfor the .VCX file name is optional). Once you find each X3 version of these files, change the "X3" to "XX". You canmodify each occurrence right in the XXDTSRCH dialog by selecting each item in the Search Results form ofXXDTSRCH and selecting the button/Modify from the shortcut menu/double-clicking on the listbox row.

    25. Several records in ZZCONFIG/APPINFO likely contain references to X3FW*.VCX in theAp_ItemValue/App_ItemValue field. Update them to specify the new XX files.

    26. DO VM34UTL1.PRG (the resulting output is named < ProjectName.VM4>) on your existing application in VMP3.0/3.01. DO VM34UTL1.PRG from the Command Window, in the normal development environment for the app (as ifyou were going to develop the application pathing set correctly, etc.).

    27. Relocate/update PEMs from instances of old cmdZZDataAdd/Cancel/Delete/Find/OK/Print/Save buttons to their newlocation on the containing form. The output from VM34UTL1.PRG likely contains just about everything (and more)that's needed here; print out the ZZ.VM4 file, copy it to a document, etc., use it to copy/paste existing code. Analternative to the ZZ.VM4 output is to DO X3DTEPEM (on yourbackup application) for each PEM listed here to trackdown places in your existing application where each PEM is explicitly set/coded.

    Note that if you have any buttons of this type that you have been rendering permanently invisible by setting Visible=.F.and Enabled=.F. in the Properties Sheet, you are likely to have to accomplish the same thing henceforth by setting thosetwo properties in the Refresh() method instead.

    Be sure to review all the code for accuracy before pasting to its new location (THIS has a different meaning when thecode is transferred to the form level, DODEFAULT() and manual callbacks refer to a different class inheritancehierarchy, etc.).

    Please don't be intimidated by the length of this comprehensive list; you are not likely to have much actual work here.

    If you have explicitcode/settings for this VMP3.01 Method/Property (DOX3DTEPEM on this itemor refer to ZZ.VM4 output)

    in an instanceinheriting from thisVMP 3.01 Class

    then transfer/migrate that PEM code/setting to thisVMP 4.0 location

    ShellBeforeAppendBlank X3FWCTRL.VCXcmdDataAdd

    The containing form AddBeforeAppendBlank() note thatit can now RETURN .F. to bring the to a halt

    ShellAfterAppendBlank X3FWCTRL.VCXcmdDataAdd

    The containing form AddAfterAppendBlank()

    Click (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataAdd

    Augment the containing form AddAction or maybe putsome/all the code in the containing formAddBeforeAppendBlank/AddAfterAppendBlank

    Refresh (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataAdd

    Likely goes in the Refresh() of the instance, overriding theframework abstracted behavior. Note that if you'vefollowed the retrofitting instructions above carefully, thiscode should be preserved on MODIFYing the containingFORM/CLASS at this point

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 9

  • 7/15/2019 VM4UPGRD

    10/72

    Click (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataCancel

    Augment the containing form CancelAction()

    Click (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataOK

    Augment the containing form OKAction()

    Click (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataFind

    Augment the containing form FindAction()

    Refresh (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataFind

    Likely goes in the Refresh() of the instance, overriding theframework abstracted behavior. Note that if you'vefollowed the retrofitting instructions above carefully, thiscode should be preserved on MODIFYing the containingFORM/CLASS at this point

    DoTheFind X3FWCTRL.VCXcmdDataFind

    Containing form.FindUI(), existing code most likelytransfers here unchanged

    icFreeTableTag X3FWCTRL.VCXcmdDataFind

    Containing form icFindActionTag

    Click (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataSave

    Augment the containing form SaveAction()

    Refresh (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataSave

    Likely goes in the Refresh() of the instance, overriding theframework abstracted behavior. Note that if you'vefollowed the retrofitting instructions above carefully, thiscode should be preserved on MODIFYing the containingFORM/CLASS at this point

    ShellBeforePreSave X3FWCTRL.VCXcmdDataSave

    Containing form SaveBeforeAnything()Also, if you did any explicit messaging to the user, thatshould be replaced by populatingTHISFORM.iaSaveFailureInfo[] seeXXFWFRM.VCX/frmDataEntry.SaveAction() headercomments.

    PreSave X3FWCTRL.VCX

    cmdDataSave

    Containing form SaveGenAndPopPK()

    Also, if you did any explicit messaging to the user, thatshould be replaced by populatingTHISFORM.iaSaveFailureInfo[] seeXXFWFRM.VCX/frmDataEntry.SaveAction() headercomments.

    ShellAfterPreSave X3FWCTRL.VCXcmdDataSave

    SaveBeforeUpdateBuffers()Also, if you did any explicit messaging to the user, thatshould be replaced by populatingTHISFORM.iaSaveFailureInfo[] seeXXFWFRM.VCX/frmDataEntry.SaveAction() headercomments.

    ProcessDataEntryGrids X3FWCTRL.VCXcmdDataSave

    frmDataEntry does not have a corresponding method thelogic is replaced by calls in SaveAction to each data-entrygrid's OnFormSaveAction() method.

    Also, if you did any explicit messaging to the user, thatshould be replaced by populatingTHISFORM.iaSaveFailureInfo[] seeXXFWFRM.VCX/frmDataEntry.SaveAction() headercomments.

    CheckRequiredFields X3FWCTRL.VCXcmdDataSave

    SaveCheckRequiredFields()

    AfterUltimateSuccess X3FWCTRL.VCXcmdDataSave

    SaveAfterSuccess()

    AfterUltimateFailure X3FWCTRL.VCX SaveAfterFailure()

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 10

  • 7/15/2019 VM4UPGRD

    11/72

    cmdDataSave

    UpdateAddOnTheFlyRecord X3FWCTRL.VCXcmdDataSave

    SaveUpdateAddOnTheFlyRecord()

    MessageOnFailure X3FWCTRL.VCXcmdDataSave

    SaveMessageOnFailure()

    ODBCErrorMessage X3FWCTRL.VCXcmdDataSave

    SaveODBCMessageOnFailure()

    ilSuppressGridErrorMessage X3FWCTRL.VCXcmdDataSave

    removed

    Click (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataDelete

    Augment the containing form DeleteAction(), or possiblylocate in one of the new methods: DeleteBeforeAnything()DeleteAfterFailure(), DeleteAfterSuccess()

    Refresh (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataDelete

    Likely goes in the Refresh() of the instance, overriding theframework abstracted behavior. Note that if you'vefollowed the retrofitting instructions above carefully, thiscode should be preserved on MODIFYing the containingFORM/CLASS at this point

    UserConfirmation X3FWCTRL.VCXcmdDataDelete

    Containing form DeleteConfirmation() combines both theold UserConfirmation() and MessageText()

    MessageText X3FWCTRL.VCXcmdDataDelete

    Containing form DeleteConfirmation() combines both theold UserConfirmation() and MessageText()

    TakeActionOnFailure X3FWCTRL.VCXcmdDataDelete

    no longer applicable instead, theSaveMessageOnFailure() is called from DeleteAction()

    ShellAdditionalDeleteAction X3FWFRM.VCXfrmDataEntry

    Form.DeleteAdditionalAction()

    Click (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataPrint

    Augment the containing form PrintAction()

    Refresh (don't bother DOingX3DTEPEM on this one)

    X3FWCTRL.VCXcmdDataPrint

    Likely goes in the Refresh() of the instance, overriding theframework abstracted behavior. Note that if you'vefollowed the retrofitting instructions above carefully, thiscode should be preserved on MODIFYing the containingFORM/CLASS at this point

    To verify that your class libraries have been successfully upgraded to VMP 4.0, load your ZZ.PJX project up in the ClassBrowser in the Open Dialog, change the "Files of type" dropdown to "Project", and select your ZZ.PJX project file. If themigration has been completed successfully:

    1. No classes should have a

  • 7/15/2019 VM4UPGRD

    12/72

    The OnUpdateFormOnNew method has been renamed to OnUpdateFormOnNav

    XXFWCTRL.VCXcmdDataMovePointerThe ilUpdateFormOnNew property has been renamed to ilUpdateFormOnNav

    Retrofitting Instructions1. In the VMP 3.01 version of your app, DO X3DTEPEM WITH "OnSave" and copy any such explicit method code to the

    OnFormSaveAction method of the same grid class/instance in the VMP 4.0 version of your app.2. In the VMP 3.01 version of your app, DO X3DTEPEM WITH "UpdateFormOnNew" and copy any such explicit method

    code to the UpdateFormOnNav method of the same grid class/instance in the VMP 4.0 version of your app.3. In the VMP 3.01 version of your app, DO X3DTEPEM WITH "OnUpdateFormOnNew" and copy any such explicit

    method code to the OnUpdateFormOnNav method of the same grid class/instance in the VMP 4.0 version of your app.4. In the VMP 3.01 version of your app, DO X3DTEPEM WITH "ilUpdateFormOnNew" and copy the value of this

    property to the ilUpdateFormOnNav property of the same button class/instance in the VMP 4.0 version of your app.

    MODIFICATION: PEM reorganizationThe major PEM reorganization described in the previous section almost entirely affects Visual MaxFrame Professional only,

    but there is one change at the Visual MaxFrame level.

    XXFW.VCXfrmDataPrintReport() renamed to PrintAction() (and all references to this method updated accordingly)

    MovePointer() modified to accept an optional 5th

    parameter, act on it to determine the Form.Refresh() behaviorfrmBaseProximityLabel() enhanced to return the Header if the passed control is a grid.column control

    Retrofitting Instructions1. If you have any code in the PrintReport() method of any existing forms, copy this code to the new PrintAction() method.2. Replace any calls in your application specific code to THISFORM.PrintReport() or THIS.PrintReport() to call the

    PrintAction() method instead.

    ENHANCEMENT: data-entry grid revisions and new "child cursor object"This enhancement starts with the idea of splitting out some PEMs from XXFWGRD.VCX/grdDataEntry in Visual MaxFrameProfessional into a separate "child cursor" class definition so that those behaviors can be accessed by parent-child data-entryimplementations other than a data-entry grid.

    During the course of making this enhancement, XXFWGRD.VCX/grdDataEntry was completely overhauled, and therevisions touched classes in XXFW.VCX in Visual MaxFrame.

    The following are the high-level changes that were made:

    XXFWGRD.VCX/grdDataEntry custom property .ilAllowAddNew was removed, along with its related PEMs. The

    native VFP .AllowAddNew behavior is now allowed, although it has a number of problems (some documented ingrdDatEntry.zReadMe) and an alternative "pre-fill" technique is recommended (also documented ingrdDataEntry.zReadMe).

    XXFWGRD.VCX/grdDataEntry PEMs that are strictly for the management of "child cursor" aspects of a data-entry grid

    have been migrated to a new XXFWMISC.VCX/cusChildCursorSvc class where they can be accessed by otherimplementations of the typical parent-child scenario. The VM example app includes form examples VMDECUS6.SCXand VMDECUS7.SCX.

    XXFWGRD.VCX/grdDataEntry has been enhanced to add a complete set of OnForm..Action() methods and

    OnUpdateFormOn..() methods to receive messages from THISFORM (frmDataEntry) at the importantAdd/Edit/Delete/Save/Cancel/Navigate events at the form level. These are the same methods asXXFWCOMP.VCX/ctrDERegisteredComposite has for the same reason.

    Messaging the user on a failed in XXFWFRM.VCX/frmDataEntry.SaveAction()/SaveMessageOnFailure() has

    been revamped to make it easier to handle specific messages when the failure occurs for reasons other than afailed THISFORM.UpdateBuffers(). A new iaSaveFailureInfo array of information is established inXXFW.VCX/frmData to hold this information which can be updated at any point during the process, and, if so,used to message the user. If not, the user receives the default messaging abstracted intofrmDataEntry.SaveMessageOnFailure().

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 12

  • 7/15/2019 VM4UPGRD

    13/72

    XXFW.VCXcmdBaseKeyPress() modified to remove the code to set Grid.inLastnKeyCodechkBaseKeyPress() modified to remove the code to set Grid.inLastnKeyCodespnBase

    KeyPress() modified to remove the code to set Grid.inLastnKeyCodetxtBase

    KeyPress() modified to remove the code to set Grid.inLastnKeyCode

    pgfPageRefreshSeeIfPageNeedsRefreshing() modifiedfrmData

    iaSaveFailureInfo newicFailedUpdateTableAlias removed, replaced by THIS.iaSaveFailureInfo[4]grdBaseInit() modifiedWhen() modifiedRefresh() modifiediaRelationInfo newStoreRelationInfo() newIsCurrentRowBlank() -- new

    XXFWMISC.VCXcusChildCursorSvc new class

    XXFWGRD.VCXgrdDataEntryMany PEMs in this class have been removed, several new ones have been added, and EVERYremaining method in this classhas been modified. The net effect of these modifications should mean little or no retrofitting chores, but you should reviewthe list of notable items just in case.

    Methods that have been Reset To Default:Refresh()

    PEMs that have been modified:

    icPKFieldName now REQUIRED, not optional (but can be set to .NULL. to indicate that PK generation should be ignored),check all your data-entry grids to make sure this property is set explicitly, either in the Properties Sheet, or in method code

    Init()

    OnFormDestroy()

    OnFormSaveAction()

    AddRow()

    BeforeRowColChange()

    AfterAppendBlank()

    CommonColumnControlLostFocus()

    PEMs that have been removed, you should DO XXDTSRCH to see if you have any explicit references that needupdating:GenAndPopKeys() behavior transferred to cusChildCursorSvc (in VMP 3.01, this behavior was abstracted ingrdDataEntry.OnSaveAfterDeleteBlankRows)

    SetLastRecno() behavior eliminated, you will likely have code that needs to simply remove these calls, especially commonin the ShellRequery() method of data-entry grids

    inLastRecno eliminated along with SetLastRecno()

    BeforeAppendBlank()

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 13

  • 7/15/2019 VM4UPGRD

    14/72

    ilAllowAddNew

    inLastnKeyCode

    ilRIDelete

    DeleteAllRows()

    DeleteCascade()

    DeleteChildrenInGrids()

    PrepareForDeleteCascade()

    inSaveRecno

    SaveRecno()

    RestoreRecno()

    UpdateAddOnTheFlyRecord()

    ilRegisterWithForm

    icParentViewAlias -- DO XXDTEPEM with "icParentAlias" and make sure all your grdDataEntry.icParentAlias propertiesreflect the ALIAS() of the .icParentPKFieldName property

    PEMs that are new:

    icChildCursorClass

    ilAllowAddNewRecord

    ioChildCursor

    IsRecnoTheLastRow()

    OnFormAddAction()

    OnFormCancelAction()

    OnFormDeleteAction()

    OnFormUpdateBuffers()

    OnUpdateFormOnAdd()

    OnUpdateFormOnCancel()

    OnUpdateFormOnDelete()

    OnUpdateFormOnEdit()

    OnUpdateFormOnNav()

    OnUpdateFormOnSave()

    AfterAppendBlank() -- code migrated here from AddRow()

    XXFWGRD.VCXcmdDEGridDeleteClick() modified to remove the parameters passed to Grid.DeleteCurrentRow()

    cmdDEGridAddRefresh() -- modified

    MODIFICATION: XXFW.VCX/pgfPageRefresh.FormContainsDataEntryGrids() method removedSince XXFWFRM.VCX/frmDataEntry.iaDataEntryGrids[] is an array of public scope, this method is unnecessary and has

    been removed.

    XXFW.VCXpgfPageRefreshFormContainsDataEntryGrids() removedSeeIfPageNeedsRefreshing() modified

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 14

  • 7/15/2019 VM4UPGRD

    15/72

    Retrofitting InstructionsNo retrofitting required unless you have calls to the pageframe.FormContainsDataEntryGrids() method, in which can bereplaced by a check for TYPE("THISFORM.iaDataEntryGrids[1,1].BaseClass") = "C", as is done in

    pgfPageRefresh.SeeIfPageNeedsRefreshing(). (In VFP 6.0 apps, you can use the VARTYPE() function instead.) To find anysuch calls, DO XXDTSRCH WITH ".FormContainsDataEntryGrids(".

    MODIFICATION: XXFWGRD.VCX/cmdDEGridDelete behaviors migrated to grdDataEntrySome of the XXFWGRD.VCX/cmdDEGridDelete.Click() behavior belongs in grdDataEntry, so it can be invoked no matterhow the action is initiated. Specifically, the user confirmation logic.

    XXFWGRD.VCXgrdDataEntryDeleteConfirmation() new methodDeleteCurrentRow() modifiedcmdDEGridDeleteClick() modifiedUserConfirmation() removed

    Retrofitting InstructionsIf you have any explicit Click() code or UserConfirmation() code, that logic may have to be modified/migrated to theassociated data-entry grid. You can check for explicit UserConfirmation() code by DOing XXDTEPEM WITH"UserConfirmation".

    UPDATE: MSGSVC.DBF and STRINGS.DBFThe MSGSVC.DBF and STRINGS.DBF tables contain many new records to accommodate new VMP 4.0 features. VMP 4.0includes a utility, XXDTMEST.PRG that makes it relatively simple to update your app-specific versions of these tables(STRIGNS.DBF is optional, and only applies to INTL-Toolkit apps). At the Command Window, DO XXDTMEST and fillin the information in the dialog. Note that if you have not added any app-specific MSGSVC.DBF and STRINGS.DBF tables,you can skip this step, since there is nothing to update.

    FEATURE: user securitySee the USER SECURITY and RELATED FEATURES section of this document for information on retrofitting madenecessary by user security enhancements.

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 15

  • 7/15/2019 VM4UPGRD

    16/72

    ENHANCEMENTS, MODIFICATIONS, NEW FEATURES

    This section lists the rest of the VMP 3.01 VMP 4.0 enhancements, modifications, and new features. Retrofittinginstructions are included where appropriate/necessary.

    APPLICATION SETUP and UTILITIES

    ENHANCEMENT: new VMP RI "engine"We've added a VMP RI "engine" to VMP 4.0. We use this RI engine to enforce RI on the VMP system tables in the VMP-required database, but you're welcome to use it for all your RI needs in local VFP databases. Read all about it in Chapter 15:Referential Integrity in the VMP 4.0 Reference Guide.

    Retrofitting InstructionsSee Chapter 15: Referential Integrity of the VMP 4.0 Reference Guide.

    MODIFICATION: X3GENPK() handles generic character IDs properlyHeretofore X3GENPK() generated integer keys whenever the 7 th optional tlGenericID parameter was passed as .T., no matterwhat you specified for the 5th tlNumeric parameter. In this modification, X3GENPK() now respects the tlNumeric parameterwhen tlGenericID is passed as .T. Also, when tlGenericID is passed as .T., the 2nd parameter is irrelevant and is ignored.

    X3GENPK.PRG -- modified

    Retrofitting InstructionsFor any existing calls to X3GENPK() for which you've passed the 7th tlGenericID parameter as .T., you need to make sure the5th tlNumeric parameter is passed explicitly as .T. in order to maintain the old behavior of generating numeric/integer keys.DO XXDTSRCH WITH "X3GENPK(" to find any such calls to X3GENPK.

    MODIFICATION: X3GENPK() skips more charactersX3GENPK.PRG has been modified to skip more characters than before. Please see the local PROCEDUREIncrementAlphaNumeric for the updated list of skipped characters when generating character keys.

    X3GENPK.PRG -- modified

    No retrofitting required

    Existing applications will simply start skipping additional characters from now on.

    ENHANCEMENT: developer OKLs and function keys are saved/restoredXXFWMAIN.PRG has been enhanced to save/restore OKLs and function key assignments in effect in the developmentenvironment.

    XXFWMAIN.PRG

    No retrofitting required

    ENHANCEMENT: improved technique for preventing multiple instances of the app at oneworkstation

    We've implemented a variation of George Tasker's article in the November 1998 issue of FoxPro Advisor magazine to preventmultiple instances of the app at one workstation. It is faster (especially when Steven Black's INTL Toolkit is installed) andmore reliable than the technique we have been using in previous versions of VMP.

    XXFW.VCXctrAppSetupMultipleInstances() modifiedDestroy() modifiedInit() -- modified

    No retrofitting required

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 16

  • 7/15/2019 VM4UPGRD

    17/72

    ENHANCEMENT: login form times outIn previous versions, the VMP login form class doesn't timeout. Even if an application-level timeout is in effect, because thatis setup much later in application startup, just before the READ EVENTS.

    XXFW.VCXfrmLogintmrTimeout new timer member times out the login form after 5 minutes

    Retrofitting InstructionsNo retrofitting is required unless you want to change the default 5 minute timeout interval.

    ENHANCEMENT: suppress the default oMenu _MSYSMENUIf your application must suppress the installation of a _MYSMENU system menu, XXFW.VCX/cusForms.zReadMe()contains the simple instructions to make it happen.

    XXFW.VCXcusMenuzReadMe() updated

    No retrofitting required

    ENHANCEMENT: Support for German toolbar/project save/restore when running an appThe class definitions contained in XXFWMAIN.PRG that save/restore extant Projects and standard VFP toolbars whenrunning a VMP app from the Command Window have been enhanced to handle Projects/VFP toolbars when the German

    localized version of VFP is running.

    XXFWMAIN.PRGcusPushPopVFPToolbarsInit() modifiedcusPushPopProjectManagerInit() modified

    No retrofitting required

    ENHANCEMENT: check for app shutdown conditions periodicallyAt strategic junctures, a new oApp.ShutdownCheck() method is called to check for conditions that indicate if the app should

    be shutdown forcibly, and, if so, messages the user and executes the existing oApp.ForceShutdown() method.

    XXFW.VCXctrAppOnTimer() modifiedShutdownCheck() new methodLogout() modifiedcusMenuDoForm() modifiedDoPRG() modifiedcusFormsDeleteInstance() modified

    XXFWFRM.VCXfrmDataEntryCancelAction() modified

    XXFWMISC.VCXfrmReportLoad() modified

    No retrofitting required

    ENHANCEMENT: oUser.oPrefs.SetPref() and .GetPref() can set/get the DescriptionoUser.oPrefs.SetPref() and GetPref() take an additional optional parameter that allow setting/getting theUserPrefs.Prf_ItemDescription value.

    XXFW.VCX

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 17

  • 7/15/2019 VM4UPGRD

    18/72

    cusUser

    SetPref() modifiedGetPref() modified

    No retrofitting required

    ENHANCEMENT: oApp.GetAppInfo() can return the descriptionBy passing the new optional 2nd parameter as .T. to oApp.GetAppInfo(), you can RETURN the Description field value insteadof the Item value.

    XXFW.VCXctrApp

    GetAppInfo() -- modified

    No retrofitting required

    ENHANCEMENT: XXFWDATA.PRG supports Integer keysFor VMP developers desiring to use Integer primary/foreign keys, XXFWDATA.PRG has been modified to support Integerkeys via a new 4th parameter.

    The Visual MaxFrame Professional Application Setup Wizard has been modified to allow specifying Integer keys (the wizardcalls the local procedures in XXFWDATA to create the initial main VMP database).

    XXFWDATA.PRG -- modified

    XXWB.VCXfrmWizAppSetupFinishAction_CreateDatabase() -- modified

    No retrofitting required

    ENHANCEMENT: multiple instances attempted from one workstationThe behavior you get when the user attempts to fire up another (second) instance of your VMP app at one workstation is nowcontrolled by a new record in the APPCONFIG table, for "MultipleInstancesOneWorkstation", which can have one of threevalues:

    0/default: The second/additional instance of your app shuts down and the first/existing instance is made the foreground

    app.

    1: The user is alerted via a MSGSVC() dialog that they are not allowed a second instance and the second/additional

    instance shuts down. 2: The second/additional instance is allowed to execute.

    As was the case previously, this action is taken in oApp.SetupMultipleInstances(), which has been modified accordingly.

    XXFWDATA.PRG new "MultipleInstancesOneWorkstation" record

    X2WEXIST.PRG no longer called, no longer distributed with Visual MaxFrame Professional

    XXFW.VCXctrAppSetupMultipleInstances() modified to check the behavior specified inoApp.GetAppInfo("MultipleInstancesOneWorkstation")

    Retrofitting Instructions

    No retrofitting required unless:1. You have explicit code the SetupMultipleInstances() of an oApp subclass that conflicts or is rendered unnecessary by thisenhancement. DO XXDTEPEM WITH "SetupMultipleInstances" to review any such explicit code.

    2. You have (non VMP framework) code that calls X2WEXIST(), which is no longer distributed with Visual MaxFrameProfessional. If so, you'll need to copy the X2WEXIST.PRG from VMP 3.01 to your VMP 4.0 \XLIB directory/folder.DO XXDTSRCH WITH "X2WEXIST" to find any such explicit calls.

    ENHANCEMENT: Top-Level Form appsA late addition to VMP 3.01 in the 9/8/98 build were a few modifications to make it easier to build Top-Level Form/SDI appsin VMP. This enhancement adds a few more modifications.

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 18

  • 7/15/2019 VM4UPGRD

    19/72

    XXFWMAIN.PRGModified to call a new oApp.InitialVisibleActions() method to handle _Screen visibility and release any installed splashscreen to make it easier to customize these behaviors.

    The Visual MaxFrame Professional Application Setup Wizard has been enhanced to allow setting the new oApp.ilSDIAppproperty.

    XXFW.VCXctrAppilSDIApp_Assign() new method

    ioSDIForm new propertySaveReset() modifiedInitialVisibleActions() modifiedSetupScreen() modifiedInstallWallPaper() modifiedDestroy() modifiedSetSDIParentForm() new methodcusMenu

    Init() modifiedInstallInitialMenu() modified

    XXWBAPPS.PRG/Application Setup WizardThe Application Setup Wizard has been modified to allow setting oApp.ilSDIApp.

    ENHANCEMENT: New custom methods to handle Tools/Options changesGlobal application objects now have custom OnToolsOptionsChange() methods to handle changes made via typicalTools/Options dialog.

    XXFW.VCXctrAppOnToolsOptionsChange() new public methodcusFormsOnToolsOptionsChange() new public methodcusUserOnToolsOptionsChange() new public methodcusToolbarsOnToolsOptionsChange() new public methodcusMenu

    OnToolsOptionsChange() new public methodfrmBaseOnToolsOptionsChange() new public methodtbrBaseOnToolsOptionsChange() new public method

    No retrofitting required

    ENHANCEMENT: control the ROLLOVER portion of SET CENTURY TO via APPCONFIG recordXXFW.VCX/ctrApp.SetupSets() has been enhanced in VMP 4.0 to ensure that VFP 5.0 apps use the new default behavior ofVFP 6.0 for SET CENTURY TO..ROLLOVER (in VFP 5.0, a plain SET CENTURY TO results in the century being set to19, even in the year 2000). In this further enhancement, you can specify the ROLLOVER year in an APPCONFIG record"SetCenturyToRollover".

    XXFW.VCXctrAppInit() modified to call the new SetupSets2() methodSetupSets() modifiedSetupSets2() new method

    XXFWDATA.PRG modified to add the new "SetCenturyToRollover" default record (defaults to 50)

    No retrofitting required

    MODIFICATION: Size of APPCONFIG/APPINFO item value fields increased

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 19

  • 7/15/2019 VM4UPGRD

    20/72

    XXFWDATA.PRG increases the size of Ap_ItemVal and App_ItemVal from C(100) to C(254).

    XXFWDATA.PRG

    No retrofitting required

    MODIFICATION: SET CENTURY TO ROLLOVER defaultThe default SET CENTURY.. setting established/abstracted in oApp has changed from SET CENTURY TO 19 ROLLOVER50 to a setting that mimics the default/plain SET CENTURY TO setting in VFP 6.0 an implicit SET CENTURY TO ROLLOVER . For example, if you start a Visual

    MaxFrame application in 1998, oApp.SetupSets() issues a SET CENTURY TO 19 ROLLOVER 48.

    XXFW.VCXctrAppSetupSets() -- modified

    No retrofitting required

    ENHANCEMENT: oApp.InstallBitmapWallpaper() updatedIn this enhancement, XXFW.VCX/ctrApp.InstallBitmapWallpaper() has been renamed to InstallWallpaper because VFP 6.0also supports .GIF and .JPG files. Also, the InstallWallpaper() method code has been modified to support Top-Level (SDI)form applications

    XXFW.VCXctrApp

    InstallBitmapWallpaper() removed (renamed)InstallWallpaper() new public method (the old InstallBitmapWallpaper(), plus some modifications

    Retrofitting InstructionsIf any of your existing apps have overriding/augmented code in the InstallBitampWallpaper() of oApp subclasses, you'll haveto move that code to the new InstallWallpaper() method. DO XXDTEPEM WITH "InstallBitmapWallpaper" to find any suchmethods.

    If you have any code that calls oApp.InstallBitmapWallpaper(), it needs to be modified to call oApp.InstallWallpaper()instead. DO XXDTSRCH WITH ".InstallBitmapWallpaper" to find any such references.

    ENHANCEMENT: Easy to perform initial oApp instantiation checking, abort if necessaryA new shell/empty method called early on in oApp.Init() makes it easy to add your own custom code to peform checks and, if

    necessary, abort/terminate the app startup process. See the new XXFW.VCX/ctrApp.SetupHook1() for all the details.XXFW.VCX

    ctrApp

    Init() modifiedSetupHook1() new method

    No retrofitting required

    However, if you've been doing the same type of thing in more complicated code augmenting oApp.Init(), you can likelysimplify that code and move it to the new SetupHook1() method.

    ENHANCEMENT: additional oApp.SetAppInfo() parameter to suppress the TABLEUPDATE()XXFW.VCX/ctrApp.SetAppInfo() has been enhanced to add a 5th optional parameter allowing you to suppress theTABLEUPDATE() so that it can be performing it manually if necessary/desired after making several updates.

    XXFW.VCXctrAppSetAppInfo() -- modified

    No retrofitting required

    ENHANCEMENT: oApp sets _Screen.Icon to XXFWBLNK.ICO by defaultIf no application/_Screen.Icon has been specified, XXFW.VCX/ctrApp.SetupScreen() installs XXFWBLNK.ICO to

    _Screen.Icon.

    XXFW.VCX

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 20

  • 7/15/2019 VM4UPGRD

    21/72

    ctrApp

    SetupScreen() -- modified

    No retrofitting required

    unless, of course, you prefer the FoxHead icon

    ENHANCEMENT: User Preferences services split out into new/separate classThe User Preferences engine has been removed from oUser into a new separate XXFW.VCX/cusUserPrefs class definition.Once the user has successfully logged in, an instance of the new class (or a subclass you specify) is AddObject()ed to oUser as

    an oPrefs member (oUser.oPrefs). User Preferences (if you decide to run with them enabled) are now driven by a view of theUserPrefs table. The "INTLLanguage" preference has been moved from the UserPrefs table to the Users table, to a newUsr_INTLLanguage C(20) field.

    This enhancement provides 3 main improvements:1. The user preferences engine runs much faster, since the lookups are done in an indexed view which VFP creates on the

    local workstation if possible (in the TMPFILES/SORTWORK directory for local views, in the TMPFILES directory forremote views if no TMPFILES/SORTWORK are specified, then the views are created in the \WINDOW\TEMPdirectory).

    2. The user preferences engine runs fine when the UserPrefs table is in a remote database (seeXXFW.VCX/cusUserPrefs.zReadMe)

    3. More flexibility when you want/need to substitute/modify to the default user preferences engine.

    To turn off user preferences, see XXFW.VCX/cusUserPrefs.zReadMe().

    Note that the new XXFW.VCX/cusUserPrefs class provides the following services that are new to this enhancement andpreviously unavailable in VMP:1. The custom ResetAllPrefs() method allows "resetting" the preferences for the passed user(s) by deleting all their records

    in the UserPrefs table.2. The custom StopPrefs() and StartPrefs() allow "turning off" user preferences on a per-user basis (see

    XXFW.VCX/cusUserPrefs.zReadMe() for turning off preferences for the entire app)

    If you have Visual MaxFrame Professional, the VMTOPTS.SCX dialog in the VM example application has beenenhanced/updated to allow the user to enable/disable the saving/restoring of user preferences.

    XXFW.VCXcusUserPrefs new class

    Also, three new MSGSVC records:"Preferences reset but unavailable""Preferences unable to reset""Save, unable, default language"

    cusUser

    Init() modifiedLocalize() -- modifiedicUserPrefsClass new protected propertySetupUserPreferences() new protected method to AddObject() the oPrefs memberilUserPrefsSeekTag removed, no longer necessaryGetFormObjPrefString() migrated to the new XXFW.VCX/cusUserPrefs classGetUserPreference() migrated to the new XXFW.VCX/cusUserPrefs class, where it has been renamed GetPref()SetUserPreference() migrated to the new XXFW.VCX/cusUserPrefs class, where it has been renamed SetPref()SaveUserPrefs() migrated to the new XXFW.VCX/cusUserPrefs class, where it has been renamed SavePrefs()

    RestoreUserPrefs() migrated to the new XXFW.VCX/cusUserPrefs class, where it has been renamed RestorePrefs()ctrAppLocalize() -- modified(many other classes have been modified to call oUser.oPrefs PEMs instead of oUser PEMs)

    XXFWDATA.PRGModified to split the creation of USERPREFS and V_USERPREFS into a separate local procedureModified to add the new Usr_INTLLanguage field to USERPREFS and V_USERPREFS (with a DefaultValue of "Original")Modified to add the new Usr_EnablePrefs field to USERPREFS and V_USERPREFS (with a DefaultValue of .T.)Modified to change the parameter for the V_USERS view from "lcUsr_PK" to "luUsr_PK" (the primary key may be integer)

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 21

  • 7/15/2019 VM4UPGRD

    22/72

    Retrofitting InstructionsIf you have any app-specific references to the former ?lcUsr_PK parameter for the V_USERS parameterized view, you'll needto change them to ?luUsr_PK. DO XXDTSRCH WITH "lcUsr_PK" to track them down.

    If your existing application(s) are INTL-enabled, you'll need to make sure your USERS table adds the newUsr_INTLLanguage C(20) field, populated with "Original" or whatever language is currently set for each user in any existingUserPrefs table. Ditto for the new Usr_EnablePrefs L(1) field, populated with a logical value indicating whether that userwants to run with user preferences enabled/disabled.

    If you are not running with user preferences, you likely have nothing to do except maybe to make sure your main VisualMaxFrame-required database does not have a USERPREFS table. If you are running with user preferences, read on:

    You'll have to create the V_USERPREFS view. Depending on your situation, you can use XXFWDATA.PRG to do it:OPEN DATA DO XXFWDATA with ,"USERPREFS"

    If you have explicit references to the USERPREFS table, you'll likely need to change them to the new V_USERPREFS view.DO XXDTSRCH to find such references to USERPREFS.

    If you have any explicit (non framework) calls to oUser methods listed above that have been migrated to the newXXFW.VCX/cusUserPrefs class definition, you'll have to update them to call oUser.oPrefs instead of oUser, and to use thenew method name. DO XXDTSRCH to find such calls.

    ENHANCEMENT: easy to run an application without user preferencesIn this enhancement, modifications have been made to eliminate the need to have a USERPREFS table if it doesn't exist, alldefault user preference behaviors are ignored. So if you want the performance benefit of not running the user preferencecode, all you have to do is ensure that the USERPREFS table remains closed during application execution or completelyremove your USERPREFS table (or remote view) and delete it.

    Note that even if USERPREFS is not open/does not exist, some minimal user preference setup code is executed in some classdefinitions. This is so that if you have overridden the user preferences methods in oUser to accommodate your own user

    preferences "engine" that does not use the VMP USERPREFS table, that code will still execute.

    XXFW.VCXcusUser

    SetUserPreference() -- modifiedGetUserPreference() -- modified

    SaveUserPrefs() -- modifiedRestoreUserPrefs() modifiedtbrBaseSaveUserPrefs() modified

    XXFWGRD.VCX (Visual MaxFrame Professional)cusGridPreferenceSavePrefs() -- modifiedRestorePrefs() -- modified

    No retrofitting required

    ENHANCEMENT: easy to setup HelpNew XXFW.VCX/ctrApp.SetupHelp() method is called from oApp.Init() and provides a place to setup Help. The default

    code SETs HELP TO the file (if any) specified in the xxCONFIG.DBF/APPCONFIG record "SetHelpToFile", now generated(blank) by XXFWDATA.PRG.New XXFW.VCX/frmBase.SetupHelp() and XXFW.VCX/frmBase.CleanupHelp() methods allow setting context-specifichelp at the form level.

    XXFW.VCXctrApp

    Init() modifiedDestroy() modifiedSetupHelp() new methodfrmBase

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 22

  • 7/15/2019 VM4UPGRD

    23/72

    GotFocus() modifiedLostFocus() modifiedDestroy() modifiedSetupHelp() new methodCleanupHelp() new method

    Retrofitting Instructions

    Add a "SetHelpToFile" record to your APPCONFIG table, and populate the Ap_ItemVal field with the name of your Helpfile. This retofitting is obviously optional if you have already subclassed oApp or another global Visual MaxFrame object to

    SET HELP TO in a method. See also the header comments in XXFW.VCX/frmBase.SetupHelp() andXXFW.VCX/frmBaseCleanupHelp().

    ENHANCEMENT: specify whether _Screen.Visible gets set to .F. on app startupMany VMP developers have complained that they don't want _Screen.Visible set to .F. when a VMP app is started from theCommand Window. A new optional 2nd parameter is accepted by XXFWMAIN.PRG to make that possible.

    XXFWMAIN.PRGmodified to accept an optional 2nd parameter, and use its value to determine whether to set _Screen.Visible = .F. on appstartup

    Retrofitting Instructions

    No retrofitting is required, but for apps currently in development, you might want to modify the main calling program to passa constant or conditional value as the 2nd parameter to XXFWMAIN.

    ENHANCEMENT: classes in other .APPs can be instantiatedVMP classes and programs have been enhanced to support the optional [IN cAppFileName] clause for the SET CLASSLIBTO command (see also NewObject). This allows creating objects and instantiating .VCX-based forms that are not in themain VMP .APP. See also the last XXFW.VCX/ctrApp.zReadMe notes that describe their usage to create "modules".

    XXFW.VCXcusForms

    DoForm() modified to add an optional 5 th parametercusMenu

    DoForm() modified to add an optional 5 th parameter

    X3SETCLS.PRG modified to add an optional 2nd parameter

    X3SETCPR.PRG modified to add an optional 2nd parameter

    X3WRPFRM.PRG modified to add an optional 3 rd parameter

    No retrofitting required

    APPLICATION SETUP WIZARD

    ENHANCEMENT: Application Setup Wizard sets the oUser.icUsersTableDatabase propertyIf you subclass XXFW.VCX/cusUser to an app-specific oUser object, the wizard sets the oUser.icUsersTableDatabase

    property.

    No retrofitting required

    ENHANCEMENT: Setup Wizard allows you to specify the name/caption of the shortcutThe desktop shortcut page of the Visual MaxFrame Professional Application Setup Wizard allows you to specify the

    Name/Caption of the shortcut, rather than forcing it to the "2-character app prefix".

    No retrofitting required

    ENHANCEMENT: App wizard deletes the File/Log out default XXFWMAIN.MNX menu option

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 23

  • 7/15/2019 VM4UPGRD

    24/72

    VMP 4.0 contains the new "user log out" feature, but when the APPCONFIG record for "LoginControl" is set to "None", theApplication Setup Wizard deletes the default File/Log out menu option from the app-specific menu (if any) that the wizardcreates.

    XXWB.VCXfrmWizAppSetupFinishAction_CreateMenu() -- modified

    No retrofitting required

    ENHANCEMENT: Application Setup Wizard easier to subclassThe single FinishAction() method of the Visual MaxFrame Professional Application Setup Wizard has been split out into aseries of FinishAction_() methods, making it easier to subclass those individual actions.

    XXWB.VCXfrmWizAppSetup

    FinishAction() modified to simply call a series of specific FinishAction_() methods

    No retrofitting required

    ENHANCEMENT: application setup wizard adds MSGSVC.DBF to the projectThe Visual MaxFrame Professional Setup Wizard now adds the app-specific copy of MSGSVC.DBF (copied from \MSGS tothe app-specific data directory) to the .PJX project.

    XXWB.VCXfrmWizAppSetupFinishAction() -- modified

    No retrofitting required

    ENHANCEMENT: Shortcut menu available for CONFIG.FPW editbox on Page4 of ApplicationSetup Wizard

    The editbox on Page4 of the Application Setup Wizard allows editing the development CONFIG.FPW, and now has ashortcut menu to allow easier editing of its contents.

    No retrofitting required

    ENHANCEMENT: New Page7

    The Application Setup Wizard has a new/additional Page7 (raising the total to 10 pages overall) on which you can selectfrom the optional table/view elements in the main VMP-required database. To create the selected tables/views, the wizardsimply calls XXFWDATA.PRG, passing the indicated parameters.

    No retrofitting required

    ENHANCEMENT: New subclassing option supports "intermediate" classesThe Application Setup Wizard has a new option on the subclassing page to support creating app-specific subclasses from an"intermediate" set of subclasses rather than directly from VMP framework classes. You can also create the intermediateclasses from the wizard, if they don't exist already.

    No retrofitting required

    USER SECURITY and RELATED FEATURESThe details of this new feature are explained in the Reference Guide chapterUser Security and Related Features. Pleaseconsult that reference for the new features they are not listed here. What we've included here are those items that possiblyrequire retrofitting of existing VMP 3.01 apps.

    ENHANCEMENT: Users table modificationsThe default VMP Users table has had to be modified, both for user security enhancements and for other new features.

    Retrofitting Instructions

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 24

  • 7/15/2019 VM4UPGRD

    25/72

    The Users.Usr_Rights field has been changed from C(1) to N(1), and the acceptable values have changed accordingly:

    VMP 3.0/3.01 acceptable values VMP 4.0 acceptable values

    (none) 1 = Administrator

    "S"upervisor 2 = Supervisor

    "G"lobal user (read-write access) 5 = User

    "R"eadonly 8 = Guest

    (none) 9 = No access

    Retrofitting requires that you find any explicit uses of Usr_Rights that specify/expect the former "S"/"G"/"R" values andupdate the accordingly. DO XXDTSRCH WITH "Usr_Rights", DO XXDTSRCH WITH "Supervisor", etc.

    Note that XXFWDATA.PRG establishes a default value of 5 for the Usr_Rights field.

    The following new fields have been added to the Users table (see XXFWDATA.PRG for the complete structure, rules, etc.)Existing apps to be migrated and existing VMP 4.0 apps need to have these new fields added to the Users table.

    FieldName DataType Size DefaultValue Description

    Usr_System C 1 "N" This field allows specifying user records as "hidden" bysetting to "Y". System/hidden users are not included inany VMP framework interfaces, views, etc.

    Usr_Active C 1 "Y" This field specifies the user as either active or inactive.Since referential integrity rarely allows physically deletinga user, use this flag to set a user "inactive" and thereforeunavailable for picklist selections, etc.

    Usr_PhoneExt* C 4 Phone extension. Optional field, if omitted, VMPframework interfaces ignore without crashing.

    Usr_EnablePrefs* C 1 "Y" Indicates whether the user wants to run with User Preferences enabled. Optional field, if omitted user

    preferences are never enabled.Usr_LastLogin T 8 .NULL. Indicates the datetime of the last login for this user.

    Optional field, ignored if omitted.Usr_INTLLanguage* C 1 "Original" Indicates the language (Steven Black's INTL Toolkit

    feature) in which the user wants the applcation presented.If INTL Toolkit is not installed, this field is ignored and

    may be omitted.* these fields are optional as described above. In addition to these, the following existing Users table fields can be deletedand the VMP framework is "smart" enough to ignore them in the abstracted interfaces:

    Usr_Phone

    Usr_Fax

    Usr_Notes

    XXFWDATA.PRG no longer creates a V_Users view, and the VMP 4.0 framework does not use a V_Users view anywhere.You can remove V_Users from your VMP required database unless you are using it for purposes other than what is abstractedinto the VMP framework (see the next paragraph regarding the replacement V_UsersList view). Also, thefrmUsersMaintenance form in XXFWFRM.VCX has been removed and replaced by two forms in the new XXFWSEC.VCX.frmDEUsers is a users maintenance form when the optional VMP user security system is notinstalled. frmUserProperties is

    the users maintenance form when the optional VMP user security system is installed. For more information, see Chapter 27User Security of the VMP 4.0 Reference Guide.

    XXFWDATA.PRG creates a new V_UsersList local parameterized view, which is required for VMP 4.0 applications; createit in your existing 3.0/3.01 apps being migrated to VMP 4.0. Note that the VFP View Designer cannot create theV_UsersList view properly. Copy-and-paste the code from XXFWDATA.PRG into your own utility program to generate theV_UsersList view in the database containing your Users table (or remote view). For more information, see Chapter 27: UserSecurity of the VMP 4.0 Reference Guide.

    ENHANCEMENT: Usr_Notes field optional

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 25

  • 7/15/2019 VM4UPGRD

    26/72

    The default USERS.Usr_Notes memo field is now optional. If you want to remove it (and its accompanying .FPT file), VisuaMaxFrame Professional form classes that contain an editbox bound to Usr_Notes contain logic to also remove the editbox.

    XXFWDATA.PRG -- modified

    No retrofitting required

    ENHANCEMENT: new Form.icSecurityID propertyThe new XXFW.VCX/frmBase.icSecurityID property is for use with the optional VMP user security system. Its propertydescription contains instructions for its use, and further information is contained in XXFW.VCX/frmBase.SetReadOnly().

    XXFW.VCXfrmBaseicSecurityID new propertySetReadOnly() -- modified

    No retrofitting required

    However, if you implement the optional VMP user security system, you'll need to set icSecurityID for any .SCX-based formsyou wish to secure. The XXDTSIT developer tool can be used to set the icSecurityID property for all .SCX-based formsautomatically.

    ENHANCEMENT: when someone attempts to login to an inactive User IDPart of the overall user security enhancements to VMP 4.0 include a new Users.Usr_Active field. In this enhancement, ifsomeone attempts to log in to an inactive User ID (Usr_Active # "Y"), they get an appropriate message and applicationstartup is immediately terminated.

    XXFW.VCXfrmLoginHitEscape() removedCancelAction() modifiedOKAction() modifiedActionI() new methodActionN() new methodActionY() new methodCustomPasswordValid() -- modifiedtxtPassword.Valid() -- modified

    Retrofitting Instructions

    If you have custom code in any of the above existing methods, they are likely to need modification. Note that HitEscape() hasbeen removed, and its code moved to CancelAction().

    If you prefer to treat such an attempted login to an inactive user account the same as any other failed login, override the newActionI() method with the following line:

    return THIS.ActionN()

    ENHANCEMENT: specify minimum password lengthA new APPINFO "MinimumPasswordLength" record allows you/your client to specify the minimum length for user

    passwords (Users.Usr_Password). This minimum length defaults to 6 and is enforced in the txtUsr_Password control inXXFWSEC.VCX/ctrUsersBoundControls.

    XXFWDATA.PRGAdds the new APPINFO record

    No retrofitting required

    FEATURE: User can "log out"oApp.Logout() is a new method that can be called (typically from a "Log out" option on the File menu) to log the user out ofthe application. The app doesn't terminate, but rather releases and re-instantiates oUser, leaving app control in the user loginform.

    When the APPCONFIG record for "LoginControl" is set to "Normal" and the APPCONFIG record for "TimeoutType" is setto "M"enu, then application timeout executes an oApp.Logout() and application control is in the user login form.

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 26

  • 7/15/2019 VM4UPGRD

    27/72

    When the APPCONFIG record for "LoginControl" is set to "None" (no user login is apparent to the user), callingoApp.Logout() does nothing.

    The VM example application includes a Logout option on the File menu.

    XXFW.VCXctrAppLogout() new methodOnTimer() modifiedcusUser

    UserLogin() -- modified

    XXFWMAIN.MNX modified to add a default "Log out" option to the File menu

    No retrofitting required

    ENHANCEMENT: main menu Admin menu padThe XXFWMAIN.MNX template menu has been enhanced to add an Admin pad, containing actions intended to be

    performed by the system administrator.

    GENMENUX directives and SKIP FOR conditions are included to remove/disable options that should not be available ifoptional features are not installed, and coordination of these in the Application Setup Wizard has been implemented.

    XXFWMAIN.MNX -- modified

    No retrofitting required

    MODIFICATION: change in parameters passed to oMenu.AddWindowMenuItem()XXFW.VCX/cusMenu.AddWindowMenuItem() has been modified to receive only one parameter that is an object reference toa form.

    XXFW.VCXcusMenu

    AddWindowMenuItem() modifiedEnsureWindowMenuItemExists() modifiedLocalize() modifiedcusFormsDoForm() -- modified

    Retrofitting InstructionsYou aren't likely to have any explicit calls to oMenu.AddWindowMenuItem(), but you can DO XXDTSRCH WITH".AddWindowMenuItem" just in case, and change any such calls to send only the one form object reference parameter.

    FORMS and CONTROLS

    ENHANCEMENT: default Shortcut menu specified for textboxesXXFW.VCX/txtBase.RightClick() has been modified to specify a default shortcut menu presented to the user on RightClick()The shortcut menu provides basic Edit menu actions.

    Note that, as with editboxes, the default shortcut menu is only presented if you have Visual MaxFrame Professional, whichcontains the shortcut menu class.

    XXFW.VCXtxtBaseRightClick() modifiedicShortcutMenuClass new property

    XXFWMISC.VCXcusShortcutMenu

    Init() modifiedInstallEditMenuItems() modified

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 27

  • 7/15/2019 VM4UPGRD

    28/72

    No retrofitting required

    ENHANCEMENT: new cmdBase properties/Refresh() logic for ReadOnly formsTwo new properties added to cmdBase make it easier to set the runtime "state" (Visible/Enabled) of commandbuttons whenTHISFORM.ilReadOnly=.T. or THISFORM.ilReadOnlyDueToSecurity=.T.

    XXFW.VCXcmdBaseicStateThisformReadonlyDueToSecurity new property

    icStateThisformReadonly new propertyRefresh() modified

    Retrofitting InstructionsNo retrofitting required unless you have forms whose ilReadOnly can be set to .T. (see frmBase.SetReadOnly) and you don'tlike the defaults for these properties.

    ENHANCEMENT: additional uses for THISFORM.ioFirstControlThe XXFW.VCX/frmBase.GetFirstControl() method is not called anywhere in the framework (which is a good thing, since ithad a bug and doesn't work), and therefore the custom frmBase.ioFirstControl property isn't used explicitly by VMP,freeing it up for your custom usage. This enhancement fixes the bug in GetFirstControl(), and adds header comments to itthat method to explain how you can put THISFORM.ioFirstControl to work in a different manner for your custom usage.

    XXFW.VCXfrmBase

    Load() modifiedGetFirstControl() modified to fix the bug, work faster, document how to put .ioFirstControl to work for custom use.ioFirstControl changed from protected scope to public scope.ioFirstDrillDownControl changed from protected scope to public scope

    No retrofitting required

    ENHANCEMENT: prevent editboxes from Refresh()ing on The default behavior of editboxes is to display text starting from the top on Refresh(). When there is more text than will fit inthe visible portion of the editbox, this results in a Form.SaveAction() behavior where the just-entered text is shifted out ofview as the editbox.Refresh() forces the visible text back to the top. This enhancement suppresses that default behavior onForm.AddAction().

    Note that the custom AddAction() method is added in frmDataEntry of Visual MaxFrame Professional, so this modificationhas no intrinsic effect on Visual MaxFrame applications unless you happen to have a custom AddAction() method

    XXFW.VCXedtBaseRefresh() modified

    No retrofitting required

    ENHANCEMENT: opening (local) views NODATA in the .SCX-based form DataEnvironment ismuch faster

    VFP is faster at opening (local) views NODATA when SET DELETED is OFF. Another VMP 4.0 enhancement toXXFW.VCX/cusDBCSvc.OpenTable() abstracts this behavior when views are opened via calls tooLib.oDBCSvc.OpenTable(), but handling views opened implicitly in the native DataEnvironment of .SCX-based forms is alittle tricky.

    This enhancement handles SETting DELETED OFF before the native DataEnvironment object of .SCX-based forms openscursors and then SETs DELETED back to its VMP default ON afterwards. The necessary protections are in place to onlyexecute this behavior when the DataEnvironment contains at least one view and all views have their NoDataOnLoad propertyset to .T. if views are to be opened WITH data, SET DELETED must be left ON to prevent DELETED() records from beingretrieved into the view. Also, once the DataEnvironment has opened cursors, any tables that have their record pointer

    positioned to a DELETED() record (because they were opened with SET DELETED OFF) have their pointer repositioned tothe first non-DELETED() record.

    XXFW.VCXfrmData

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 28

  • 7/15/2019 VM4UPGRD

    29/72

    SetDeletedOnOffAtLoad() new public methodDEBeforeOpenTables() modified to call THIS.StandaloneSetup() and SetDeletedOnOffAtLoad()PrivateDataSessionSets() modifiedLoad() modified to call SetDeletedOnOffAtLoad()cusPrivateDataSessionSets()

    Init() modified to remove the RETURN .F.

    XXDTNEWF.PRG modified to add comments to the auto-generated DE.BeforeOpenTables() line of code

    Retrofitting Instructions

    If you have subclassed XXFW.VCX/cusPrivateDataSessionSets(), you'll have to be sure to RETURN .T. from the Init().

    Any forms/classes that have explicit Load() code (usually to add augmenting code) should be checked to make sure they makethe callback before taking any action with respect to the open cursors. DO XXDTEPEM WITH "Load" to find all forms/formclasses with explicit Load code, and make sure the callback is before any cursor-specific code (the VM example app had noforms/classes with Load code that needed modification, but it's good to make sure).

    ENHANCEMENT: oForms.HowManyInstantiated() can also return the total numberXXFW.VCX/cusForms.HowManyInstantiated() has been enhanced to accept the first parameter as "ALL", in which case thetotalnumber of forms instantiated via oForms.DoForm() and therefore currently tracked in oForms.iaFormInstances isRETURNed.

    XXFW.VCXcusForms

    HowManyInstantiated() modified

    No retrofitting required

    ENHANCEMENT: forms initially displayed offset to the previous form if they completelyobscure it

    When forms are instantiated, if they completely obscure the form that was up when they were called, the new form cascadedjust below and to the right of the previously-active form. This behavior is intended as a visual aid to the average user, tomake it clear that a new form is active, but the previous one is still there.

    XXFW.VCXfrmBaseSetInitialVisibleLocation() -- modified

    No retrofitting required

    MODIFICATION: base combo class contains Valid and adds a CustomValid() methodCombobox validation is a little different than that of other standard data-entry controls, consisting mostly of just simple "add-on" behavior in most situations. This modification of XXFW.VCX/cboBase adds Valid code similar to that in other VMP"base" classes to handle high-level exceptions, and adds a CustomValid() method for your subclass/instance-specific "add-on"code.

    Please note the VFP does not appear to act on RETURNing .F. from the Valid() of a combo with respect to keeping focus inthat combo (you can play with issuing NODEFAULT in the LostFocus() as a possible solution if you need that behavior).Also, beware that the When() event fires each time you move around in the combo, making it tricky to use an "ilValidFlag"like we do in other VMP "base" classes, where we reset it each time the When() fires.

    XXFW.VCX

    cboBaseValid() modifiedCustomValid() new method

    Retrofitting InstructionsNo retrofitting is required for combos that are working fine. You will want to put validation code in the new CustomValid()method for all future development.

    ENHANCEMENT: Form.CheckRequiredFields() much faster

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 29

  • 7/15/2019 VM4UPGRD

    30/72

    XXFW.VCX/frmBase.CheckRequiredFields() contains code to recurse through all form members, looking for any whosecustom Visual MaxFrame ilRequired property is set to .T. but whose .Value is empty()/null. As such, it was noticeably slow,especially on forms with lots of controls

    In this enhancement, frmBase.CheckRequiredFields() is virtually instantaneous, because controls whose ilRequired=.T. arenow "registered" with the form, which can just loop through those controls on , rather than all members.

    In the public domain Visual MaxFrame files, frmBase.CheckRequiredFields() isn't actually called anywhere, but if you'vecalled it manually anywhere, it's lots faster. In Visual MaxFrame Professional, CheckRequiredFields() is called by default

    early in the XXFWFRM.VCX/frmDataEntry.SaveAction() process.XXFW.VCX

    frmBase

    iaReqControls new public array propertyRegisterReqControls() new public methodCheckRequiredFields() modifiedInit() modifiedDestroy() modifiedcboBaseInit() modifiedilRequired_Assign() new methodchkBaseInit() modifiedilRequired_Assign() new methodedtBase

    Init() modifiedilRequired_Assign() new methodopgBaseInit() modifiedilRequired_Assign() new methodspnBase

    Init() modifiedilRequired_Assign() new methodtxtBaseInit() modifiedilRequired_Assign() new method

    Retrofitting InstructionsNo retrofitting is required unless you set ilRequired in method code (setting it in the Properties Sheet is fine, no retrofittingrequired). If so, and in VFP 5.0 only (in VFP 6.0, the ilRequired_Assign() fires automatically on setting ilRequired inmethod code), replace calls like

    THIS.ilRequired = .t.

    withTHIS.ilRequired_Assign(.t.)

    If you have any explicit calls to the Form.CheckRequiredFields() method (there are no such calls in the Visual MaxFrameProfessional framework) that pass what was an optional parameter, note that it no longer accepts a parameter. The old codehas been left in the CheckRequiredFields() method, so if you really need that behavior, or care to modify it to your needs, youcan copy it to a new method and call that method passing the parameter.

    ENHANCEMENT: Control.inRequiredBackColor property migrated to the app/user level ratherthan the control level

    Controls whose custom Visual MaxFrame ilRequired property is set to .T. also display in the inRequiredBackColor, whichdefaults to cyan. This behavior has been moved from the individual control level to the User Preferences/APPINFO level,since it really isn't a per-control setting.

    This enhancement not only implements this change, but also introduces a mechanism to allow "broadcasting" app/user levelchanges to global objects in the current application session.

    XXFW.VCXcboBase

    inRequiredBackColor removedchkBase

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 30

  • 7/15/2019 VM4UPGRD

    31/72

    inRequiredBackColor removededtBaseinRequiredBackColor removedopgBaseinRequiredBackColor removedspnBaseinRequiredBackColor removedtxtBaseinRequiredBackColor removed

    cusFormsinRequiredControlBackColor new public propertySetinRequiredControlBackColor new public methodInit() modifiedOnToolsOptionsChange() modified

    XXFWDATA.PRG/APPINFO tableA new APPINFO record "RequiredControlBackColor" sets the default value at the application level. However, if you providean interface, each user can specify their preference, stored in the User Preferences table. If you have Visual MaxFrameProfessional, see

    VMSSETUP.SCX

    VMTOPTS.SCX

    in the VM example application.

    No retrofitting required

    However, if you have already been mucking with inRequiredBackColor, you may have to modify what you've been doing. It'seasier now that there is a single point of maintenance for the BackColor of all ilRequired controls.

    FEATURE: Form.ShowTips controlled by an oForms property/User PreferencesTo allow each user to toggle the Form.ShowTips property globally for all forms in the app, theXXFW.VCX/frmBase.ShowTips property has been Reset to Default (.F.) and is instead set dynamically infrmBase.RestoreUserPrefs() where it is set to the value stored in oForms.ilShowTips (which, in turn, has been set by theoForms.SetilShowTips() custom method).

    Since XXFW.VCX/cusForms.ilShowTips has been set to .T., there is no net change to existing VMP apps as forms areinstantiated, their ShowTips property is set to .T. However, this new feature allows you to provide a Tools/Optionsinterface where the user can toggle Tool Tips on/off for the entire app. If you have Visual MaxFrame Professional, theVMTOPTS.SCX form demonstrates one way to do this.

    XXFW.VCXfrmBaseShowTips Reset to Default (.F.)RestoreUserPrefs() modifiedOnToolsOptionsChange() modified

    XXFW.VCXcusForms

    ilShowTips new public property, defaults to .T.SetilShowTips() new public methodOnToolsOptionsChange() modified

    No retrofitting required

    ENHANCEMENT: MovePointer() a specified number of recordsXXFW.VCX/frmData.MovePointer() has been enhanced to accept an additional parameter specifying the number of recordsto SKIP.

    XXFW.VCXfrmDataMovePointer() modified

    XXFWFRM.VCXfrmDataEntryMovePointer() modified

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 31

  • 7/15/2019 VM4UPGRD

    32/72

    XXFWCTRL.VCXcmdDataMovePointerClick() modifiedinHowMany new property

    No retrofitting required

    ENHANCEMENT: X3WRPFRM() and oForms.DoForm() can receive/send an object parameterIn addition to the previous behavior of sending a string of non-object parameters to X3WRPFRM()/oForms.DoForm() for

    passing on to the called modal form, this enhancement allows you to optionally send a single object reference toX3WRPFRM()/oForms.DoForm() for passing on to the called form. See the parameter listing in the header comments ofX3WRPFRM.PRG and XXFW.VCX/cusForms.DoForm().

    X3WRPFRM.PRG modified

    XXFW.VCXcusFormsDoForm() modified

    No retrofitting required

    FEATURE: new oForms.GetSYS1271() methodXXFW.VCX/cusForms.GetSYS1271() is a new oForms method that returns the .SCX/.VCX/.PRG filename where the passedform/form member is located, and optionally presents that information in an X3MSGSVC() dialog.

    If you have Visual MaxFrame Professional, the Admin menu of the VM example Application contains a "CurrentScreen.ActiveForm" menu option that executes oForms.GetSYS1271(Screen.ActiveForm,.t.), useful for developers if theywant to know what form is currently running, or for the system administrator to be more helpful over the phone.

    XXFW.VCXcusFormsGetSYS1271() new method

    No retrofitting required

    ENHANCEMENT: standalone form setup/cleanup split out into separate objectMost standalone form setup/cleanup tasks have been split out into a separate XXFW.VCX/cusStandaloneForms class, andinstance of which is created in XXFW.VCX/frmBase.StandaloneSetup().

    XXFW.VCXfrmBaseInit() modifiedStandaloneSetup() modifiediaScreenTimers removediaStandaloneStuff removedcusStandaloneForms new class

    Retrofitting instructions

    Generally, no retrofitting is required, but if you've customized any of the Standalone() methods or CustomStandalone()methods, you are likely to have to modify your code, especially if you've set any THISFORM.iaStandaloneStuff[] values, sincethat array has been moved to goStandaloneForms.iaStuff.

    ENHANCEMENT: OnFormDestroy() method added to container classesData-entry grids, data-entry form pageframes, and the new "registered" container classes have a new OnFormDestroy()method, called "automatically" from THISFORM.Destroy(), which allows for easy object reference "garbage collection" (oranything else you want to do at that point) for those containers. Abstracted code sets THIS.iaVelcro to .NULL.; augment asdesired.

    XXFWCOMP.VCXctrDERegisteredCompositeOnFormDestroy() new method

    XXFWGRD.VCXgrdDataEntry

    Visual MaxFrame Revision History, version 4.0 VM4UPGRD.DOC

    1998-1999 Metamor Industry Solutions Page 32

  • 7/15/2019 VM4UPGRD

    33/72

    OnFormDestroy() new method

    XXFWFRM.VCXpgfDEFormsOnFormDestroy() new methodfrmDataEntryDestroy() -- modified

    No retrofitting required

    MODIFICATION: txtBase.Century property defaults to 1-OnIn previous versions of Visual MaxFrame Professional, the Century property of textboxes is left at the VFP 5.0 default 2,which meant it was determined by whether SET CENTURY is ON or OFF. XXFW.VCX/txtBase.Century now defaults to 1-On, which is the default for VFP 6.0.

    XXFW.VCXtxtBaseCentury -- modified

    Retrofitting InstructionsYou should have no retrofitting, because the default SET CENTURY setting for Visual MaxFrame applications is ON, whichmeans that textboxes with the Century property left at their default setting always displayed all 4 digits of the year. Thismodification means that all 4 digits of the year are now displayed in txtBase textboxes regardless of the current SETCENTURY ON/OFF setting.

    MODIFICATION: Form.BackColor reset to defaultInstead of setting the frmBase.BackColor to gray explicitly, it has been Reset To Default, since gray is the default in VFP 5.0on.

    XXFW.VCXfrmBaseBackColor reset to default

    No retrofitting required

    FEATURE: oUser created for standalone formsWhen running forms standalone at the Command Window, oUser is now created. The user is logged in according to thelogin control records in APPCONFIG.DBF. If you want to run User Preferences for standalone forms, j