Sie sind auf Seite 1von 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 Visual MaxFrame Professional application running under VMP v3.01 to the current v4.0. Read it carefully, paying particular attention to the indicated Retrofitting Instructions. The following is a list of features, enhancements, and modifications to the Visual MaxFrame Professional framework that constitute 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 so that 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 MaxFrame superset, and the Visual MaxFrame Professional comprehensive product.

If v4.0 is your first purchase of VMP


You 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 to VMP 4.0
If you have an existing set of "intermediate" classes based on the VMP 3.01 framework from which you have 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 not compatible with your VMP 4.0 classes, so you should install VMP 4.0 in a new directory/folder structure and keep your existing VMP 3.01 code base separate. Copy your existing "intermediate" classes to your new VMP 4.0 directory/folder structure, and follow the retrofitting instructions in this document as they apply to your "intermediate" classes. See the If you are 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 new features of VMP 4.0.

If you are upgrading an existing app from VMP 3.01 to VMP 4.0
You must follow the retrofitting instructions listed in this document. Each modification, enhancement, and new feature is listed 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 to the retrofitting instructions and the implications for your existing applications.

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 to modify/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 existing applications, too!). Make a backup of your entire existing application(s) before retrofitting. The backup should be available, running in v3.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.0 installation. 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 the entire migration process, you should keep the VMP 3.01 version of your app in working order as a reference point. Once you are completely satisfied that your app(s) have been successfully migrated to VMP 4.0, you may delete your VMP 3.01 framework 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 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 2

ENHANCEMENTS REQUIRING SIGNIFICANT


RETROFITTING
This section lists the major VMP 3.01 VMP 4.0 enhancements that require retrofitting when upgrading an existing VMP 3.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 you have 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 XX


The naming convention we've been using for years, wherein the first character is an "X" and the 2 nd character is an integer indicating 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 in the context of the Visual MaxFrame/Visual MaxFrame Professional framework have been renamed to corresponding XX*.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.PRG XXFWMAIN.PRG XXERROR.PRG * XXAPPINF.PRG * XXFWMAIN.MNX * XXFWBLNK.ICO * * indicates those files that are likely to be referenced in app-specific code Visual MaxFrame Professional XXFWCTRL.VCX * XXFWFRM.VCX * XXFWGRD.VCX * XXFWMISC.VCX * XXFWPICK.VCX * XXTOOLS.VCX XXWB.VCX XXBUILDR.PRG XXDT.PRG XXDTDBFL.PRG XXDTEPEM.PRG XXDTHACK.PRG XXDTMEST.PRG XXDTNEWF.PRG XXDTPOPC.PRG XXDTSRCH.PRG XXDTSUBC.PRG XXWB.PRG (2 changes -- formerly X3WZ.PRG) XXWBAPPS.PRG (2 changes -- formerly X3WZAPPS.PRG) XXWBCFPW.BMP XXWBDIR.BMP
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 3

XXWBFNSH.BMP XXWBMFSM.BMP XXWBMP.BMP XXWBSHCT.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.01 application(s). The required retrofitting is included in the Retrofitting Instructions in the next MODIFICATION: Major PEM reorganization section, items 3 and 5.

MODIFICATION: Major PEM reorganization


This modification migrates the PEMs previously contained in the following X3FWCTRL.VCX commandbutton classes cmdDataAdd cmdDataDelete cmdDataFind cmdDataPrint cmdDataOK cmdDataSave cmdDataCancel 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; I was able to retrofit the entire VM example application in less than one hour. The only time there is actual retrofitting to do is when 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 installation intact, and copy your application to a new directory/folder structure where it can run under VMP 4.0 in parallel with your original 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 current location/value of existing PEMs, and to copy/paste when advantageous. Be sure to fully complete the retrofitting instructions for 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 to frmDataEntry, they have been grouped together according to type all the Save-specific methods start with "Save", all the Delete-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 Chapter 16: 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 example form) On the down side, forms inheriting from frmDataEntry have more PEMs to wade through on the Properties Sheet. But at least the ones dealt with here are grouped together according to their "action" XXFWCTRL.VCX
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 4

cmdData Init() modified to set a default ToolTipText based on the new icType property, default ilCallSecurityFromRefresh Refresh() added default code icType new public property, default to SPACE(0) ilCallSecurityFromRefresh new public property, default to .NULL. SetUserSecurity() added default code zReadMe() updated cmdDataMovePointer Refresh() modified to conditionally call THISFORM.ActionButtonRefreshLogic() icType reset to default SetUserSecurity() overridden AfterClick() removed Click() modified to defer the actual form.Refresh() to the Form.MovePointer() method cmdDataCallMemoEditForm icType set to "M" in the Properties Sheet cmdDataAction NEW CLASS Click() call the THISFORM.Action() method corresponding to THIS.icType cmdDataAdd -- REMOVED cmdDataCancel -- REMOVED cmdDataDelete -- REMOVED cmdDataFind -- REMOVED cmdDataPrint -- REMOVED cmdDataOK -- REMOVED cmdDataSave -- REMOVED XXFWFRM.VCX frmDataEntrySCADO -- REMOVED frmDEOne2Many -- REMOVED frmDataEntry Activate() modified logic to go into "AddOnTheFly" mode even if there's no <Add> button ActionButtonRefreshLogic() new public method with code migrated from the individual cmdData.. buttons AddAction() 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 <Add> to a halt AddAfterAppendBlank() 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() and the old cmdDataDelete.MessageText() DeleteAdditionalAction() new public method corresponding to the old frmDataEntry.ShellAdditionalDeleteAction() DeleteBeforeAnything() new public empty/shell method DeleteAfterSuccess() new public empty/shell method DeleteAfterFailure() new public empty/shell method EditAction() the old BoundControlsInteractiveChange() method, simply renamed FindAction() 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.icFreeTableTag SaveAction() 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 old cmdDataSave.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 modified PopMainAliasRecno() the old RestoreMainAliasRecno() method renamed
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 5

inSaveMainAliasRecno removed, as per the warning in the VMP 3.0 property description. The equivalent value can be queried via THISFORM.ioSaveMainAliasRecno.GetPProp("inSaveRecno") iaSaveFailureInfo actually added to frmData but used throughout frmDataEntry, to hold information regarding a failed SaveAction() 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 resolution operator callbacks updated accordingly. Added six instances of XXFWCTRL.VCX/cmdDataAction, now that this form class inherits the action buttons from frmDataEntrySCADO: 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 inherited from frmDataEntrySCADO. frmEventLog Hack 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() -- modified frmDEGridNav2Pages DeleteAction() 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() removed AfterFormControlMethod() removed ControlSelection() modified tbrSCADONav Click() modified to add/insert the new 1 st parameter passed to THISFORM.ControlSelection() OnTimer() modified to call _Screen.ActiveForm.ActionButtonRefreshLogic() when indicated cmdFind.Click() modified LinkedMenu() modified to update the SKIP FOR logic, also required updating the STRINGS.DBF records for \<Print and Pre\<vious to P\<rint and \<Previous, to match the icType property settings

Retrofitting Instructions
Throughout this listing, the "ZZ" designation indicates your app-specific (and/or intermediate) subclasses of the VMP framework. Once you have completed these items, you will also have retrofit the file name changes in the previous MODIFICATION: X3 prefix replaced with XX section. If you only have Visual MaxFrame (not Visual MaxFrame Professional), only items 1 thru 5 apply. 1. Copy your existing VMP 3.x application to a new directory/folder structure. Not only should you have a backup of your application, but you'll perform all migration tasks on the copy. Once the migration/retrofitting tasks are complete, the copy will be the VMP 4.0 version of your application. If you haven't done so already, install VMP 4.0. Be sure to not overwrite your existing VMP 3.0/3.01 installation, but rather install VMP 4.0 to a new directory structure. At least until you finish the migration of your app to VMP 4.0, you'll need to be able to run your existing VMP 3.x application in its entirety. Modify your CONFIG.xxD configuration file as necessary to reflect the new development setup, including: If you have a line to set your _BUILDER to X3BUILDR.PRG, be sure to update that to XXBUILDR.PRG. Be sure to update your PATH line to point to your new VMP4\XLIB files. Do not include your old VMP3\XLIB directory in the PATH. For best results, rename the folder where your VMP 3.0 framework files are located, so that VFP won't be able to find those files at all (rename the folder back to its original name any time you are working with your working backup copy of your existing VMP 3.x application). In order for the new CONFIG.xxD settings to take effect, quit VFP and start a new session. In VFP 6.0, you can just issue the new SYS(3056) function at the Command Window, rather than quitting and starting a new session.

2.

3.

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 6

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 delete the existing stored procedures. DO XXFWDATA WITH "ZZ","MIN",.T. to replace the APPCONFIG (ZZCONFIG.DBF) and APPINFO tables, replace the USERS table, and replace the V_USERS view with the V_USERSLIST view. For those APPINFO/APPCONFIG records where your application uses non-default values, update those tables in the new ZZ.DBC database. If your existing 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 will be 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 the application (and you have Visual MaxFrame Professional ) DO XXFWDATA WITH "ZZ","RI",.T. to add necessary VMP-specific Referential Integrity meta data, whether you intend 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 the VMP framework (typically the ZZFW*.VCX class libraries at the app-specific level), the ClassLibrary property (indicates where the ParentClass is located) has to be updated. You can accomplish this in the Class Browser or by attempting to open the class in the Class Designer, and locating the parent class library in the Locate dialog; or you can hack each appspecific .VCX and update the ClassLoc field, which displays in the Class Designer as the ClassLibrary property:
use <??FW*.VCX> brow for "X3" $ upper(ClassLoc) ** change all X3FW*.VCX references in the ClassLoc field to XXFW*.VCX ** also change the relative pathing to reflect the location of the VMP 4.0 version use

If you have created intermediate subclasses, they will need to be copied to a new folder location and thus redefined to "point" to the new XXFW.VCX class libraries. Your app-specific classes will then have to be thus redefined to "point" to the new ??FW.VCX class libraries. 6. IMPORTANT! Until further notice (further down this retrofitting instruction list), do not open any of your app-specific forms or form classes in the Form/Class Designers! By not using the designers (no need to anyway), you will preserve method code and property settings for native VFP PEMs (like Click and Refresh) and will have less work to do later on. You should not have a frmZZDEOne2Many subclass of X3FWFRM.VCX/frmDEOne2Many (see the warnings in the zReadMe), but if you do, use the Class Browser to remove it since XXFWFRM.VCX no longer contains a frmDEOne2Many. If you not only have a frmZZDEOne2Many, but have created forms based on it, you'll need to keep frmDEOne2Many, but you will have some work on your hands to keep things intact. You'll have to create a separate .VCX just for the old frmDataEntrySCADO and frmDEOne2Many form classes (both now removed from the VMP framework) and redefine any existing forms to inherit from there. If you have a frmZZDataEntrySCADO form class, use the Class Browser (or hack ZZFWFRM.VCX) to redefine it to inherit from XXFWFRM.VCX/frmDataEntry. Create a cmdZZDataAction subclass of XXFWCTRL.VCX/cmdDataAction.

7.

8. 9.

10. If you have any cmdZZDataAdd, cmdZZDataCancel, cmdZZDataDelete, etc. commandbuttons in your ZZFWCTRL.VCX, use the Class Browser (or hack ZZFWCTRL.VCX) to redefine them all to inherit from your new cmdZZDataAction class. Set the icType property, Caption in each button as shown below in step #10.

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 7

11. If you have a frmZZDataEntrySCADO form class but do not have one or more of the following button classes in your ZZFWCTRL.VCX, create them now, with the following property settings: ClassName cmdZZDataFind cmdZZDataSave cmdZZDataCancel cmdZZDataPrint cmdZZDataDelete cmdZZDataAdd cmdZZDataOK Caption \<Find \<Save Cancel P\<rint \<Delete \<Add \<OK icType F S C R D A O Cancel .T.

.T.

12. Remove any existing cmdZZData class unless you've used it to provide inheritance to buttons other than your nowredefined cmdZZDataAdd/Cancel/Delete/etc. buttons. 13. If you have a frmZZDataEntrySCADO form class, open it in the Class Designer and add an instance of the new cmdZZDataAdd/Cancel/Delete/Find/Print/OK/Save buttons to your frmZZDataEntrySCADO class to replace the ones that used to be inherited from frmDataEntrySCADO. Add them in the order shown in the listing in step #10. Set the Name property for each button to cmdAdd, cmdCancel, cmdDelete, etc., to match what they were before. Modify any explicit :: scope-resolution operator callbacks in your frmZZDataEntrySCADO to callback to frmDataEntry, not the nowremoved-frmDataEntrySCADO. 14. It is now safe to use the Form/Class Designers (see step #5), now that your frmZZDataEntrySCADO form class has its buttons back. 15. DO XXDTSRCH on ".SaveMainAliasRecno(" and replace any such calls with .PushMainAliasRecno(. DO XXDTSRCH on ".RestoreMainAliasRecno(" and replace any such calls with .PopMainAliasRecno(. DO XXDTSRCH with ".inSaveMainAliasRecno" and replace any such calls with .ioSaveMainAliasRecno.GetPProp("inSaveRecno") . 16. DO XXDTSRCH with ".PrintReport(" and replace any such calls with .PrintAction(. 17. DO XXDTEPEM with "BeforeFormControlMethod" and "AfterFormControlMethod". If you find any such method code, you'll have to find a way to do without them they have been removed from XXFWFRM.VCX/tbrGen. 18. Update your app-specific STRINGS.DBF and MSGSVC.DBF with the changes made in this modification. The records that have been changed are marked with "***" in their cWhere field, just SET FILTER TO cWhere = "***" to look at them and compare them to your existing app-specific versions. Note that if you haven't added any new records to your app-specific STRINGS/MSGSVC tables, all you have to do is copy the new framework versions over your existing app-specific tables. DO XXDTMEST to update your app-specific MSGSVC.DBF and STRINGS.DBF tables with the records that are new to VMP 4.0. 19. DO XXDTEPEM with "AfterClick" to find any instances of cmdDataMovePointer buttons in which you've got some explicit code in the AfterClick method. If so, you'll have to move that code to the Click, after a manual callback, since the AfterClick() method has been removed. 20. In your backup/v3.01 copy of your app, DO X3DTEPEM with "BoundControlsInteractiveChange" to find any instances of frmDataEntry, ctrMover, frmMover that have specific BoundControlsInteractiveChange code. Transfer that code to the corresponding EditAction method of your VMP 4.0 app. Be sure to rename any manual "::BoundControlsInsteractiveChange()" callbacks to "::EditAction()". In the new VMP 4.0 version of you app, DO XXDTSRCH WITH ".BoundControlsInteractiveChange" and replace all explict calls to this renamed method to ".EditAction". 21. Modify your ZZMAIN.PRG main calling program to call XXFWMAIN.VCX instead of X3FWMAIN.VCX. Also make sure the call to XXFWMAIN.PRG sends only one parameter a string specifying the name of your ZZCONFIG.DBF file.

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 8

22. Delete your ZZ.PJX project file. Create a new one and add ZZMAIN.PRG as the main calling program. Rebuild the project, and ignore all the complaints about not being able to find files (you can just select <Ignore All> the first time you get the dialog). Review the log of errors the Project Manager creates, and modify the problem code, which should mainly consist of X3*.*calls that need to be changed to XX*.* references, usually those files that are marked with an asterisk in the listings in the previous MODIFICATION: X3 prefix changed to XX section. You may have to Rebuild the ZZ.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 for references 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 <FileName> for each of the files marked with an asterisk in the listings in the previous MODIFICATION: X3 prefix changed to XX section. 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 extension for the .VCX file name is optional). Once you find each X3 version of these files, change the "X3" to "XX". You can modify each occurrence right in the XXDTSRCH dialog by selecting each item in the Search Results form of XXDTSRCH and selecting the <Modify> 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 the Ap_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 VMP 3.0/3.01. DO VM34UTL1.PRG from the Command Window, in the normal development environment for the app (as if you 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 new location 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. An alternative to the ZZ.VM4 output is to DO X3DTEPEM (on your backup application) for each PEM listed here to track down 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 those two 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 the code is transferred to the form level, DODEFAULT() and manual callbacks refer to a different class inheritance hierarchy, 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 explicit code/settings for this VMP 3.01 Method/Property (DO X3DTEPEM on this item or refer to ZZ.VM4 output) ShellBeforeAppendBlank ShellAfterAppendBlank Click (don't bother DOing X3DTEPEM on this one) Refresh (don't bother DOing X3DTEPEM on this one) in an instance inheriting from this VMP 3.01 Class X3FWCTRL.VCX cmdDataAdd X3FWCTRL.VCX cmdDataAdd X3FWCTRL.VCX cmdDataAdd X3FWCTRL.VCX cmdDataAdd then transfer/migrate that PEM code/setting to this VMP 4.0 location

The containing form AddBeforeAppendBlank() note that it can now RETURN .F. to bring the <Add> to a halt The containing form AddAfterAppendBlank() Augment the containing form AddAction or maybe put some/all the code in the containing form AddBeforeAppendBlank/AddAfterAppendBlank Likely goes in the Refresh() of the instance, overriding the framework abstracted behavior. Note that if you've followed the retrofitting instructions above carefully, this code should be preserved on MODIFYing the containing FORM/CLASS at this point

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 9

Click (don't bother DOing X3DTEPEM on this one) Click (don't bother DOing X3DTEPEM on this one) Click (don't bother DOing X3DTEPEM on this one) Refresh (don't bother DOing X3DTEPEM on this one)

X3FWCTRL.VCX cmdDataCancel X3FWCTRL.VCX cmdDataOK X3FWCTRL.VCX cmdDataFind X3FWCTRL.VCX cmdDataFind

Augment the containing form CancelAction()

Augment the containing form OKAction()

Augment the containing form FindAction() Likely goes in the Refresh() of the instance, overriding the framework abstracted behavior. Note that if you've followed the retrofitting instructions above carefully, this code should be preserved on MODIFYing the containing FORM/CLASS at this point Containing form.FindUI(), existing code most likely transfers here unchanged Containing form icFindActionTag

DoTheFind icFreeTableTag

X3FWCTRL.VCX cmdDataFind X3FWCTRL.VCX cmdDataFind X3FWCTRL.VCX cmdDataSave X3FWCTRL.VCX cmdDataSave

Click (don't bother DOing X3DTEPEM on this one) Refresh (don't bother DOing X3DTEPEM on this one)

Augment the containing form SaveAction() Likely goes in the Refresh() of the instance, overriding the framework abstracted behavior. Note that if you've followed the retrofitting instructions above carefully, this code should be preserved on MODIFYing the containing FORM/CLASS at this point Containing form SaveBeforeAnything() Also, if you did any explicit messaging to the user, that should be replaced by populating THISFORM.iaSaveFailureInfo[] see XXFWFRM.VCX/frmDataEntry.SaveAction() header comments. Containing form SaveGenAndPopPK() Also, if you did any explicit messaging to the user, that should be replaced by populating THISFORM.iaSaveFailureInfo[] see XXFWFRM.VCX/frmDataEntry.SaveAction() header comments. SaveBeforeUpdateBuffers() Also, if you did any explicit messaging to the user, that should be replaced by populating THISFORM.iaSaveFailureInfo[] see XXFWFRM.VCX/frmDataEntry.SaveAction() header comments. frmDataEntry does not have a corresponding method the logic is replaced by calls in SaveAction to each data-entry grid's OnFormSaveAction() method. Also, if you did any explicit messaging to the user, that should be replaced by populating THISFORM.iaSaveFailureInfo[] see XXFWFRM.VCX/frmDataEntry.SaveAction() header comments. SaveCheckRequiredFields() SaveAfterSuccess() SaveAfterFailure()
VM4UPGRD.DOC

ShellBeforePreSave

X3FWCTRL.VCX cmdDataSave

PreSave

X3FWCTRL.VCX cmdDataSave

ShellAfterPreSave

X3FWCTRL.VCX cmdDataSave

ProcessDataEntryGrids

X3FWCTRL.VCX cmdDataSave

CheckRequiredFields AfterUltimateSuccess AfterUltimateFailure


Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

X3FWCTRL.VCX cmdDataSave X3FWCTRL.VCX cmdDataSave X3FWCTRL.VCX

Page 10

UpdateAddOnTheFlyRecord MessageOnFailure ODBCErrorMessage ilSuppressGridErrorMessage

cmdDataSave X3FWCTRL.VCX cmdDataSave X3FWCTRL.VCX cmdDataSave X3FWCTRL.VCX cmdDataSave X3FWCTRL.VCX cmdDataSave X3FWCTRL.VCX cmdDataDelete X3FWCTRL.VCX cmdDataDelete

SaveUpdateAddOnTheFlyRecord() SaveMessageOnFailure() SaveODBCMessageOnFailure() removed

Click (don't bother DOing X3DTEPEM on this one) Refresh (don't bother DOing X3DTEPEM on this one)

UserConfirmation MessageText TakeActionOnFailure ShellAdditionalDeleteAction

X3FWCTRL.VCX cmdDataDelete X3FWCTRL.VCX cmdDataDelete X3FWCTRL.VCX cmdDataDelete X3FWFRM.VCX frmDataEntry X3FWCTRL.VCX cmdDataPrint X3FWCTRL.VCX cmdDataPrint

Augment the containing form DeleteAction(), or possibly locate in one of the new methods: DeleteBeforeAnything(), DeleteAfterFailure(), DeleteAfterSuccess() Likely goes in the Refresh() of the instance, overriding the framework abstracted behavior. Note that if you've followed the retrofitting instructions above carefully, this code should be preserved on MODIFYing the containing FORM/CLASS at this point Containing form DeleteConfirmation() combines both the old UserConfirmation() and MessageText() Containing form DeleteConfirmation() combines both the old UserConfirmation() and MessageText() no longer applicable instead, the SaveMessageOnFailure() is called from DeleteAction() Form.DeleteAdditionalAction()

Click (don't bother DOing X3DTEPEM on this one) Refresh (don't bother DOing X3DTEPEM on this one)

Augment the containing form PrintAction() Likely goes in the Refresh() of the instance, overriding the framework abstracted behavior. Note that if you've followed the retrofitting instructions above carefully, this code should be preserved on MODIFYing the containing FORM/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 Class Browser in the Open Dialog, change the "Files of type" dropdown to "Project", and select your ZZ.PJX project file. If the migration has been completed successfully: 1. No classes should have a << double-chevron at the left, which indicates that they inherit from a class library not included in the project. 2. There should only be one class at the outermost indent for each VFP base class a "xxxBase" VMP "base" class.

MODIFICATION: Methods/Properties renamed


The above PEM reorganization spurred other minor renamings. XXFWGRD.VCX grdDataEntry The OnSave method has been renamed to OnFormSaveAction() XXFWFRM.VCX frmDataEntry The UpdateFormOnNew method has been renamed to UpdateFormOnNav() XXFWFRM.VCX pgfDEForms
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 11

The OnUpdateFormOnNew method has been renamed to OnUpdateFormOnNav XXFWCTRL.VCX cmdDataMovePointer The ilUpdateFormOnNew property has been renamed to ilUpdateFormOnNav

Retrofitting Instructions
1. 2. 3. 4. 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. 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. 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. 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 reorganization


The 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.VCX frmData PrintReport() renamed to PrintAction() (and all references to this method updated accordingly) MovePointer() modified to accept an optional 5 th parameter, act on it to determine the Form.Refresh() behavior frmBase ProximityLabel() enhanced to return the Header if the passed control is a grid.column control

Retrofitting Instructions
1. 2. If you have any code in the PrintReport() method of any existing forms, copy this code to the new PrintAction() method. 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 MaxFrame Professional into a separate "child cursor" class definition so that those behaviors can be accessed by parent-child data-entry implementations other than a data-entry grid. During the course of making this enhancement, XXFWGRD.VCX/grdDataEntry was completely overhauled, and the revisions 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 in grdDatEntry.zReadMe) and an alternative "pre-fill" technique is recommended (also documented in grdDataEntry.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 other implementations of the typical parent-child scenario. The VM example app includes form examples VMDECUS6.SCX and 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 important Add/Edit/Delete/Save/Cancel/Navigate events at the form level. These are the same methods as XXFWCOMP.VCX/ctrDERegisteredComposite has for the same reason. Messaging the user on a failed <Save> in XXFWFRM.VCX/frmDataEntry.SaveAction()/SaveMessageOnFailure() has been revamped to make it easier to handle specific messages when the <Save> failure occurs for reasons other than a failed THISFORM.UpdateBuffers(). A new iaSaveFailureInfo array of information is established in XXFW.VCX/frmData to hold this information which can be updated at any point during the <Save> process, and, if so, used to message the user. If not, the user receives the default messaging abstracted into frmDataEntry.SaveMessageOnFailure().

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 12

XXFW.VCX cmdBase KeyPress() modified to remove the code to set Grid.inLastnKeyCode chkBase KeyPress() modified to remove the code to set Grid.inLastnKeyCode spnBase KeyPress() modified to remove the code to set Grid.inLastnKeyCode txtBase KeyPress() modified to remove the code to set Grid.inLastnKeyCode pgfPageRefresh SeeIfPageNeedsRefreshing() modified frmData iaSaveFailureInfo new icFailedUpdateTableAlias removed, replaced by THIS.iaSaveFailureInfo[4] grdBase Init() modified When() modified Refresh() modified iaRelationInfo new StoreRelationInfo() new IsCurrentRowBlank() -- new XXFWMISC.VCX cusChildCursorSvc new class XXFWGRD.VCX grdDataEntry Many PEMs in this class have been removed, several new ones have been added, and EVERY remaining method in this class has been modified. The net effect of these modifications should mean little or no retrofitting chores, but you should review the 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 need updating: GenAndPopKeys() behavior transferred to cusChildCursorSvc (in VMP 3.01, this behavior was abstracted in grdDataEntry.OnSaveAfterDeleteBlankRows) SetLastRecno() behavior eliminated, you will likely have code that needs to simply remove these calls, especially common in the ShellRequery() method of data-entry grids inLastRecno eliminated along with SetLastRecno() BeforeAppendBlank()

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 13

ilAllowAddNew inLastnKeyCode ilRIDelete DeleteAllRows() DeleteCascade() DeleteChildrenInGrids() PrepareForDeleteCascade() inSaveRecno SaveRecno() RestoreRecno() UpdateAddOnTheFlyRecord() ilRegisterWithForm icParentViewAlias -- DO XXDTEPEM with "icParentAlias" and make sure all your grdDataEntry.icParentAlias properties reflect 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.VCX cmdDEGridDelete Click() modified to remove the parameters passed to Grid.DeleteCurrentRow() cmdDEGridAdd Refresh() -- modified

MODIFICATION: XXFW.VCX/pgfPageRefresh.FormContainsDataEntryGrids() method removed


Since XXFWFRM.VCX/frmDataEntry.iaDataEntryGrids[] is an array of public scope, this method is unnecessary and has been removed. XXFW.VCX pgfPageRefresh FormContainsDataEntryGrids() removed SeeIfPageNeedsRefreshing() modified
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 14

Retrofitting Instructions
No retrofitting required unless you have calls to the pageframe.FormContainsDataEntryGrids() method, in which can be replaced 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 any such calls, DO XXDTSRCH WITH ".FormContainsDataEntryGrids(".

MODIFICATION: XXFWGRD.VCX/cmdDEGridDelete behaviors migrated to grdDataEntry


Some of the XXFWGRD.VCX/cmdDEGridDelete.Click() behavior belongs in grdDataEntry, so it can be invoked no matter how the <Delete> action is initiated. Specifically, the user confirmation logic. XXFWGRD.VCX grdDataEntry DeleteConfirmation() new method DeleteCurrentRow() modified cmdDEGridDelete Click() modified UserConfirmation() removed

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

UPDATE: MSGSVC.DBF and STRINGS.DBF


The MSGSVC.DBF and STRINGS.DBF tables contain many new records to accommodate new VMP 4.0 features. VMP 4.0 includes 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 fill in 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 security


See the USER SECURITY and RELATED FEATURES section of this document for information on retrofitting made necessary by user security enhancements.

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 15

ENHANCEMENTS, MODIFICATIONS, NEW FEATURES


This section lists the rest of the VMP 3.01 VMP 4.0 enhancements, modifications, and new features. Retrofitting instructions 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 VMPrequired 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 Instructions
See Chapter 15: Referential Integrity of the VMP 4.0 Reference Guide.

MODIFICATION: X3GENPK() handles generic character IDs properly


Heretofore X3GENPK() generated integer keys whenever the 7 th optional tlGenericID parameter was passed as .T., no matter what you specified for the 5th tlNumeric parameter. In this modification, X3GENPK() now respects the tlNumeric parameter when tlGenericID is passed as .T. Also, when tlGenericID is passed as .T., the 2 nd parameter is irrelevant and is ignored. X3GENPK.PRG -- modified

Retrofitting Instructions
For any existing calls to X3GENPK() for which you've passed the 7 th tlGenericID parameter as .T., you need to make sure the 5th 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 characters


X3GENPK.PRG has been modified to skip more characters than before. Please see the local PROCEDURE IncrementAlphaNumeric 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/restored


XXFWMAIN.PRG has been enhanced to save/restore OKLs and function key assignments in effect in the development environment. XXFWMAIN.PRG

No retrofitting required

ENHANCEMENT: improved technique for preventing multiple instances of the app at one workstation
We've implemented a variation of George Tasker's article in the November 1998 issue of FoxPro Advisor magazine to prevent multiple instances of the app at one workstation. It is faster (especially when Steven Black's INTL Toolkit is installed) and more reliable than the technique we have been using in previous versions of VMP. XXFW.VCX ctrApp SetupMultipleInstances() modified Destroy() modified Init() -- modified

No retrofitting required

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 16

ENHANCEMENT: login form times out


In previous versions, the VMP login form class doesn't timeout. Even if an application-level timeout is in effect, because that is setup much later in application startup, just before the READ EVENTS. XXFW.VCX frmLogin tmrTimeout new timer member times out the login form after 5 minutes

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

ENHANCEMENT: suppress the default oMenu _MSYSMENU


If your application must suppress the installation of a _MYSMENU system menu, XXFW.VCX/cusForms.zReadMe() contains the simple instructions to make it happen. XXFW.VCX cusMenu zReadMe() updated

No retrofitting required

ENHANCEMENT: Support for German toolbar/project save/restore when running an app


The class definitions contained in XXFWMAIN.PRG that save/restore extant Projects and standard VFP toolbars when running 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.PRG cusPushPopVFPToolbars Init() modified cusPushPopProjectManager Init() modified

No retrofitting required

ENHANCEMENT: check for app shutdown conditions periodically


At 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.VCX ctrApp OnTimer() modified ShutdownCheck() new method Logout() modified cusMenu DoForm() modified DoPRG() modified cusForms DeleteInstance() modified XXFWFRM.VCX frmDataEntry CancelAction() modified XXFWMISC.VCX frmReport Load() modified

No retrofitting required

ENHANCEMENT: oUser.oPrefs.SetPref() and .GetPref() can set/get the Description


oUser.oPrefs.SetPref() and GetPref() take an additional optional parameter that allow setting/getting the UserPrefs.Prf_ItemDescription value. XXFW.VCX

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 17

cusUser SetPref() modified GetPref() modified

No retrofitting required

ENHANCEMENT: oApp.GetAppInfo() can return the description


By passing the new optional 2nd parameter as .T. to oApp.GetAppInfo(), you can RETURN the Description field value instead of the Item value. XXFW.VCX ctrApp GetAppInfo() -- modified

No retrofitting required

ENHANCEMENT: XXFWDATA.PRG supports Integer keys


For VMP developers desiring to use Integer primary/foreign keys, XXFWDATA.PRG has been modified to support Integer keys via a new 4th parameter. The Visual MaxFrame Professional Application Setup Wizard has been modified to allow specifying Integer keys (the wizard calls the local procedures in XXFWDATA to create the initial main VMP database). XXFWDATA.PRG -- modified XXWB.VCX frmWizAppSetup FinishAction_CreateDatabase() -- modified

No retrofitting required

ENHANCEMENT: multiple instances attempted from one workstation


The behavior you get when the user attempts to fire up another (second) instance of your VMP app at one workstation is now controlled by a new record in the APPCONFIG table, for "MultipleInstancesOneWorkstation", which can have one of three values: 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.VCX ctrApp SetupMultipleInstances() modified to check the behavior specified in oApp.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 this enhancement. 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 MaxFrame Professional. 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 apps


A 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 apps in VMP. This enhancement adds a few more modifications.

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 18

XXFWMAIN.PRG Modified to call a new oApp.InitialVisibleActions() method to handle _Screen visibility and release any installed splash screen to make it easier to customize these behaviors. The Visual MaxFrame Professional Application Setup Wizard has been enhanced to allow setting the new oApp.ilSDIApp property. XXFW.VCX ctrApp ilSDIApp_Assign() new method ioSDIForm new property SaveReset() modified InitialVisibleActions() modified SetupScreen() modified InstallWallPaper() modified Destroy() modified SetSDIParentForm() new method cusMenu Init() modified InstallInitialMenu() modified XXWBAPPS.PRG/Application Setup Wizard The Application Setup Wizard has been modified to allow setting oApp.ilSDIApp.

ENHANCEMENT: New custom methods to handle Tools/Options changes


Global application objects now have custom OnToolsOptionsChange() methods to handle changes made via typical Tools/Options dialog. XXFW.VCX ctrApp OnToolsOptionsChange() new public method cusForms OnToolsOptionsChange() new public method cusUser OnToolsOptionsChange() new public method cusToolbars OnToolsOptionsChange() new public method cusMenu OnToolsOptionsChange() new public method frmBase OnToolsOptionsChange() new public method tbrBase OnToolsOptionsChange() new public method

No retrofitting required

ENHANCEMENT: control the ROLLOVER portion of SET CENTURY TO via APPCONFIG record
XXFW.VCX/ctrApp.SetupSets() has been enhanced in VMP 4.0 to ensure that VFP 5.0 apps use the new default behavior of VFP 6.0 for SET CENTURY TO..ROLLOVER (in VFP 5.0, a plain SET CENTURY TO results in the century being set to 19, even in the year 2000). In this further enhancement, you can specify the ROLLOVER year in an APPCONFIG record "SetCenturyToRollover". XXFW.VCX ctrApp Init() modified to call the new SetupSets2() method SetupSets() modified SetupSets2() 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 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 19

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 <ExpN> ROLLOVER <ExpN> default


The default SET CENTURY.. setting established/abstracted in oApp has changed from SET CENTURY TO 19 ROLLOVER 50 to a setting that mimics the default/plain SET CENTURY TO setting in VFP 6.0 an implicit SET CENTURY TO <the current century> ROLLOVER <the current 2-digit year of the current century plus 50>. For example, if you start a Visual MaxFrame application in 1998, oApp.SetupSets() issues a SET CENTURY TO 19 ROLLOVER 48. XXFW.VCX ctrApp SetupSets() -- modified

No retrofitting required

ENHANCEMENT: oApp.InstallBitmapWallpaper() updated


In this enhancement, XXFW.VCX/ctrApp.InstallBitmapWallpaper() has been renamed to InstallWallpaper because VFP 6.0 also supports .GIF and .JPG files. Also, the InstallWallpaper() method code has been modified to support Top-Level (SDI) form applications XXFW.VCX ctrApp InstallBitmapWallpaper() removed (renamed) InstallWallpaper() new public method (the old InstallBitmapWallpaper(), plus some modifications

Retrofitting Instructions
If any of your existing apps have overriding/augmented code in the InstallBitampWallpaper() of oApp subclasses, you'll have to move that code to the new InstallWallpaper() method. DO XXDTEPEM WITH "InstallBitmapWallpaper" to find any such methods. 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 necessary


A 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() modified SetupHook1() 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 likely simplify 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 5 th optional parameter allowing you to suppress the TABLEUPDATE() so that it can be performing it manually if necessary/desired after making several updates. XXFW.VCX ctrApp SetAppInfo() -- modified

No retrofitting required

ENHANCEMENT: oApp sets _Screen.Icon to XXFWBLNK.ICO by default


If 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 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 20

ctrApp SetupScreen() -- modified

No retrofitting required
unless, of course, you prefer the FoxHead icon<g>

ENHANCEMENT: User Preferences services split out into new/separate class


The 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 the UserPrefs table. The "INTLLanguage" preference has been moved from the UserPrefs table to the Users table, to a new Usr_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 for remote views if no TMPFILES/SORTWORK are specified, then the views are created in the \WINDOW\TEMP directory). 2. The user preferences engine runs fine when the UserPrefs table is in a remote database (see XXFW.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 and previously 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 been enhanced/updated to allow the user to enable/disable the saving/restoring of user preferences. XXFW.VCX cusUserPrefs new class Also, three new MSGSVC records: "Preferences reset but unavailable" "Preferences unable to reset" "Save, unable, default language" cusUser Init() modified Localize() -- modified icUserPrefsClass new protected property SetupUserPreferences() new protected method to AddObject() the oPrefs member ilUserPrefsSeekTag removed, no longer necessary GetFormObjPrefString() migrated to the new XXFW.VCX/cusUserPrefs class GetUserPreference() 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() ctrApp Localize() -- modified (many other classes have been modified to call oUser.oPrefs PEMs instead of oUser PEMs) XXFWDATA.PRG Modified to split the creation of USERPREFS and V_USERPREFS into a separate local procedure Modified 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 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 21

Retrofitting Instructions
If you have any app-specific references to the former ?lcUsr_PK parameter for the V_USERS parameterized view, you'll need to 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 new Usr_INTLLanguage C(20) field, populated with "Original" or whatever language is currently set for each user in any existing UserPrefs table. Ditto for the new Usr_EnablePrefs L(1) field, populated with a logical value indicating whether that user wants 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 Visual MaxFrame-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 <YourDBC> DO XXFWDATA with <Your2CharPrefix>,"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 new XXFW.VCX/cusUserPrefs class definition, you'll have to update them to call oUser.oPrefs instead of oUser, and to use the new method name. DO XXDTSRCH to find such calls.

ENHANCEMENT: easy to run an application without user preferences


In this enhancement, modifications have been made to eliminate the need to have a USERPREFS table if it doesn't exist, all default user preference behaviors are ignored. So if you want the performance benefit of not running the user preference code, all you have to do is ensure that the USERPREFS table remains closed during application execution or completely remove 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 class definitions. 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.VCX cusUser SetUserPreference() -- modified GetUserPreference() -- modified SaveUserPrefs() -- modified RestoreUserPrefs() modified tbrBase SaveUserPrefs() modified XXFWGRD.VCX (Visual MaxFrame Professional) cusGridPreference SavePrefs() -- modified RestorePrefs() -- modified

No retrofitting required

ENHANCEMENT: easy to setup Help


New 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-specific help at the form level. XXFW.VCX ctrApp Init() modified Destroy() modified SetupHelp() new method frmBase

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 22

GotFocus() modified LostFocus() modified Destroy() modified SetupHelp() new method CleanupHelp() new method

Retrofitting Instructions
Add a "SetHelpToFile" record to your APPCONFIG table, and populate the Ap_ItemVal field with the name of your Help file. 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() and XXFW.VCX/frmBaseCleanupHelp().

ENHANCEMENT: specify whether _Screen.Visible gets set to .F. on app startup


Many VMP developers have complained that they don't want _Screen.Visible set to .F. when a VMP app is started from the Command Window. A new optional 2nd parameter is accepted by XXFWMAIN.PRG to make that possible. XXFWMAIN.PRG modified to accept an optional 2nd parameter, and use its value to determine whether to set _Screen.Visible = .F. on app startup

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

ENHANCEMENT: classes in other .APPs can be instantiated


VMP classes and programs have been enhanced to support the optional [IN cAppFileName] clause for the SET CLASSLIB TO command (see also NewObject). This allows creating objects and instantiating .VCX-based forms that are not in the main VMP .APP. See also the last XXFW.VCX/ctrApp.zReadMe notes that describe their usage to create "modules". XXFW.VCX cusForms DoForm() modified to add an optional 5th parameter cusMenu DoForm() modified to add an optional 5th parameter X3SETCLS.PRG modified to add an optional 2 nd parameter X3SETCPR.PRG modified to add an optional 2nd parameter X3WRPFRM.PRG modified to add an optional 3rd parameter

No retrofitting required

APPLICATION SETUP WIZARD


ENHANCEMENT: Application Setup Wizard sets the oUser.icUsersTableDatabase property
If 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 shortcut
The 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 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 23

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

No retrofitting required

ENHANCEMENT: Application Setup Wizard easier to subclass


The single FinishAction() method of the Visual MaxFrame Professional Application Setup Wizard has been split out into a series of FinishAction_() methods, making it easier to subclass those individual actions. XXWB.VCX frmWizAppSetup FinishAction() modified to simply call a series of specific FinishAction_() methods

No retrofitting required

ENHANCEMENT: application setup wizard adds MSGSVC.DBF to the project


The Visual MaxFrame Professional Setup Wizard now adds the app-specific copy of MSGSVC.DBF (copied from \MSGS to the app-specific data directory) to the .PJX project. XXWB.VCX frmWizAppSetup FinishAction() -- modified

No retrofitting required

ENHANCEMENT: Shortcut menu available for CONFIG.FPW editbox on Page4 of Application Setup Wizard
The editbox on Page4 of the Application Setup Wizard allows editing the development CONFIG.FPW, and now has a shortcut 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 select from the optional table/view elements in the main VMP-required database. To create the selected tables/views, the wizard simply calls XXFWDATA.PRG, passing the indicated parameters.

No retrofitting required

ENHANCEMENT: New subclassing option supports "intermediate" classes


The 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 intermediate classes from the wizard, if they don't exist already.

No retrofitting required

USER SECURITY and RELATED FEATURES

The details of this new feature are explained in the Reference Guide chapter User Security and Related Features. Please consult that reference for the new features they are not listed here. What we've included here are those items that possibly require retrofitting of existing VMP 3.01 apps.

ENHANCEMENT: Users table modifications


The 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 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 24

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 (none) "S"upervisor "G"lobal user (read-write access) "R"eadonly (none) VMP 4.0 acceptable values 1 = Administrator 2 = Supervisor 5 = User 8 = Guest 9 = No access

Retrofitting requires that you find any explicit uses of Usr_Rights that specify/expect the former "S"/"G"/"R" values and update 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. Description This field allows specifying user records as "hidden" by setting to "Y". System/hidden users are not included in any 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 deleting a user, use this flag to set a user "inactive" and therefore unavailable for picklist selections, etc. Usr_PhoneExt* C 4 Phone extension. Optional field, if omitted, VMP framework 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 deleted and 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 abstracted into the VMP framework (see the next paragraph regarding the replacement V_UsersList view). Also, the frmUsersMaintenance 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 not installed. frmUserProperties is the users maintenance form when the optional VMP user security system is installed. For more information, see Chapter 27: User 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; create it in your existing 3.0/3.01 apps being migrated to VMP 4.0. Note that the VFP View Designer cannot create the V_UsersList view properly. Copy-and-paste the code from XXFWDATA.PRG into your own utility program to generate the V_UsersList view in the database containing your Users table (or remote view). For more information, see Chapter 27: User Security of the VMP 4.0 Reference Guide. FieldName Usr_System DataType C Size 1 DefaultValue "N"

ENHANCEMENT: Usr_Notes field optional


Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 25

The default USERS.Usr_Notes memo field is now optional. If you want to remove it (and its accompanying .FPT file), Visual MaxFrame 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 property


The new XXFW.VCX/frmBase.icSecurityID property is for use with the optional VMP user security system. Its property description contains instructions for its use, and further information is contained in XXFW.VCX/frmBase.SetReadOnly(). XXFW.VCX frmBase icSecurityID new property SetReadOnly() -- modified

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

ENHANCEMENT: when someone attempts to login to an inactive User ID


Part of the overall user security enhancements to VMP 4.0 include a new Users.Usr_Active field. In this enhancement, if someone attempts to log in to an inactive User ID (Usr_Active # "Y"), they get an appropriate message and application startup is immediately terminated. XXFW.VCX frmLogin HitEscape() removed CancelAction() modified OKAction() modified ActionI() new method ActionN() new method ActionY() new method CustomPasswordValid() -- modified txtPassword.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() has been 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 new ActionI() method with the following line:
return THIS.ActionN()

ENHANCEMENT: specify minimum password length


A 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 in XXFWSEC.VCX/ctrUsersBoundControls. XXFWDATA.PRG Adds 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 of the application. The app doesn't terminate, but rather releases and re-instantiates oUser, leaving app control in the user login form. When the APPCONFIG record for "LoginControl" is set to "Normal" and the APPCONFIG record for "TimeoutType" is set to "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 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 26

When the APPCONFIG record for "LoginControl" is set to "None" (no user login is apparent to the user), calling oApp.Logout() does nothing. The VM example application includes a Logout option on the File menu. XXFW.VCX ctrApp Logout() new method OnTimer() modified cusUser UserLogin() -- modified XXFWMAIN.MNX modified to add a default "Log out" option to the File menu

No retrofitting required

ENHANCEMENT: main menu Admin menu pad


The 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 if optional 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 to a form. XXFW.VCX cusMenu AddWindowMenuItem() modified EnsureWindowMenuItemExists() modified Localize() modified cusForms DoForm() -- modified

Retrofitting Instructions
You 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 textboxes
XXFW.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, which contains the shortcut menu class. XXFW.VCX txtBase RightClick() modified icShortcutMenuClass new property XXFWMISC.VCX cusShortcutMenu Init() modified InstallEditMenuItems() modified
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 27

No retrofitting required

ENHANCEMENT: new cmdBase properties/Refresh() logic for ReadOnly forms


Two new properties added to cmdBase make it easier to set the runtime "state" (Visible/Enabled) of commandbuttons when THISFORM.ilReadOnly=.T. or THISFORM.ilReadOnlyDueToSecurity=.T. XXFW.VCX cmdBase icStateThisformReadonlyDueToSecurity new property icStateThisformReadonly new property Refresh() modified

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

ENHANCEMENT: additional uses for THISFORM.ioFirstControl


The XXFW.VCX/frmBase.GetFirstControl() method is not called anywhere in the framework (which is a good thing, since it had 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 it that method to explain how you can put THISFORM.ioFirstControl to work in a different manner for your custom usage. XXFW.VCX frmBase Load() modified GetFirstControl() 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 <Save>


The default behavior of editboxes is to display text starting from the top on Refresh(). When there is more text than will fit in the visible portion of the editbox, this results in a Form.SaveAction() behavior where the just-entered text is shifted out of view as the editbox.Refresh() forces the visible text back to the top. This enhancement suppresses that default behavior on Form.AddAction(). Note that the custom AddAction() method is added in frmDataEntry of Visual MaxFrame Professional, so this modification has no intrinsic effect on Visual MaxFrame applications unless you happen to have a custom AddAction() method XXFW.VCX edtBase Refresh() modified

No retrofitting required

ENHANCEMENT: opening (local) views NODATA in the .SCX-based form DataEnvironment is much faster
VFP is faster at opening (local) views NODATA when SET DELETED is OFF. Another VMP 4.0 enhancement to XXFW.VCX/cusDBCSvc.OpenTable() abstracts this behavior when views are opened via calls to oLib.oDBCSvc.OpenTable(), but handling views opened implicitly in the native DataEnvironment of .SCX-based forms is a little tricky. This enhancement handles SETting DELETED OFF before the native DataEnvironment object of .SCX-based forms opens cursors and then SETs DELETED back to its VMP default ON afterwards. The necessary protections are in place to only execute this behavior when the DataEnvironment contains at least one view and all views have their NoDataOnLoad property set to .T. if views are to be opened WITH data, SET DELETED must be left ON to prevent DELETED() records from being retrieved 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 to the first non-DELETED() record. XXFW.VCX frmData
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 28

SetDeletedOnOffAtLoad() new public method DEBeforeOpenTables() modified to call THIS.StandaloneSetup() and SetDeletedOnOffAtLoad() PrivateDataSessionSets() modified Load() 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 make the callback before taking any action with respect to the open cursors. DO XXDTEPEM WITH "Load" to find all forms/form classes with explicit Load code, and make sure the callback is before any cursor-specific code (the VM example app had no forms/classes with Load code that needed modification, but it's good to make sure).

ENHANCEMENT: oForms.HowManyInstantiated() can also return the total number


XXFW.VCX/cusForms.HowManyInstantiated() has been enhanced to accept the first parameter as "ALL", in which case the total number of forms instantiated via oForms.DoForm() and therefore currently tracked in oForms.iaFormInstances is RETURNed. XXFW.VCX cusForms HowManyInstantiated() modified

No retrofitting required

ENHANCEMENT: forms initially displayed offset to the previous form if they completely obscure it
When forms are instantiated, if they completely obscure the form that was up when they were called, the new form cascaded just below and to the right of the previously-active form. This behavior is intended as a visual aid to the average user, to make it clear that a new form is active, but the previous one is still there. XXFW.VCX frmBase SetInitialVisibleLocation() -- modified

No retrofitting required

MODIFICATION: base combo class contains Valid and adds a CustomValid() method
Combobox validation is a little different than that of other standard data-entry controls, consisting mostly of just simple "addon" 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 in that 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 cboBase Valid() modified CustomValid() new method

Retrofitting Instructions
No 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 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 29

XXFW.VCX/frmBase.CheckRequiredFields() contains code to recurse through all form members, looking for any whose custom 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. are now "registered" with the form, which can just loop through those controls on <Save>, rather than all members. In the public domain Visual MaxFrame files, frmBase.CheckRequiredFields() isn't actually called anywhere, but if you've called 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 property RegisterReqControls() new public method CheckRequiredFields() modified Init() modified Destroy() modified cboBase Init() modified ilRequired_Assign() new method chkBase Init() modified ilRequired_Assign() new method edtBase Init() modified ilRequired_Assign() new method opgBase Init() modified ilRequired_Assign() new method spnBase Init() modified ilRequired_Assign() new method txtBase Init() modified ilRequired_Assign() new method

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

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

ENHANCEMENT: Control.inRequiredBackColor property migrated to the app/user level rather than the control level
Controls whose custom Visual MaxFrame ilRequired property is set to .T. also display in the inRequiredBackColor, which defaults 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 level changes to global objects in the current application session. XXFW.VCX cboBase inRequiredBackColor removed chkBase
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 30

inRequiredBackColor removed edtBase inRequiredBackColor removed opgBase inRequiredBackColor removed spnBase inRequiredBackColor removed txtBase inRequiredBackColor removed cusForms inRequiredControlBackColor new public property SetinRequiredControlBackColor new public method Init() modified OnToolsOptionsChange() modified XXFWDATA.PRG/APPINFO table A new APPINFO record "RequiredControlBackColor" sets the default value at the application level. However, if you provide an interface, each user can specify their preference, stored in the User Preferences table. If you have Visual MaxFrame Professional, 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's easier 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 Preferences


To allow each user to toggle the Form.ShowTips property globally for all forms in the app, the XXFW.VCX/frmBase.ShowTips property has been Reset to Default (.F.) and is instead set dynamically in frmBase.RestoreUserPrefs() where it is set to the value stored in oForms.ilShowTips (which, in turn, has been set by the oForms.SetilShowTips() custom method). Since XXFW.VCX/cusForms.ilShowTips has been set to .T., there is no net change to existing VMP apps as forms are instantiated, their ShowTips property is set to .T. However, this new feature allows you to provide a Tools/Options interface where the user can toggle Tool Tips on/off for the entire app. If you have Visual MaxFrame Professional, the VMTOPTS.SCX form demonstrates one way to do this. XXFW.VCX frmBase ShowTips Reset to Default (.F.) RestoreUserPrefs() modified OnToolsOptionsChange() modified XXFW.VCX cusForms ilShowTips new public property, defaults to .T. SetilShowTips() new public method OnToolsOptionsChange() modified

No retrofitting required

ENHANCEMENT: MovePointer() a specified number of records


XXFW.VCX/frmData.MovePointer() has been enhanced to accept an additional parameter specifying the number of records to SKIP. XXFW.VCX frmData MovePointer() modified XXFWFRM.VCX frmDataEntry MovePointer() modified
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 31

XXFWCTRL.VCX cmdDataMovePointer Click() modified inHowMany new property

No retrofitting required

ENHANCEMENT: X3WRPFRM() and oForms.DoForm() can receive/send an object parameter


In 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 to X3WRPFRM()/oForms.DoForm() for passing on to the called form. See the parameter listing in the header comments of X3WRPFRM.PRG and XXFW.VCX/cusForms.DoForm(). X3WRPFRM.PRG modified XXFW.VCX cusForms DoForm() modified

No retrofitting required

FEATURE: new oForms.GetSYS1271() method


XXFW.VCX/cusForms.GetSYS1271() is a new oForms method that returns the .SCX/.VCX/.PRG filename where the passed form/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 "Current Screen.ActiveForm" menu option that executes oForms.GetSYS1271(Screen.ActiveForm,.t.), useful for developers if they want to know what form is currently running, or for the system administrator to be more helpful over the phone. XXFW.VCX cusForms GetSYS1271() new method

No retrofitting required

ENHANCEMENT: standalone form setup/cleanup split out into separate object


Most standalone form setup/cleanup tasks have been split out into a separate XXFW.VCX/cusStandaloneForms class, and instance of which is created in XXFW.VCX/frmBase.StandaloneSetup(). XXFW.VCX frmBase Init() modified StandaloneSetup() modified iaScreenTimers removed iaStandaloneStuff removed cusStandaloneForms 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, since that array has been moved to goStandaloneForms.iaStuff.

ENHANCEMENT: OnFormDestroy() method added to container classes


Data-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" (or anything else you want to do at that point) for those containers. Abstracted code sets THIS.iaVelcro to .NULL.; augment as desired. XXFWCOMP.VCX ctrDERegisteredComposite OnFormDestroy() new method XXFWGRD.VCX grdDataEntry
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 32

OnFormDestroy() new method XXFWFRM.VCX pgfDEForms OnFormDestroy() new method frmDataEntry Destroy() -- modified

No retrofitting required

MODIFICATION: txtBase.Century property defaults to 1-On


In 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 1On, which is the default for VFP 6.0. XXFW.VCX txtBase Century -- modified

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

MODIFICATION: Form.BackColor reset to default


Instead of setting the frmBase.BackColor to gray explicitly, it has been Reset To Default, since gray is the default in VFP 5.0 on. XXFW.VCX frmBase BackColor reset to default

No retrofitting required

FEATURE: oUser created for standalone forms


When running forms standalone at the Command Window, oUser is now created. The user is logged in according to the login control records in APPCONFIG.DBF. If you want to run User Preferences for standalone forms, just make sure the UserPrefs table is opened early on, THISFORM.CustomStandaloneSetup3() or an augmented THISFORM.StandaloneSetupOUser() is probably the best place to do so. If your oUser object instantiation is just too complicated for use when running forms standalone, just NODEFAULT the new Form.StandaloneSetupOUser() method. XXFW.VCX frmBase StandaloneSetup() modified StandaloneSetupOUser() new method cusUser Init() modified UserLogin() -- modified

No retrofitting required
however, you may have to set your oUser.icUsersTableDatabase property explicitly to prevent oUser.Init() from crashing (to remind you, an X3WINMSG dialog lets you know why you crashed and what you need to modify).

ENHANCEMENT: txtBase.Year2000Strategy() obsolete


The manual Year 2000 strategy we implemented previous versions of Visual MaxFrame is no longer necessary because this version no longer supports VFP 3.0b. This resulted in the removal of several PEMs from XXFW.VCX/txtBase, making it leaner, meaner, and faster. XXFW.VCX txtBase zReadMe() modified Valid() modified
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 33

KeyPress() modified GotFocus() -- modified Year2000Strategy() removed inVFPVersion removed icContents -- removed

No retrofitting required

MODIFICATION: labels are no longer "refreshable"


In VFP 3.0b, issuing THISFORM.Refresh() fires the Refresh() method of any contained labels, if the labels have a custom Refresh() method (no native VFP Refresh() method). The good folks at Microsoft removed this functionality in VFP 5.0, and we have now removed support for this "feature" in lblBase. XXFW.VCX lblBase Refresh() -- removed BoundCaption() -- removed

Retrofitting Instructions
If you have any labels that used this feature running under VFP 3.0b in VMP 3.01, replace those label instances with other necessary code. You should be able to redefine them to instances inheriting from XXFWCTRL.VCX/txtLabel. To find any such labels that need retrofitting, DO XXDTEPEM WITH "BoundCaption".

ENHANCEMENT: new cmdDataGeneral button class


The new XXFWCTRL.VCX/cmdDataGeneral button class is intended as the ultimate parent class for any buttons on VMP data-entry forms, for those buttons that do not inherit from cmdDataAction/cmdDataMovePointer: Save/Cancel/Add/Delete/Find/Print/OK/Top/Bottom/Next/Previous. This class has 3 additional properties whose settings along with abstracted Refresh() code control the "state" (Visible/Enabled) during the three form "modes": Add, Edit, Default. XXFWCTRL.VCX cmdDataGeneral new class cmdDataCallMemoEditForm redefined to inherit from cmdDataGeneral

No retrofitting required

FEATURE: new cmdPicklistValid class


XXFWCOMP.VCX/cmdPicklistValid is a button class inheriting from the new XXFWCTRL.VCX/cmdDataGeneral class to be used as the ultimate parent class of any optional "lookup" button added to the new XXFWCOMP.VCX/ctrPicklistValid "txtPicklistValid container" class. XXFWCOMP.VCX cmdPicklistValid new class

Retrofitting Instructions
If you have created any ctrPicklistValid subclasses that include a "lookup" button, you need to redefine those buttons to inherit from XXFWCOMP.VCX/cmdPicklistValid. Note that you may need to create intermediate/app-specific subclass(es) of cmdPicklistValid first, and then redefine your instances to inherit from those class(es).

ENHANCEMENT: grdPicklist/grdGeneral txtFind locations in Tab Order more flexible


In previous versions, we required any txtPicklistFind associated with a grdGeneral/grdPicklist be the previous control in tab order. In this enhancement, we allow you more lattitude in placement of any associated txtPicklistFind "Look For:" textbox. However, as documented in the grdGeneral/grdPicklist zReadMe, fastest performance is yielded by putting the txtPicklistFind textbox immediately before the grid, in tab order. XXFWGRD.VCX grdGeneral GetFindTextboxTabDiff() modified XXFWPICK.VCX grdPicklist CommonHeaderDblClick() modified
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 34

CommonTextboxKeypress() modified

No retrofitting required

MODIFICATION: new frmDEGridNav.NavTimerAction() method


XXFWFRM.VCX/frmDEGridNav has a new NavTimerAction() method, containing the code executed by the timer associated with the navigational grid (fires when the user pauses navigating in the grid for the timer.Interval). This makes it easier to augment the behavior, since the timer action is kinda obscure. XXFWFRM.VCX frmDEGridNav NavTimerAction() new method frmDEGridNav2Pages NavTimerAction() modified to include the code that was previously in the tmrPauseGridRefresh1.TimerAction() .pgfPageRefresh1.Page1.tmrPauseGridRefresh1.TimerAction() modified to simply call THISFORM.NavTimerAction() frmDEGridNav NavTimerAction() modified to include the code that was previously in the tmrPauseGridRefresh1.TimerAction() .tmrPauseGridRefresh1.TimerAction() modified to simply call THISFORM.NavTimerAction()

Retrofitting Instructions
No retrofitting required unless you have explicit code in the TimerAction() of the timer on forms inheriting from frmDEGridNav2Pages/frmDEGridNavNoPages. DO XXDTEPEM WITH "TimerAction" to find any such code.

MODIFICATION: suppress extra grdDataEntry.ShellRequery()s


When selecting THISFORM.AddAction() on frmDEGridNav2Pages forms (or forms you create yourself that include an instance of XXFWFRM.VCX/pgfDEForms) that contain a data-entry grid, if the pageframe.OnUpdateFormOnAdd() contains explicit code to activate a specific page, as does frmDEGridNav2Pages.pgfPageRefresh1.CommonPageActivate(), then the ShellRequery() data-entry grid(s) can fire 2 or 3 times instead of once. This bug fix corrects that situation. XXFW.VCX pgfPageRefresh CommonPageActivate() modified XXFWFRM.VCX frmDataEntry UpdateFormOnAdd() modified

No retrofitting required

ENHANCEMENT: grdNavigate calls pageframe.OnUpdateFormOnNav()


When a form inherits from XXFWFRM.VCX/frmDataEntry and contains both an instance of XXFWFRM.VCX/grdNavigate and an instance of XXFWFRM.VCX/pgfDEForms (for example, XXFWFRM.VCX/frmDEGridNav2Pages), then as the user navigates in the grid, its AfterRowColChange() calls the pageframe's OnUpdateFormOnNav(). This abstracts an "automatic" call to the pageframe.OnUpdateFormOnNav(), allowing code to be executed relative to the pageframe as the record pointer in the navigational grid.RecordSource moves. XXFWFRM.VCX grdNavigate AfterRowColChange() modified to call any THISFORM.ioDEPageFrame.OnUpdateFormOnNav() pgfDEForms OnUpdateFormOnAdd() -- added a call to THIS.EnableDisable() OnUpdateFormOnCancel() -- added a call to THIS.EnableDisable() OnUpdateFormOnSave() -- added a call to THIS.EnableDisable() OnUpdateFormOnNav() -- updated the header comments frmDEGridNav2Pages pgfPageRefresh1.OnUpdateFormOnDelete() -- reset to default pgfPageRefresh1.OnUpdateFormOnSave() -- reset to default pgfPageRefresh1.OnUpdateFormOnCancel() -- replaced the explicit call to THIS.EnableDisable() with a manual callback pgfPageRefresh1.OnUpdateFormOnAdd() -- replaced the explicit call to THIS.EnableDisable() with a manual callback

No retrofitting required

MODIFICATION: better picklist form class hierarchy


Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 35

The three commandbutton classes in XXFWPICK.VCX are not necessary, and only bloat the .VCX. They have been removed. The commandbuttons on XXFWPICK.VCX/frmPicklist have been re-defined to come from the appropriate existing VMP commandbutton classes, and form functionality is identical to what is was in previous versions of VMP. Also, the custom XXFWPICK.VCX/frmPick.SelectAction() method has been removed and its contents migrated to the standard VMP form method OKAction(). Again, the actual behavior is unchanged. XXFWPICK.VCX frmPick SelectAction() removed OKAction() modified to contain what was in SelectAction() cmdPicklistAdd removed cmdPicklistCancel -- removed cmdPicklistOK removed

Retrofitting Instructions
If you had any explicit SelectAction() code, you'll need to migrate it to OKAction. DO XXDTEPEM WITH "SelectAction" to find any such overriding/augmenting code. DO XXDTSRCH WITH ".SelectAction(" to find any explicit calls to this method, replace them with calls to OKAction(). Any PEM modifications you might have made (unlikely) to the 3 commandbuttons on XXFWPICK.VCX/frmPicklist should be OK because the existing commandbuttons on the form class were simply re-defined to inherit from existing VMP classes.

FEATURE: toggle forms to/from ReadOnly state


A new custom class definition allows toggling a form between ReadOnly and ReadWrite access by calling its methods. The following form examples in the VM example application demonstrate usage: VMDECUSg.SCX VMDECUSh.SCX VMDECUSi.SCX VMDECUSj.SCX VMDEINV2.SCX VMDELKU4.SCX VMDECTYa.SCX XXFWMISC.VCX cusToggleFormReadOnly new class

No retrofitting required

ENHANCEMENT: THISFORM.RefreshControlsOfBaseClass() optionally hits the active page on a THISFORM.ioDEPageFrame, too


XXFW.VCX/frmBase.RefreshControlsOfBaseClass() now receives a new optional 2 nd parameter, which, if passed as .T., also refreshes the indicated controls if they are contained on the active page of a pageframe inheriting from XXFWFRM.VCX/frmDEForms and stored to THISFORM.ioDEPageFrame. There are 2 calls to THISFORM.RefreshControlsOfBaseClass() in the VMP framework, both which have been modified to pass the 2 nd parameter as .T. XXFW.VCX frmBase RefreshFormControlsOfBaseclass() modified XXFWFRM.VCX tbrSCADONav Show() -- modified frmDataEntry UpdateFormOnEdit() -- modified UpdateFormOnSave() -- modified

No retrofitting required

ENHANCEMENT: new txtPicklistValid properties to reduce DoPicklistForm() subclassing

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 36

In order to fully support the 3 parameters that can be sent to the picklist form summoned on an invalid entry or hotkey lookup, two new properties have been added to XXFWCTRL.VCX/txtPicklistValid. The property values are processed in the DoPicklistForm() method into the 2 nd and 3rd optional parameters sent to the picklist form, reducing the need to subclass txtPicklistValid.DoPicklistForm() in order to send the filter condition. XXFWCTRL.VCX txtPicklistValid icPicklistFormFilter new public property ilPicklistFormAddButton new public property DoPicklistForm() -- modified

No retrofitting required

ENHANCEMENT: new shell/empty frmPick.BeforeCallAddForm() method


XXFWPICK.VCX/frmPick has been enhanced to add an empty/shell BeforeCallAddForm(), called from the AddAction() method, and allowing you to put instance-specific code to execute before actually calling the <Add> form, and potentially RETURNing .F., preventing the <Add> form from being called. XXFWPICK.VCX frmPick BeforeCallAddForm() new public method

No retrofitting required

ENHANCEMENT: txtPicklistValid.ShellAdditionalProcessing() RETURNs a value


If the code you add to the ShellAdditionalProcessing() of an XXFWCTRL.VCX/txtPicklistValid control needs to prohibit some action after the user has passed all other validation, you can RETURN .F. to do so (in previous versions of VMP any RETURN value was ignored). XXFWCTRL.VCX txtPicklistValid ShellAdditionalProcessing() comments modified ProcessNewValue() -- modified ActionOnInValid() -- modified CustomValid() -- modified

No retrofitting required

MODIFICATION: consistent Find dialogs from shortcut menu


In VMP 3.01, when a shortcut menu inheriting from X3FWMISC.VCX/cusShortCutMenu was called from a VMP editbox as the default behavior, the actual Find dialog presented to the user was either the native VFP Find dialog, if the editbox was contained in a modeless form the custom VMP Find dialog (X3FWFRM.VCX/frmFindDialog) if the editbox was contained on a modal form (because the native VFP Find dialog never enables the <Find Next> option in modeless forms) This behavior was based on the premise that we should always use native stuff when possible. However, from the perspective of a consistent interface, this behavior undesirable. Not only does the VMP Find dialog not contain the extra options at the bottom that are never enabled in a distributed .EXE, but the native VFP Find dialog does not have an icon consistent with the rest of the application. So, in this modification, we call the custom VMP Find dialog from both modal and modeless forms, when called from the cusShortCutMenu class. XXFWMISC.VCX cusShortCutMenu EditBoxMenuActions() -- modified InstallEditMenuItems() -- modified

No retrofitting required

ENHANCEMENT: Form <Cancel> faster when data-entry grid(s) on pageframes


Abstracted code has been modified to not REQUERY() data-entry grid(s) located on pageframes inheriting from pgfPageRefresh when the form-level <Cancel> is performed. The REQUERY() is not necessary because the form-level RevertBuffers() call as part of THISFORM.CancelAction() already reverts the buffer.
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 37

XXFWGRD.VCX grdDataEntry OnPageActivate() -- modified

No retrofitting required

ENHANCEMENT: ctrMover Selected cursor does not have to have a single field matching .lstAvailable.RowSource
When the mover is used with cursors, you can present a field expression in the Selected listbox without having to have a single field in the .icSelectedCursorName cursor that exactly matches the current .lstAvailable.RowSource only the field expression must match. XXFWCOMP.VCX ctrMover icSelectedCursorFieldExpr() new public property OnUpdateFormOnNav() modified RemoveAction() -- modified

No retrofitting required

ENHANCEMENT: better messaging on failed form <Save> due to row/field rule


Instead of defaulting to a generic (and not very informative) message when a data-entry form <Save> fails, this enhancement presents the user with the rule error test established in the .DBC if the <Save> failed due to a failed row/field rule. If that rule error text has been "INTL-ized" via stored procedure XXFWRuleErrorText() (see XXFWDATA.PRG and VMDVRULE.PRG in the VM example app), then the localized/translated message is presented. XXFWFRM.VCX frmDataEntry SaveMessageOnFailure() -- modified

No retrofitting required

ENHANCEMENT: specify text when no ProximityLabel() exists


The code in XXFWFRM.VCX/frmDataEntry.SaveCheckRequiredFields() has been enhanced so that if a "proximity label" can't be found for an empty-but-ilRequired control, if that control has the new custom icProximityLabel property and it is not empty(), then that text is used for the resulting MSGSVC() dialog. If that fails to find message text, the existing subsequent logic kicks in to check the .DBC for a Caption property and finally, as a last resort, use the Control.Name text. Note that all VMP controls that have a custom ilRequired property also have this new icProximityLabel property. This can be especially useful for OptionGroups because they frequently don't have a nearby label. XXFWFRM.VCX frmDataEntry SaveCheckRequiredFields() modified XXFW.VCX cboBase icProximityLabel new property chkBase icProximityLabel new property edtBase icProximityLabel new property opgBase icProximityLabel new property spnBase icProximityLabel new property txtBase icProximityLabel new property

No retrofitting required
unless, of course, you've kludged a workaround in the past and can now eliminate that code and simply fill in the new icProximityLabel property.
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 38

ENHANCEMENT: support for a "proximity" txtLabel


The frmBase.ProximityLabel() method has been enhanced to support a textbox inheriting from XXFWCTRL.VCX/txtLabel as the proximity label. XXFW.VCX frmBase ProximityLabel() modified XXFWFRM.VCX frmDataEntry SaveCheckRequiredFields() modified

No retrofitting required

ENHANCEMENT: ctrMover removes the ".f." line when there are no Available items
When there are no Available items and you're using arrays in XXFWCOMP.VCX/ctrMover, the default VFP behavior is to display a ".f." on the first line of the listbox, since its RowSource is an empty one-cell array. This enhancement suppresses that ".f.", leaving the listbox truly empty. XXFWCOMP.VCX ctrMover OnUpdateFormOnNav() -- modified

No retrofitting required

ENHANCEMENT: frmChangePassword overhauled


XXFWFRM.VCX/frmChangePassword has been overhauled to take advantage of/synch with the new optional VMP user security system modifications. XXFWFRM.VCX frmChangePassword (lots of changes)

Retrofitting Instructions
No retrofitting is required unless you passed parameters to your instances/subclasses of frmChangePassword it's Init() no longer accepts parameters, and it no longer supports being called standalone from the Command Window.

MODIFICATION: frmChangePassword textbox properties


To make it easier to subclass, the textbox properties set in the form.Init() are now set in the SetExprProps() method of each textbox. XXFWFRM.VCX frmChangePassword Init() -- modified .txtCurrentPassword SetExprProps() -- modified .txtNewPassword SetExprProps() -- modified .txtConfirmPassword SetExprProps() -- modified

No retrofitting required

ENHANCEMENT: ctrMover now inherits from ctrDERegisteredComposite


Movers are easier to manage now because XXFWCOMP.VCX/ctrMover has been redefined to inherit from XXFWCOMP.VCX/ctrDERegisteredComposite. XXFWCOMP.VCX ctrMover redefined to inherit from ctrDERegisteredComposite UpdateMoverOnNew() removed (use OnUpdateFormOnNav() instead)

Retrofitting Instructions

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 39

Move your old mover.UpdateMoverOnNew() code to the new OnUpdateFormOnNew(), inherited from XXFWCOMP.VCX/ctrDERegisteredComposite. To see if you have any such code to move, DO X3DTEPEM WITH "UpdateMoverOnNew" on your existing VMP 3.01 application. Note that the ctrMover instance on XXFWFRM.VCX/frmMover is, of course, this newly-redefined ctrMover.

ENHANCEMENT: removed parameters from UpdateFormOnSave/Cancel methods


XXFWFRM.VCX/frmDataEntry methods UpdateFormOnSave() and UpdateFormOnCancel() heretofore received a parameter indicating whether the code has been called subsequent to and "ADD" or "EDIT". Parameter passing is always a pain we avoid when possible, and an earlier enhancement to frmDataEntry.SaveAction() created a new pcMode private memvar (available to all subsequently-called methods) to eliminate this need. In this enhancement pcMode created in SaveAction() is used to eliminate the parameter still passed to UpdateFormOnSave() the pcMode private memvar technique is applied also to UpdateFormOnCancel() eliminated the first CheckIfOnDeletedRecord() parameter, checking the calling program via X2PSTACK() instead XXFWFRM.VCX frmDataEntry CancelAction() removed the 1st parameter sent to CheckIfOnDeletedRecord(), create pcMode, remove the explicit value passed to UpdateFormOnCancel() UpdateFormOnCancel() removed the received lParameter, replaced existing tcPreviousMode references with pcMode CheckIfOnDeletedRecord() removed the first parameter (leaving the second one, which is now the only one) Activate() removed the 1st parameter sent to CheckIfOnDeletedRecord() SaveAction() removed the 1st parameter sent to CheckIfOnDeletedRecord(), remove the explicit value passed to UpdateFormOnSave() frmDEGridNav UpdateFormOnCancel() removed the received parameter and replaced tcPreviousMode references with pcMode UpdateFormOnSave() ditto frmDEGridNav2Pages UpdateFormOnCancel() removed the received parameter and replaced tcPreviousMode references with pcMode UpdateFormOnSave() ditto frmDEGridNavNoPages UpdateFormOnCancel() removed the received parameter and replaced tcPreviousMode references with pcMode UpdateFormOnSave() ditto

Retrofitting Instructions
Retrofitting requires eliminating the parameters from any manual callbacks in your form classes/instances. To find them, DO XXDTEPEM WITH the following: "UpdateFormOnSave" "UpdateFormOnCancel" "CheckIfOnDeletedRecord" "Activate" If you find any such code, you should also replace any explicit references to the passed (tcPreviousMode) parameter with pcMode.

ENHANCEMENT: new txtCustomersZip textbox class


In the VM example application, a new VMCTRL.VCX/txtCustomersZip class provides the bound "Zip" textbox on all the VMDECUS*.SCX forms. The txtCustomersZip.GotFocus() code dynamically updates the InputMask, based on whether the city is in the United States/another country. You might want to create app-specific textbox classes along the lines of this example. VMCTRL.VCX txtCustomersZip new class VMDECUS*.SCX all hacked to redefine the txtCus_Zip to inherit from VMCTRL.VCX/txtCustomersZip and to remove the explicit InputMask setting in the Properties Sheet

No retrofitting required

FEATURE: Shortcut menu for editboxes contains Print and Print Preview options
The default shortcut menu for VMP editboxes now has 2 additional options: Print and Print Preview, allowing the user to preview/print out a quick-and-dirty report from XXTBLOCK.FRX of the editbox contents.
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 40

The new XXTBLOCK.FRX report form can be built right into the distributed .EXE. The default report object is frmReportTextBlock, but you can create/subclass your own if you'd rather, and specify it in the shortcut menu icEditboxReportClass property. The called report form XXTBLOCK.FRX matches the font properties for the single item in the Detail band (for the contents of the calling editbox.Text) to the font properties of the editbox which invoked the shortcut menu. XXFWMISC.VCX cusShortcutMenu EditboxDefaults() modified to add the 2 new menu items EditboxMenuActions() modified to add code when either of the 2 new menu items are selected icEditboxReportClass new public property allows specifying a different report object in subclasses XXFWMISC.VCX frmReportTextBlock new class the default report object called from the 2 new shortcut menu items XXTBLOCK.FRX new VMP report form, executed by the new XXFWMISC.VCX/frmReportTextBlock.ReportForm()

No retrofitting required

ENHANCEMENT: Caption of Zoom form (frmMemoEdit) can be set to explicit string when called from an editbox shortcut menu
When the Zoom form is called from the default shortcut menu of an editbox, the Zoom form Caption can now be set to something other than the default "Notes" (the shortcut menu doesn't/can't pass the optional 3 rd parameter to the frmMemoEdit/Zoom form). Just set the icZoomFormCaption property of VMP editboxes to the desired caption, and code in frmMemoEdit.Init() uses it when the explicit tcCaption parameter hasn't been passed. XXFW.VCX edtBase icZoomFormCaption new public property XXFWFRM.VCX frmMemoEdit Init() -- modified

No retrofitting required

ENHANCEMENT: Zoom form (frmMemoEdit) called from shortcut menu defaults when no user preferences in effect
XXFWFRM.VCX/frmMemoEdit now sets the font properties of the editbox to match those of any "calling" editbox. Also, XXFWFRM.VCX/frmMemoEdit now sets its Height/Width to a default of SYSMETRIC(1/2) *.7 if no user preferences are in effect. XXFWMISC.VCX frmMemoEdit Init() -- modified edtBound1.RestorePrefs() -- modified

No retrofitting required

MODIFICATION: new XXFWCOMP.VCX class library


XXFWCOMP.VCX is a new visual class library to hold classes that are composites or abstract classes intended to be put to use at the app-specific level as composites. Most of the class definitions that will be in this .VCX are form control composites.

Retrofitting Instructions
The VMP 3.01 classes in the list below have been moved to XXFWCOMP.VCX. For each one, if you have created appspecific subclasses, you'll have to use the Class Browser, XXDTHACK.VCX, or otherwise redefine them to inherit from the same class as before, but now located in XXFWCOMP.VCX: ctrGetFile (from XXFWMISC.VCX)
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 41

ctrReportDestinationSPF (from XXFWMISC.VCX) ctrMover (from XXFWMISC.VCX)

ENHANCEMENT: shortcut menu for ctrMover listboxes


The two listboxes in XXFWCOMP.VCX/ctrMover each have a shortcut menu. XXFWCOMP.VCX ctrMover.lstAvailable RightClick() -- modified ctrMover.lstSelected RightClick() -- modified

No retrofitting required

FEATURE: new "complex composite data-management container" class


This new abstract class provides a way to build relatively complex containers for use on data-entry forms that have all the hooks necessary to keep them in synch with the rest of the form in its different modes and actions. Useful for creating appspecific composites that require manual data-handling (for example, controls bound to CREATE CURSOR cursors/temporary views/etc. and the information used to manually replace/update/dirtybuffers of other "real" data cursors). This ctrDERegisteredComposite collaborates with the containing form by "registering" in the same manner as VMP dataentry grids do. At critical Add/Delete/Save/Cancel/etc. junctures, each ctrDERegisteredComposite instance is messaged to execute its corresponding code. XXFWFRM.VCX ctrDERegisteredComposite new class XXFWFRM.VCX frmDataEntry iaDERegisteredComposites new public array property Destroy() modified UpdateFormOnAdd() modified UpdateFormOnCancel() modified UpdateFormOnDelete() modified UpdateFormOnEdit() modified UpdateFormOnNav() modified UpdateFormOnSave() modified AddAction() modified CancelAction() -- modified DeleteAction() -- modified SaveAction() -- modified frmData UpdateBuffers() -- modified

No retrofitting required

FEATURE: txtPicklistValid container for creating composites


txtPicklistValid textboxes frequently need an accompanying control to display related information, and many interface designs utilize a commandbutton to fire the picklist manually. This new feature makes that easily done at the app-specific level. XXFWCOMP.VCX ctrPicklistValid new class cmdPicklistValid new class XXFWCTRL.VCX txtPicklistValid ProcessNewValue() modified BeforeDoPicklistForm() modified Refresh() modified VMFWCOMP.VCX ctrVMPicklistValid new class

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 42

cmdVMPicklistValid new class VMTXTPCK.VCX ctrPicklistValidStyle1 new class ctrPicklistValidStyle2 new class ctrCusNamePicklistValid new class ctrPicklistValidStyle2D new class ctrCityNamePicklistValid new class ctrPicklistValidStyle3 new class ctrPicklistValidStyle3D new class VMDECUSZ.VCX new example form demonstrates several variations VMDEINVL.SCX, VMDEINV2.SCX, VMDEINVA.SCX implement the new ctrCusNamePicklistValid

No retrofitting required

FEATURE: new class automates "manual candidate key uniqueness enforcement"


While VFP tables can specify a candidate key, when a data-entry form contains a textbox/spinner to collect a candidate key value: Enforcement doesn't take place until issuing a TABLEUPDATE(), which makes it difficult to present an informative user-message; a better interface design calls for checking for violation as the user attempts to exit the control Ditto when the ControlSource is a field in a remote view/SQL Pass-Thru (SPT) cursor When the ControlSource is a field in a Fox2x table, all candidate key uniqueness enforcement has to be done manually anyway This new feature is a "manual candidate key uniqueness enforcement" class definition. You attach it to the iaVelcro[] array property of a textbox/spinner, and the CK check is performed in the CustomValid() after default rule-checking and before ActionOnValid(). Of course, you can still perform manual candidate key enforcement in the ActionOnValid() method using a direct call to X3CKCHEK() as is done in several forms in the VM example application (DO XXDTSRCH WITH "X3CKCHEK(" to find them). X3FWCTRL.VCX cusCKCheck new class PEM -- whatever X3FWCTRL.VCX txtBound CustomValid() modified CKCheck() new public method zReadMe() -- modified X3FWCTRL.VCX spnBound CustomValid() modified CKCheck() new public method zReadMe() -- modified VMDEPUBS.SCX txtPub_ID.ShellAdditionalInit() VMDEPUBS.SCX txtPub_Name.ShellAdditionalInit() VMDEINVL.SCX txtInv_NumberCK.CKCheck() VMDEINV2.SCX txtInv_NumberCK.CKCheck() VMDEINVA.SCX txtInv_NumberCK.CKCheck()

No retrofitting required
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 43

ENHANCEMENT: ctrMover updates


Simultaneous with updates to XXFWMISC.VXC/ctrMover implemented VMP v3.01, the improvements listed in VM30ERR.DOC apply here, too. See item VMP56.

No retrofitting required

ENHANCEMENT: tmrPauseGridRefresh updates


Simultaneous with updates to XXFWCTRL.VXC/tmrPauseGridRefresh implemented VMP v3.01, the improvements listed in VM30ERR.DOC apply here, too. See item VMP58.

No retrofitting required

ENHANCEMENT: remote refresh when THISFORM.icMainAlias is an updateable view


When THISFORM.icMainAlias is an updateable local/remote view, the previous XXFWFRM.VCX/frmRemoteRefresh() did not REQUERY() that view, since it is not REQUERY()d in THISFORM.ShellRequeryMainViewAlias(), nor, if THISFORM contains a view manager, is it REQUERY()d by the view manager because it is updateable. In this enhancement, XXFWFRM.VCX/frmDataEntry.RemoteRefresh() has been modified to call a new THIS.RequeryMainAlias() method which handles this scenario. XXFWFRM.VCX frmDataEntry RemoteRefresh() -- modified RequeryMainAlias() -- new

No retrofitting required

ENHANCEMENT: use txtPicklistValid as an "unbound" control


XXFWCTRL.VCX/txtPicklistValid has been enhanced to allow using it as an unbound control. This can be useful when either of the following is true: You are using tables for data-entry. You are using views for data-entry, but for whatever reason you don't want to include the lookup table field in the view definition and therefore have no field to which to bind the txtPicklistValid instance. The key enhancement is to the Refresh() method, to "automatically" update THIS.Value based on the icSeekAlias lookup table. Set the new ilUnbound property to .T. to enable this new behavior. Please note that you cannot use this feature when the txtPicklistValid instance is in a grid column. XXFWCTRL.VCX txtPicklistValid Init() -- modified ProgrammaticChange() -- modified Refresh() -- modified

No retrofitting required

ENHANCEMENT: ilAlternateLookup property for txtPicklistValid


The new XXFWCTRL.VCX/txtPicklistValid.ilAlternateLookup property must be set to .T. when using the AlternateLookup() behavior. This is mandatory when using the new "unbound" behavior, and is optional but highly recommended when using the txtPicklistValid in the "normal" bound condition. XXFWCTRL.VCX txtPicklistValid .ilAlternateLookup new public property Refresh() modified PositionRecnoInSeekAlias() modified ProcessNewValue() modified InteractiveChange() modified CustomValid() modified zReadMe() updated

Retrofitting Instructions

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 44

No retrofitting is actually required, since existing txtPicklistValid controls cannot be using the new "unbound" feature, introduced in this version of VMP. Existing txtPicklistValids that use the AlternateLookup() method are OK, but if you get a chance, it would be a good idea to set the ilAlternateLookup property to .T. anyway. DO XXDTEPEM WITH "AlternateLookup" to find any such existing txtPicklistValids.

ENHANCEMENT: pass an optional new message to frmThermoBar


XXFWFRM.VCX/frmThermoBar.UpdateStatusBar() has been enhanced to allow passing an optional 2 nd parameter specifying new display text. XXFWFRM.VCX frmThermoBar UpdateStatusBar() -- modified

No retrofitting required

ENHANCEMENT: GetNextVelcroElement() can find existing iaVelcro obj ref


The custom GetNextVelcroElement() method of all VMP base classes has been enhanced to allow passing an optional parameter that checks to see if an object of the specified ClassName,VCXFileName is already stored to THIS.iaVelcro. XXFW.VCX xxxBase GetNextVelcroElement() modified

No retrofitting required

ENHANCEMENT: easily specify the ActivePage on <Add>


The new XXFWFRM.VCX/pgfDEForms.inActivePageOnAdd defaults to 2 and allows you to easily specify the page that should be made active when the form goes in to Add "mode". XXFWFRM.VCX pgfDEForms inActivePageOnAdd new public property OnUpdateFormOnAdd modified frmDEGridNav2Pages pgfPageRefresh1.OnUpdateFormOnAdd Reset to Default

Retrofitting Instructions
No retrofitting required unless you have explicit pageframe.OnUpdateFormOnAdd() code to handle this manually. DO XXDTEPM WITH "OnUpdateFormOnAdd" to hunt down explicit methods and make any necessary updates, if any (if all you have in those methods is a callback plus augmenting code, no change required).

ENHANCEMENT: specify the ActivePage on Form.Init()


The new XXFW.VCX/pgfBase.inActivePageOnInit property defaults to 1 and allows you to specify the ActivePage when the containing form instantiates. This property is ignored when the containing form doesn't inherit from frmDataEntry/frmDEGridNav2Pages in Visual MaxFrame Professional. However, you can add code to the InitialSetFocus() method of any VMP form to set the ActivePage of the pageframe to that specified in the inActivePageOnInit property. XXFW.VCX pgfBase inActivePageOnInit new public property XXFWFRM.VCX frmDataEntry InitialSetFocus() modified frmDEGridNav2Pages InitialSetFocus() modified

No retrofitting required

ENHANCEMENT: specify the AcivePage on grdNav.SelectionMade()

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 45

The new XXFW.VCX/pgfBase.inActivePageOnSelection property defaults to 2 and allows you to specify the ActivePage when the user makes a selection in a navigational control in the containing form. This property everywhere in the VMP framework except in XXFWFRM.VCX/frmDEGridNav2Pages.pgfPageRefresh1.Page1.grdNav.SelectionMade() (Visual MaxFrame Professional only). You can use this property in form classes of your own creation that need a similar behavior. XXFW.VCX pgfBase inActivePageOnSelection new public property XXFWFRM.VCX frmDEGridNav2Pages pgfPageRefresh1.Page1.grdNav.SelectionMade() modified

No retrofitting required

ENHANCEMENT: ShellAdditionalInit() RETURN value matters


The Init() of all VMP "base" classes in XXFW.VCX have been modified to check the RETURN value from the call to the ShellAdditionalInit(), and, if it's .F., RETURN .F. from the Init(). XXFW.VCX xxxBase Init() modified ShellAdditionalInit() modified (comments only)

Retrofitting Instructions
No retrofitting required unless, for some unknown reason, you have RETURNed something from your ShellAddtionalInit() code.

MODIFICATION: labels in the mover class renamed


The 2 labels in XXFWCOMP.VCX/ctrMover have been renamed from lblBase1/lblBase2 to lblAvailable and lblSelected. XXFWCOMP.VCX ctrMover lblBase1 renamed to lblAvailable lblBase2 renamed to lblSelected

Retrofitting Instructions
If you have any method code that refers to either label (i.e. to dynamically update the Caption, etc.), then you'll need to update the object references accordingly.

MODIFICATION: GETFILE()/cmdGetFile parameter changes


VFP 6.0 has an extra GETFILE() parameter, requiring corresponding changes to XXFWCTRL.VCX/cmdGetFile. XXFWCTRL.VCX cmdGetFile icDialogCaption modified to only be used in VFP 6.0, corresponding to the GETFILE() parameter #5 icFileNameCaption new property for the GETFILE() parameter #2 icCreatorType removed, since VMP supports only VFP 5.0/6.0, therefore no support for Macintosh

Retrofitting Instructions
In previous versions of VMP, the icDialogCaption property was used for the GETFILE() parameter #2 DO XXDTSRCH/XXDTEPEM with "icDialogCaption" to see if you have any explicit settings that need updating to specify an icFileNameCaption and/or change the existing icDialogCaption.

BUG FIX: Filter on THISFORM.icMainAlias in the DataEnvironment cleared


If you set a filter on THISFORM.icMainAlias in the DataEnvironment/Load/etc., that filter is cleared on form instantiation. XXFW.VCX frmData Init() modified to change the single line call to .SetFilter() to prevent that call when indicated.

No retrofitting required

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 46

ENHANCEMENT: Forms can be run "empty"


The icMainAlias property is no longer required you can instantiate data-entry forms without crashing if it's not set. This makes it easier to dummy up blank forms for prototyping. And to accommodate forms that are based on non-VFP cursor data (i. e. ADO), mostly with future enhancements in mind. Methods in many classes are affected, but there's nothing that alters the existing behavior. Just code to protect against crashes, etc.

No retrofitting required

ENHANCEMENT: textboxes and editboxes support {Shift+F3} like Word


All VMP textboxes and editboxes support {SHIFT+F3} to cycle thru Change Case selections all lower, proper, all upper, just like in Word. This behavior is on the default shortcut menu for both controls, as well as available directly from the keyboard. XXFW.VCX edtBase KeyPress() modified txtBase KeyPress() modified XXFWLIBS.VCX cusChangeTextCase new class XXFWMISC.VCX cusShortcutMenu InstallEditMenuItems() modified EditboxMenuActions() modified

No retrofitting required

ENHANCEMENT: better messages on failed Delete


When a data-entry form.DeleteAction() fails due to a multi-user conflict or failure to get exclusive use of a row/table long enough to effect the deletion, the form.SaveMessageOnFailure() gives a more meaningful message to the user. XXFWFRM.VCX frmDataEntry SaveMessageOnFailure() modified MSGSVC.DBF Two new "Delete, unable, " records.

No retrofitting required

ENHANCEMENT: better default QueryUnload behavior


We've added a 4th data-entry form.QueryUnload() behavior, and made it the default to bring the action in line with other standard software: ask the user if they want to save their changes and close the form. The previous default behavior is now #3 and is the same except that it asks the user if they want to discard their changes and close the form. XXFWFRM.VCX frmDataEntry QueryUnload() modified MSGSVC.DBF one new record XXFWDATA.PRG modified to update the description field of the "FormQueryUnload" record

Retrofitting Instructions
No retrofitting unless you want the old default behavior, in which case you need to set the APPCONFIG.Ap_ItemVal for the "FormQueryUnload" record to "3".

ENHANCEMENT: specify the order in which tables/views/cursors get TABLEUPDATE()d

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 47

Until now, the order in which tables/views/cursors are TABLEUPDATE()d in XXFW.VCX/frmData.UpdateBuffers() has been determined by their position in the AUSED() array. There are situations in which you need to ensure that one or more cursors (particularly tables) get TABLEUPDATE()d before one or more other cursors. This enhancement allows you to update the 10th/sequence column in the paCursors array, indicating the relative order of TABLEUPDATE(). See the header comments in the new XXFW.VCX/frmData.SpecifyTableupdateSequence() method. XXFW.VCX frmData UpdateBuffers() modified SpecifyTableupdateSequence() new method

No retrofitting required

MODIFICATION: frmData.GetMainAliasInfo() method removed


Since the GetCursorInfo() method can do what the GetMainAliasInfo() method does, we have removed the GetMainAliasInfo() method from XXFW.VCX/frmData. XXFW.VCX frmData GetMainAliasInfo() removed

Retrofitting Instructions
If you have any calls to the .GetMainAliasInfo() method, replace them with calls to .GetCursorInfo(). To find any such calls, DO XXDTSRCH WITH ".GetMainAliasInfo" once you've got a copy of your app in VMP 4.0. The GetMainAliasInfo() method was not called anywhere in the VMP framework.

ENHANCEMENT: specify forms not to be added to the Window menu


The new ilAddToWindowMenu property added to XXFW.VCX/frmBase allows you to specify a (modeless) form that should not be added to the Window menu. XXFW.VCX frmBase ilAddToWindowMenu new public property, defaults to .T.

No retrofitting required

MODIFICATION: new pageframe.ilNoFocusOnPageCaptions property


The default behavior of VFP 3.0 (and the preference of many VFP developers) and the default behavior of prior versions of VMP is to not allow pageframe.page.Captions to get focus as pages are activated. The new XXFW.VCX/pgfBase.ilNoFocusOnPageCaptions property allows toggling betweent this default VMP behavior and the "standard" Windows behavior where pageframe pages (their captions) do get focus. XXFW.VCX pgfBase ilNoFocusOnPageCaptions new public property, defaults to .T. zReadMe() explanatory text added pgfPageRefresh CommonPageActivate() modified frmBase InitialSetFocus() -- modified XXFWFRM.VCX frmDataEntry InitialSetFocus() -- modified

No retrofitting required

ENHANCEMENT: Easier record pointer repositioning after <Add> in view-based picklist forms
XXFWPICK.VCX/frmPick.SetRecordPointerOnAdd() has been enhanced to make it easier to reposition the record pointer in THISFORM.icMainAlias when THISFORM.icMainAlias is a view, and therefore has no natural primary key field/value/tag. The new icSetRecordPointerOnAddTag property can be used to specify a tag for repositioning.

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 48

XXFWPICK.VCX frmPick icSetRecordPointerOnAddTag new property SetRecordPointerOnAdd() modified zReadMe() updated frmPickList zReadMe() updated

No retrofitting required

ENHANCEMENT: PKs are not generated if a DefaultValue has been specified


XXFWFRM.VCX/frmDataEntry.GenAndPopPK() has been enhanced to check for a DefaultValue specified for the PK field it would generate/populate a key. If a DefaultValue has been specified for that field, then GenAndPopPK() simply RETURNs .T. it does not call THISFORM.GenPK() nor does it populate the PK field. XXFWFRM.VCX frmDataEntry GenAndPopPK() modified

No retrofitting required

GRIDS
ENHANCEMENT: all grids now inherit incremental-search capability
The incremental-search capability formerly built into grids inheriting from grdPicklist has been migrated to grdGeneral, so all VMP grids (including data-entry grids) can now include a Look For: textbox and do incremental searching based on the current column contents. XXFWGRD.VCX grdGeneral icSeekPrefix migrated here from grdPicklist icFindTextboxName migrated here from grdPicklist SeekValue() migrated here from grdPicklist RegisterWithTextbox() migrated here from grdPicklist GetFindTextboxObjRef() migrated here from grdPicklist SelectionMade() migrated here from grdPicklist Init() modified to call RegisterWithTextbox() XXFWPICK.VCX grdPicklist icSeekPrefix reset to default icFindTextboxName reset to default SeekValue() reset to default RegisterWithTextbox() reset to default GetFindTextboxObjRef() reset to default

No retrofitting required

FEATURE: "prefill" records for data-entry grids


As noted in XXFWGRD.VCX/grdDataEntry.zReadMe(), there are several reasons why the native VFP .AllowAddNew property isn't a great solution to the <Add> interface for a data-entry grid. This new "prefill" feature of VMP data-entry grids offers an alternative: "prefill" the grid with a number of blank rows you specify. The VM example application has examples in these forms: VMDECUS5.SCX VMDEINVa.SCX VMDELKU3.SCX XXFWGRD.VCX
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 49

grdDataEntry inPrefillTotal new property Prefill() new method Init() modified Destroy() modified AfterRowColChange() modified DeleteCurrentRow() modified OnFormDeleteAction() modified OnUpdateFormOnCancel() modified XXFWFRM.VCX frmDataEntry DeleteAction() modified

No retrofitting required

MODIFICATION: toControl parameter removed from grdGeneral.SeekValue()


The 2nd parameter passed to XXFWGRD.VCX/grdGeneral.SeekValue() has never been used for anything and has been removed. XXFWGRD.VCX grdGeneral SeekValue() modified to remove the 2nd toControl parameter XXFWFRM.VCX grdNavigate SeekValue() modified to remove the 2nd toControl parameter XXFWPICK.VCX txtPicklistFind SeekInGrid() modified to not send the 2 nd THIS parameter

Retrofitting Instructions
No retrofitting is required unless you have explicit SeekInGrid (txtPicklistFind subclasses) or SeekValue (grdGeneral subclasses) code. DO XXDTEPEM WITH "SeekInGrid", DO XXDTEPEM WITH "SeekValue" to find any such explicit code.

ENHANCEMENT: grid cover supports MouseWheel()


XXFWGRD.VCX/shpGridCover.MouseWheel() supports using a mousewheel to scroll in the underlying grid. Special thanks to VMP beta tester Gene Pasquini for this one. XXFWGRD.VCX shpGridCover MouseWheel() modified()

No retrofitting required

MODIFICATION: grdDataEntry.inAddCounter property removed


The XXFWGRD.VCX/grdDataEntry.inAddCounter property was never used for anything in the VMP framework and has been removed. XXFWGRD.VCX grdDataEntry inAddCounter removed

Retrofitting Instructions
If you've used this property for anything, you'll have to find another way to get the job done <g>. DO XXDTSRCH WITH "inAddCounter" to see if you have any explicit .inAddCounter references that need attention.

ENHANCEMENT: grid "cover" supports RightClick pass-thru


XXFWGRD.VCX/shpGridCover.RightClick() passes the RightClick on through to the covered grid, same as Click() XXFWGRD.VCX shpGridCover RightClick() modified
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 50

ClickPassThru() new method Click() modified to call the new ClickPassThru()

No retrofitting required

ENHANCEMENT: easier to substitute your own grid preferences class


We previously made no simple provision for substituting your own grid preferences class for the default "cusGridPreference,xxfwgrd.vcx", and you had to override your grid.SetupPreferences() method. In this enhancement, no code is required, you just have to set the new custom icPrefsClass property. To do so globally for all your grids, you'll have to set icPrefsClass for each grid class you subclass out of the VMP framework. XXFWGRD.VCX grdBase icPrefsClass new public method SetupPreferences() modified

No retrofitting required

MODIFICATION: removed call to data-entry grid.UpdateAddOnTheFlyRecord()


Since XXFWVCX/frmDataEntry currently only supports the "add-on-the-fly" for THISFORM.icMainAlias/icMainViewAlias, the call in X3FWGRD.VCX/grdDataEntry.OnSave() (now OnFormSaveAction) to the grid.UpdateAddOnTheFlyRecord() has been removed. XXFWGRD.VCX grdDataEntry OnFormSaveAction() modified

Retrofitting Instructions
It is highly unlikely (but theoretically possible) that you were using the "add-on-the-fly" behavior in association with the RecordSource of a data-entry grid, but, if so, see the header comments for XXFWFRM.VCX/frmDataEntry.SaveUpdateAddOnTheFlyRecord() for instructions on how to make it work when THISFORM.icAddOnTheFlyAlias is the RecordSource of a data-entry grid.

ENHANCEMENT: grid.ReSort() can create tags as needed


XXFWGRD.VCX/grdGeneral has been enhanced to be "smart" enough to create index tags if they don't exist the first time the user dbl-clicks on a column header for which a tag has been specified in THIS.iaColumnInfo[xx,3]. XXFWGRD.VCX grdGeneral Init() modified to increase the number of columns of .iaColumnInfo to 10 ReSort() modified to create tags if they don't exist CreateIndexTags() comments updated SetIndexTagInfo() comments updated zReadMe() comments updated

No retrofitting required

ENHANCEMENT: specify column.header attributes when ilResort=.t./ReSort()


In previous versions of VMP, the appearance of the "controlling" column.Header was hard-coded. In this enhancement, you can specify any property for the header of the "controlling" column and the "sortable" columns. See XXFWGRD.VCX/grdGeneral.SetReSortBehaviors() and SetCustomizableReSortBehaviors() for all the details. XXFWGRD.VCX grdGeneral inHeaderForeColor removed inHeaderBackColor removed iaControllingHeaderProps new iaSortableHeaderProps new Init() modified CheckColumnOrderOnInit() modified SetReSortBehaviors() new SetCustomizableReSortBehaviors() new
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 51

inLeftmostSortableColumnHeaderPropSwap new

No retrofitting required
However, if you've modified the default VMP grid behavior, you'll want to switch to using the tools included here.

ENHANCEMENT: new Grid.CommonColumnControlRightClick() method


To make it easier to code a single shortcut menu called from each column/control in a grid, the new XXFW.VCX/grdBase.CommonColumnControlRightClick() method works like the existing CommonColumnControl..() methods to provide a place to share common code. XXFW.VCX grdBase CommonColumnControlRightClick() new method, simply calls the Grid.RightClick() all ColumnX.Text1.RightClick() methods modified to call the CommonColumnControlRightClick()

No retrofitting required

MODIFICATION: new IsCurrentRowBlank() put to work in data-entry grids


The new XXFW.VCX/grdBase.IsCurrentRowBlank() method is put to work in XXFWGRD.VCX/DeleteBlankRows() method, replacing the manual code that was called. Override the grid.IsCurrentRowBlank() when your "blank row" criteria is different than that abstracted into grdBase.IsCurrentRowBlank(). XXFWGRD.VCX grdDataEntry DeleteBlankRows() -- modified

No retrofitting required

REMOTE DATA
FEATURE: New class providing connection services for remote data applications
The new cusConnectionSvc class definition in XXFWLIBS.VCX is instantiated to oLib.oConnectionSvc() by an new oApp.SetupRemoteDataServices() (even if your app uses only local data). For remote applications, you can substitute your own "connection services" object (usually a subclass of XXFWLIBS.VCX/cusConnectionSvc) by updating your APPCONFIG record for "oLib.oConnectionSvcClass". In addition to basic services via custom methods, the ODBCErrorMessage() method is a "hook" where you can fire your own ODBC-error-message routine to present messages to the user when AERROR() reports an error 1526. XXFWLIBS.VCX cusConnectionSvc new class XXFW.VCX ctrApp Init() modified SetupRemoteDataServices() new method MSGSVC.DBF New records to handle messages generated in this class see the MSGSVC.cWhere field New records to handle messages generated in oApp.SetupRemoteDataServices() see the MSGSVC.cWhere field XXFWDATA.PRG/APPCONFIG table New "oLib.oConnectionSvcClass" record specifies the ClassName,.VCXFileName of the class to be instantiated to oLib.oConnectionSvc by oApp.SetupRemoteDataServices(), defaults to "cusConnectionSvc,XXFWLIBS.VCX", no need to modify unless you want to instead instantiate a subclass of XXFWLIBS.VCX/cusConnectionSvc. XXFWDATA.PRG/APPINFO table The app-specific APPINFO table contains new records where the developer can specify (and the system administrator can maintain):

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 52

"BusyConnectionTimeout" specifies the number of seconds, on encountering a busy connection, the executing query/connection/SQL operation aborts/times out. Number of seconds after which, if a connection handle continues to be busy, the SQL operation is aborted. Defaults to 2, see also XXFWLIBS.VCX/cusConnecionSvc.BusyConnection(). "BusyConnectionRetryInterval" Interval at which to retry a busy connection. Defaults to .2 seconds. See XXFWLIBS.VCX/cusConnecionSvc.BusyConnection() "QueryAllowUserToRetryWhenBusy" -- Establishes oLib.oConnectionSvc.ilQueryAllowUserToRetryWhenBusy, used as the default value of the optional 3rd parameter of XXRQUERY() and XXSQLEXE() functions. See also XXFWLIBS.VCX/cusConnectionSvc.SetProperties() "QueryPresentErrorMessage" -- Establishes oLib.oConnectionSvc.ilQueryPresentErrorMessage, used as the default value of the optional 4th parameter of XXRQUERY() and XXSQLEXE() functions. See also XXFWLIBS.VCX/cusConnectionSvc.SetProperties() "QueryShutdownIfProblem" -- Establishes oLib.oConnectionSvc.ilQueryShutdownIfProblem, used as the default value of the optional 5th parameter of XXRQUERY() and XXSQLEXE() functions. See also XXFWLIBS.VCX/cusConnectionSvc.SetProperties() "TestConnectionSQL" -- SQL-Select statement that retrieves one-record/one-field as fast as possible, for checking valid connections in XXFWLIBS.VCX/cusConnectionSvc.TestConnection() (see the notes there for more info)

No retrofitting required

ENHANCEMENT: Additional remote data handling in forms


This enhancement adds logic to handle any combination of local data, remote data, or both, with regard to updating the data inside a transaction. It extends the existing local data implementation to include remote data seamlessly. Both remote views and SQL pass-thru (SPT) cursors are handled, as long as they're all open using the "single connection handle per user" strategy abstracted into the framework. The actual SQL UPDATEs for SPT cursor have to be handled manually, but that code can be placed in THISFORM.BeforeDefaultUpdates() (see the header comments in that shell method). When a serious connection problem occurs during the <Save> process, THISFORM.iaSaveFailureInfo[3] contains .T., precipating an application shutdown in THISFORM.SaveAction (Visual MaxFrame Professional only). XXFW.VCX frmData UpdateBuffers() modified BeginTran() modified EndTran() modified RollbackTran() modified

No retrofitting required

ENHANCEMENT: checks for a remote data connection gone bad


In this enhancement, checks for a remote data connection gone bad have been added to the framework, which, if so, result in the app being shutdown. XXFW.VCX frmData RevertBuffers() modified ctrApp ActionOnTimer() -- modified

No retrofitting required

ENHANCEMENT: oUser now accommodates a (remote) view


In a "pure" client-server app, the USERS table is likely a remote view (or maybe a SQL pass-thru cursor). These enhancements to cusUser and frmLogin make it easier to specify such via the oUser properties, as well as to override when necessary. See XXFW.VCX/cusUser.zReadMe() in the How To Implement This Class section, property listing. XXFW.VCX cusUser Init() -- modified LocateUsrPK() -- modified SetupUsersTable() -- new protected method zReadMe() -- updated frmLogin
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 53

CustomPasswordValid() -- modified

No retrofitting required

FEATURE: wrapper for SQLExec()


XXSQLEXE.PRG is a wrapper to the native VFP SQLExec() function, providing error/busy connection checking, etc. XXSQLEXE.PRG new program

No retrofitting required

FEATURE: wrapper for REQUERY()


XXRQUERY.PRG is a wrapper to the native VFP REQUERY() function, providing error/busy connection checking, etc. when the REQUERY() is to be performed on a remote view. Can be used for either local or remote views, so that one wrapper can be used for views that can be switchable between local and remote. XXRQUERY.PRG new program

No retrofitting required

ENHANCEMENT: frmDataEntry.SaveODBCMessageOnFailure() moved to oLib.oConnectionSvc


The logic for XXFWFRM.VCX/frmDataEntry.SaveODBCMessageOnFailure() has been moved to XXFWLIBS.VCX/cusConnectionSvc XXFWFRM.VCX frmDataEntry SaveODBCMessageOnFailure() removed XXFWLIBS.VCX cusConnectionSvc ODBCErrorMessage() new method

Retrofitting Instructions
If you had code in a Form.SaveODBCMessageOnFailure() method, you need to move it to XXFWLIBS.VCX/cusConnectionSvc.ODBCErrorMessage(). DO XXDTEPEM WITH "SaveODBCMessageOnFailure" to find any such explicit code.

ENHANCEMENT: cmdDataFind.Click() senses remote views


XXFWCTRL.VCX/cmdDataFind.Click() is now smart enough to sense when THISFORM.icMainAlias is a remote view, and since THISFORM.icPKField should be set in that scenario, uses available information to process the result of the call to THIS.DoTheFind(). XXFWCTRL.VCX cmdDataFind Click() -- modified

No retrofitting required

ENHANCEMENT: X3CKCHEK.PRG supports remote data via SQL Pass-Thru


X3CKCHEK.PRG can now be used for manually checking candidate key violations for either local VFP data (via a simple SQL-Select) or remote data (via SQL Pass-Thru). X3CKCHEK.PRG includes a local procedure DEMOREMOTE that you can run from the Command Window to demonstrate its usage. The primary key parameters have been modified to allow sending a .NULL. value instead of figuring out a PK value that cannot be on file. X3CKCHEK.PRG -- modified

No retrofitting required

FEATURE: VM example application includes a new Remote Data menu


Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 54

The VM example application includes a new "Remote Data" menu. If you have SQL Server running, you can use the options on this menu to connect to the sample Pubs database that ships with SQL Server and run several example forms. The forms automatically switch between local VFP data mirroring the Pubs database and the remote Pubs data. Here are the new/modified files: VMMAIN.MNX -- modified VMPUBDAT.PRG -- new VMPUBCON.SCX -- new VMDEPUBS.SCX -- new VMCONECT.PRG -- new VMREMINF.SCX -- new

No retrofitting required

ENHANCEMENT: turn off VMP generation and population of PKs and FKs
A new ilGenKeys property on XXFWFRM.VCX/frmDataEntry allows you to suppress the default VMP behavior of generating and populating primary keys (and foreign keys when the form contains cusChildCursorSvc object(s) to handle child cursors). This is primarily intended for use with remote tables whose keys are maintained in identity columns. XXFWFRM.VCX frmDataEntry ilGenKeys new public property GenAndPopPK() modified GenPK() -- modified

No retrofitting required

PRINTING and REPORTS


ENHANCEMENT: New frmReport.DeletePrinterSetupFromFRX() method
VFP hard-codes printer setup information in the Expr, Tag, and Tag2 fields of .FRXs. This new method allows you to delete that explicit printer setup information so that a report can be successfully printed to a printer other than the default printer for the current user. XXFWMISC.VCX/frmReportTextBlock.PrepareData() calls this method. XXFWMISC.VCX frmReport DeletePrinterSetupFromFRX() new method

No retrofitting required

MODIFICATION: _ASCIICOLS redefinition moved to separate method for easier customization


In previous versions, XXFWMISC.VCX/frmReport.ReportForm() included a redefinition of the system _ASCIICOLS memvar and then reset it when the report had been run. In order to use your own desired _ASCIICOLS value, you had to subclass the entire method (copy and paste, then change the _ASCIICOLS setting). In this modification, that activity has been moved to BeforeReportForm() and AfterReportForm(). See XXFWMISC.VCX/frmReport.BeforeReportForm(). XXFWMISC.VCX frmReport ReportForm() modified BeforeReportForm() modified AfterReportForm() modified iaPushPop new public property.

Retrofitting Instructions
If any of your report object classes inheriting from XXFWMISC.VCX/frmReport contain BeforeReportForm() or AfterReportForm() code, be sure you are making the manual callback to these previously-empty (at the VMP framework level) methods. DO XXDTEPEM WITH "AfterReportForm" and "BeforeReportForm" to track down any such methods in your project.

FEATURE: Default main _MSYSMENU menu Print/Print Preview options

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 55

XXFWMAIN.MNX has new default Print and Print Preview menu options under the File menu. The Command simply calls _Screen.ActiveForm.PrintAction(<parameter>), and the SKIP FOR condition calls a new oMenu.PrintSkipForCondition() custom method. Also, a call to the new oMenu.EnableFileMenuPrintItems() method has been added to frmBase.GotFocus(), so that modal forms can also have Print and Print Preview menu options enabled. XXFW.VCX cusMenu PrintSkipForCondition() new public method EnableFileMenuPrintItems() new public method frmData PrintAction() method code remains intact, but this method is now established in frmBase frmBase PrintAction() this method now established here so that all Visual MaxFrame forms have a PrintAction() method GotFocus() modified to call oMenu.EnableFileMenuPrintItems() for modal forms XXFWMAIN.MNX new File/Print menu option (see both the Command and the SKIP FOR condition) new File/Print Preview menu option (see both the Command and the SKIP FOR condition) MSGSVC.DBF Several new Print and Print Preview records

Retrofitting Instructions
No retrofitting required, although you should check the XXFW.VCX/cusMenu.PrintSkipForCondition() to see if it meets your needs if you decide to include this menu option in your applications. If you have Visual MaxFrame Professional, note that the Form.PrintAction() method now receives a parameter when called from the 2 new default menu bars if you decide to use them, you'll have to modify your existing PrintAction() methods to insert the lParameters tcOutput parameter and pass it on to the report as the 3 rd parameter (see the forms in the VM example application, VMDECUS.SCX for example). To find all your forms that have explicit PrintAction() code, DO XXDTEPEM WITH "PrintAction".

ENHANCEMENT: 3rd parameter to frmReport.Init() now accepts "PREVIEW"


You can now pass the 3rd parameter to VMP report objects as "PREVIEW", which is the same as passing "SCREEN". XXFWMISC.VCX frmReport SeticDestination() modified GetDestinationClause() modified

No retrofitting required

MODIFICATION: ReportCatalog.Rep_Class field now C(100)


The ReportCatalog.Rep_Class field is now created with a size of C(100) instead of the C(40) used in previous versions of VMP because a report class name plus .VCX can easily exceed 40 characters. XXFWDATA.PRG -- modified

Retrofitting Instructions
No retrofitting is required to existing apps unless, of course, you have report objects whose class name plus .VCX filename exceeds the previous default of 40 characters for the Rep_Class field.

LIBRARY ROUTINES and OBJECTS


NEW LIBRARY ROUTINE: lock/unlock _Screen
X3LCKSCR.PRG does for _Screen what LockScreen does for VFP forms. X3LCKSCR.PRG new file

No retrofitting required

FEATURE: New X3GOURL.PRG routine to fire the web browser, pointing to a passed URL
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 56

X3GOURL.PRG is the utility Rick Strahl published in his article in the March 1998 FoxPro Advisor Magazine. It fires up the web browser (or other associated application) for the passed URL/file. It is demonstrated in the VM example application in the Help menu, which contains an option for www.maxlink.com/vmpmain.htm. X3GOURL.PRG new program VMMAIN.MPR new www.maxlink.com/vmpmain.htm option on the Help menu

No retrofitting required

FEATURE: new XXSYNCPK.PRG utility


XXSYNCPK.PRG is a new library routine that allows you to easily synchronize your GeneratePK.GPK_CurrentNumber/GPK_CurrentAlpha to the current highest PK for each table. XXSYNCPK.PRG is used/called in VMDVPOP.PRG in the VM example application \DVSTUFF directory. XXSYNCPK.PRG new file

No retrofitting required

FEATURE: MousePointer/HourGlass management


The MousePointer is set to an hourglass in several appropriate situations (and set back to its previous value when the activity is complete). You can use the new cusPushPopMousePointer class to push/pop the _Screen.MousePointer and _Screen.Activeform.MousePointer (if there is an _Screen.Activeform), and optionally set both to 11-Hourglass while the cusPushPopMousePointer object exists. XXFW.VCX frmData MovePointer() -- modified XXFWFRM.VCX frmStandby iaMousePointers new protected property Init() modified Destroy() -- modified frmThermoBar iaMousePointers new protected property Init() modified Destroy() modified frmDataEntry AddAction() modified CancelAction() -- modified DeleteAction() modified SaveAction() modified XXFWGRD.VCX grdDataEntry AddRow() modified DeleteAllRows() -- modified XXFWCOMP.VCX ctrMover Click() all 4 commandbuttons -- modified XXFWPPOP.VCX cusPushPopMousePointers new class X3MSGSVC.PRG -- modified X3WINMSG.PRG -- modified X3WRPFRM.PRG -- modified

No retrofitting required

FEATURE: oLib.oDBCSvc.OpenTable() faster to open tables, NODATA views

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 57

XXFWLIBS.VCX/cusDBCSvc.OpenTable() has been modified to SET DELETED OFF and SET OPTIMIZE OFF before opening tables and NODATA views. This speeds up: 1. opening a table, especially noticeable when tables contain large numbers of records and any number of deleted() records 2. opening a (local) view NODATA XXFWLIBS.VCX cusDBCSvc OpenTable() modified

No retrofitting required

ENHANCEMENT: performance enhancement to X2JSTFIL.PRG


A minor modification to X2JSTFIL.PRG when checking for FOXTOOLS.FLL being loaded makes it much faster in VFP 5.0 apps (in VFP 6.0, X2JSTFIL.PRG doesn't bother with FOXTOOLS.FLL, since the FOXTOOLS functions used by X2JSTFIL have been incorporated into native VFP in version 6.0). Methods/.PRGs that call X2JSTFIL.PRG are therefore faster, one place in particular is oLib.oDBCSvc.OpenTable(). The same modification has been applied to X2WEXIST.PRG, for the same reason, but the performance implications are minimal, since X2WEXIST.PRG is rarely called. X2JSTFIL.PRG -- modified

No retrofitting required

ENHANCEMENT: X3GETVER.PRG removed


All references to X3GETVER.PRG have been removed from the VMP framework (and the Visual MaxFrame Professional VM Example Application) because starting in VFP 5.0, we recommend checking the current running version directly:
lnVersion = int(val(leftc(_VFP.Version,1))) IF lnVersion < 6 * VFP 5.0 code ELSE * VFP 6.0 or better code ENDIF lcVersion = _VFP.Version IF lcVersion = "5" * VFP 5.0 code ELSE * VFP 6.0 or better code ENDIF

or

X3GETVER.PRG -- removed

Retrofitting Instructions
No retrofitting required unless you've got X3GETVER() calls in your app-specific code, in which case you'll need to modify them as indicated above. DO XXDTSRCH WITH "X3GETVER" to find any such calls.

FEATURE: new cusPushPopSQLThermo class


The new XXFWPPOP.VCX/cusPushPopSQLThermo class allows wrapping a SQL-Select statement inside a push/pop object that SETs TALK ON and TO a hidden window, displaying the native VFP "Running query" thermometer status bar. XXFWPPOP.VCX cusPushPopSQLThermo new class

No retrofitting required

ENHANCEMENT: cusPushPopSetTo now handles multiple-value SET commands


XXFWPPOP.VCX/cusPushPopSetTo has been enhanced to receive a 2nd parameter used when the SET command has multiple values and you want to Push/Pop one of those values (ie DATE, MESSAGE, ALTERNATE, etc). XXFW.VCX cusPushPopSetTo Init() modified

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 58

Destroy() modified zReadMe() -- modified

No retrofitting required

ENHANCEMENT: XXFWPPOP.VCX/cusPushPopOn supports OKLs


XXFWPPOP.VCX has been enhanced to push/pop ON KEY LABELs. XXFWPPOP.VCX cusPushPopOn Init() modified to accept a 2nd optional parameter, process it Destroy() modified to process the possible OKL value zReadMe() updated instructions

No retrofitting required

FEATURE: New oLib.GetTempDir() method


oLib now has a public GetTempDir() method, which returns the directory where VFP is currently creating temporary files like view cursors, CREATE CURSOR cursors, etc. XXFW.VCX cusAppLibs GetTempDir() new method

No retrofitting required

ENHANCEMENT: oLib.oDBCSvc.OpenTable() now handles both local and remote views


Opening a table is very similar to opening a view, and XXFWLIBS.VCX/cusDBCSvc has been enhanced to also open local and remote views. XXFWLIBS.VCX cusDBCSvc OpenTable() -- modified

No retrofitting required

ENHANCEMENT: oLib.oDBCSvc.OpenTable() handles views that are USEd AGAIN ALIAS


An earlier VMP 4.0 enhancement allowed opening views via calls to oLib.oDBCSvc.OpenTable(), but did not allow specifying an ALIAS (4th parameter). In this enhancement, the ALIAS clause is supported for views. However, note the comments in the OpenTable() method for the tcAlias/tlGetData parameters if tcAlias is passed, then tlGetData is explicitly set to .F. because when you ask VFP to USE a view AGAIN ALIAS <Whatever>, it simply creates a copy of the already-open view, complete with its records. To USE a view AGAIN ALIAS <Whatever> properly, you have to open the view NODATA and then REQUERY() it. XXFWLIBS.VCX cusDBCSvc OpenTable() modified

No retrofitting required

MODIFICATION: buffer mode established for tables/views opened via cusDBCSvc.OpenTable()


VMP expects that, when USEing a table, no buffering be enabled. However, when SET RESOURCE is ON (usually only in development), VFP respects the setting you've made in the Buffering option of the Data tab of the VFP Tools/Options dialog. For this reason, we strongly recommend setting that option to Off! However, since we can't guarantee that's the case, this modification enforces no buffering for tables opened via cusDBCSvc.OpenTable() and optimistic table buffering for tables opened via cusDBCSvc.OpenTable(). XXFWLIBS.VCX cusDBCSvc OpenTable() modified SetBuffering() new protected method

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 59

inBufferMode_Table new public property inBufferMode_View new public property

Retrofitting instuctions
Since views opened via the OpenTable() method (of oLib.oDBCSvc or an instance of cusDBCSvc added to a form) are now open with optimistic table buffering, if you immediately create index tag(s) without setting buffering to 3 to create the tags and then to 5 afterwards, you will have to update your code to do so. Otherwise, your INDEX ON command(s) will fail due to table buffering in effect rather than row buffering.

ENHANCEMENT: foreground memory allocation/SYS(3050,1,<ExpN>)


In this performance enhancement, X3FBMEM.PRG (many thanks to Gary DeWitt) is called from various places in the framework, to keep foreground buffer memory allocation constantly updated. X3FBMEM.PRG new file XXFWMAIN.PRG -- modified XXFW.VCX frmBase Load() -- modified

No retrofitting required

ENHANCEMENT: X3CSVORT.PRG replacement


X3CSVORT.PRG has been replaced by X3SRCTYP.PRG, which executes a similar function, but returns more useful information about the alias of the passed item. X3CSVORT.PRG -- deleted from VMP X3SRCTYP.PRG -- new program X3VVALID.PRG modified X3PKTAG.PRG modified XXFWGRD.VCX grdDataEntry UpdateAddOnTheFlyAlias() modified XXFWCTRL.VCX cmdDataSave UpdateAddOnTheFlyAlias() modified CheckRequiredFields() -- modified

Retrofitting Instructions
X3CSVORT.PRG only returned one of the following values: "T" "R" "L" SPACE(0) but X3SRCTYP.PRG returns one of the following: "VR" "VL" "OVR" "OVL" "TC" "TF" "SPT" "C" The calls to X3CSVORT.PRG in the framework have been updated, but retrofitting of existing apps requires checking all existing X3CSVORT.PRG calls to make sure they check for the correct new value(s). Hunt down possible retrofits by Doing XXDTSRCH WITH "X3CSVORT".

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 60

ENHANCEMENT: X2CNVCHR.PRG is slightly faster


X2CNVCHR.PRG has been modified to make it slightly faster when asking it to convert a passed value to a character string. X2CNVCHR.PRG -- modified

No retrofitting required

ENHANCEMENT: new X2PSTACK.PRG library routine


X2PSTACK.PRG is a new library routine that allows you to check whether a specific .PRG/method is in the SYS(16) program execution stack. You can optionally pass an array of .PRGs/methods, and a second parameter to indicate whether X2PSTACK RETURNs .T. if any or all strings are in the SYS(16) program execution stack. Several Visual MaxFrame Professional methods call this routine. X2PSTACK.PRG -- new program

ENHANCEMENT: X3STDBY.PRG allows you to specify the form class/VCX


X3STDBY.PRG receives two additional and optional parameters allowing you to specify an .ICO to display and the form class plus .VCX to use as the "standby" form. If no .ICO is passed and no oApp.GetAppInfo("IconFile") is specified, if there is an _Screen.Icon, it is used. X3STDBY.PRG -- modified XXFWFRM.VCX frmStandby Init() -- modified

No retrofitting required

ENHANCEMENT: X3CPEDIG.PRG runs faster


X3CPEDIG.PRG has been modified to push/pop SET EXACT manually, eliminating the need for X3FWPPOP.VCX and making it run faster. X3CPEDIG.PRG -- modified

No retrofitting required

ENHANCEMENT: new X3ISFLD.PRG library routine


text X3ISFLD.PRG new file XXFWFRM.VCX frmDataEntry GenAndPopPK() -- modified

No retrofitting required

ENHANCEMENT: new X2RELXPR.PRG routine


The new X2RELXPR.PRG combines two functions in one library routine. By RETURNING the relational expression for the RELATION SET between a passed "parent alias" and a passed "child alias", it answers the question "Is there a relation in effect between the parent/child?" (the value RETURNed is an empty character string). If there is a relation in effect between the two aliases, it RETURNs the relational expression. By passing the optional 3 rd parameter as .T., the relation expression RETURNed has the parent ALIAS() inserted before each field name, suitable for use in FOR clauses. X2RELXPR.PRG new library routine XXFWGRD.VCX grdDataEntry Refresh() -- modified

No retrofitting required

ENHANCEMENT: new X3VTABLE.PRG


X3VTABLE.PRG is similar to but different from X3BTABLE.PRG.
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 61

XXFWCTRL.VCX/cmdDataSave.UpdateAddOnTheFlyRecord() has been updated, and the revised code includes a call to X3VTABLE.PRG. X3VTABLE.PRG new file XXFWCTRL.VCX cmdDataSave UpdateAddOnTheFlyRecord() -- modified

No retrofitting required

FEATURE: new X3DBCSWP.PRG library routine


Similar to X3DBCPTH.PRG, X3DBCSWP.PRG allows you to swap out an entire Database property for .SCX-based forms' DataEnvironment.Cursor objects. X3DBCSWP.PRG -- new file

No retrofitting required

MODIFICATION: specify EXCLUSIVE/SHARED for both the database and tables in XXFWLIBS.VCX/cusDBCSvc.OpenData()
Starting in VFP 5.0, you don't have to have a database open EXCLUSIVE to peform maintenance chores on its tables. So this modification allows you to pass the optional 3 rd parameter to oLib.oDBCSvc.OpenData() as a string containing two logical values, one for the database and one for the tables to be opened if tlDataOnly is .F. XXFWLIBS.VCX cusDBCSvc OpenData() -- modified

No retrofitting required

ENHANCEMENT: cusReindex doesn't close views


XXFWMISC.VCX/cusReindex has been enhanced to close contained tables explicitly, not by issuing a CLOSE DATABASE. This has the distinct advantage of leaving views alone; in VMP 3.01, all views contained in the database whose tables were to be reindexed were closed and left closed. In order to accomplish this, two new criteria must be met when calling cusReindex.ReindexData(): 1. the database passed to ReindexData() must be open 2. the database passed to ReindexData() MUST NOT be open for EXCLUSIVE use unless the database has no native VFP RI-Builder-maintained referential integrity. If any of the RIIINFO fields in the .DBC for the relations are populated and the database is open EXCLUSIVE when calling ReindexData(), it will fail gracefully and RETURN .F. DO XXDTSRCH WITH ".ReindexData(" to find any existing calls to the .ReindexData() method, and make sure both these new criteria are met. XXFWMISC.VCX cusReindex ReindexData() modified SaveTableStates() modified RestoreTableStates() modified

Retrofitting Instructions
See the description for this enhancement.

FEATURE: new cusPushPopWorkAreas class definition


XXFWPPOP.VCX/cusPushPopWorkAreas is a new class definition that allows you to save/restore the condition of all tables and non-parameterized views, even opening them if they are closed when the Destroy() does its "pop"ping. XXFWPPOP.VCX cusPushPopWorkAreas new class

No retrofitting required

FEATURE: new X3RLB.PRG

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 62

X3RLB.PRG is a library routine to Refresh Local Buffer of the passed alias. In some situations you may find it necessary to manually refresh the local buffer of a VFP table so that a subsequent SQL-SELECT or USE <ViewName> gets the latest information on disk rather than what VFP has currently buffered on the current workstation. XXRLB.PRG new file

No retrofitting required

DEVELOPER TOOLS
ENHANCEMENT: A.PRG/DrillDown() hotkey
A.PRG contains a local DrillDown procedure that makes it easier to execute the Select/Rightclick/<select Edit> action to drill down into containers like pageframes. It is fired on an {F3} ON KEY LABEL. If you have Visual MaxFrame Professional, try the following to see the most impressive part of this feature (assuming you've run A.PRG to setup the {F3} hotkey): 1. MODI FORM VMDECUS4 2. position the mouse over the Tab/Caption of any page other than the showing Page1 3. {F3} A.PRG -- modified DrillDown() new local procedure

No retrofitting required

ENHANCEMENT: A.PRG issues SET STRICTDATE TO 2


For those of you who use A.PRG and run under VFP 6.0, the SetupStuff local procedure in A.PRG issues a SET STRICTDATE TO 2, to use the strictest ambiguous date checking in the development environment. A.PRG local procedure SetupStuff -- modified

No retrofitting required
unless you don't like that setting, in which case you should take the necessary action in ASETUP.PRG or whatever

ENHANCEMENT: XXDTSRCH enhancements, primarily to allow Modify


The XXDTSRCH text search utility has been significantly enhanced, mostly to allow you to modify found items in the appropriate editor (.PRG editor, Class Designer, Form Designer, Menu Designer, etc.). Here are all the enhancements: <Modify> or Rightclick/Modify fires the appropriate editor for the selected file/class, appropriate text selected Bitmaps quickly identify the file type Files are sorted alphabetically within each file type Shortcut menu from the listbox .QPR queries are handled Tooltips added for several key controls X3TOOLS.VCX frsTextSearch modifications too numerous to list

No retrofitting required

ENHANCEMENT: XXDTSRCH finds more strings, fires the Class Browser, etc.
The XXDTSRCH tool now finds the specified string in the following locations not previously checked: description for a .VCX file description for an individual class library in a .VCX file any field in APPINFO, when the VMP-required .DBC is in the project (recommended) any field in APPCONFIG, when the xxCONFIG.DBF is in the project (recommended)

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 63

any field in GENERATEPK when the VMP-required .DBC is in the project and it includes a GENERATEPK table any field in REPORTCATALOG when the VMP-required .DBC is in the project and it includes a REPORTCATALOG table any field in xxUSYSSI.DBF, when it exists and is in the project (recommended part of the Visual MaxFrame Professional optional user security system) any field in MSGSVC.DBF, when it is in the project (recommended) any field in STRINGS.DBF, when used and when it is in the project Free tables that are in the project but are not in the above list are listed in the listbox to indicate that they are in the project but have not been "processed", or checked for the passed string. When focus is on a line for a .VCX file or the description for a .VCX file, the first shortcut menu bar/<Modify> button selection loads that .VCX in the Class Browser. When focus is on a line for a .DBF item, the first shortcut menu bar/<Modify> button BROWSEs that table, and if the selected listbox line is for an individual/specific record in the table, the BROWSE is presented with that record selected. The dialog contains two new checkboxes for specifying options for the search string: Match case? Alltrim() the string?

No retrofitting required

ENHANCEMENT: XXDTSRCH/text search checks property/method descriptions


Until now, DO XXDTSRCH did not find occurrences of the specified string in the description text of PEMs. Now it does. X3TOOLS.VCX frsTextSearch ProcessSCXVCX() -- modified

No retrofitting required

ENHANCEMENT: XXDTSRCH/XXDTEPEM now support <Print>ing the results


XXDTSRCH and XXDTEPEM developer tools now contains a <Print> button and shortcut menu option, allowing you to print the results. XXTOOLS.VCX frsTextSearch cmdPrint.Click() new member, new method

No retrofitting required

ENHANCEMENT: incorporation of Ken Levy's latest SuperCls tool


VMP now ships with a modified version of Key Levy's SuperCls public domain utility. Only one file ships, SUPERCLS.APP, which is the latest SuperCls from Ken Levy plus an extra (rightmost) commandbutton that summons all inherited code for the current method, all the way up the class inheritance hierarchy. The single SUPERCLS.APP works in both VFP 5.0 and VFP 6.0. XXTOOLS.VCX cmdInheritedCode This class used to be in the VMP-modified SuperCls.

Retrofitting Instructions
You can delete all SuperCls*.* files in your \XLIB directory, using the old VMP 3.0 setup, replacing them all with the single SUPERCLS.APP that ships with VMP 4.0. Or, the SUPERCLS.APP that ships with VMP 4.0 can be anywhere in your VFP path (if you want the VMP-modified SuperCls, then don't include the SuperCls directly from Ken Levy in your VFP path).

ENHANCEMENT: syntax coloring, etc. for the VMP SuperCls button


The VMP-specific extra (rightmost) button on the SuperCls toolbar has been enhanced to present the inherited code in a .PRG file rather than a MODI MEMO window, so that it is displayed with syntax coloring. And the generated INHERIT.PRG is not erased, so it is left on disk for manipulation later, if desired. XXTOOLS.VCX
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 64

cmdInheritedCode Click() -- modified

No retrofitting required

ENHANCEMENT: XXDTNEWF enhanced to include a dialog


XXDTNEWF no longer accepts the parameters it did before, but rather sends you to a dialog from which to specify the .SCX filename and optional Class/VCX. In VFP 6.0, the ellipsis button summons the new AGETCLASS() dialog for class selection. You can pass one optional parameter specifying your own subclass of frmXXDTNEWF, with extra features you've added to do your own stuff. XXTOOLS.VCX frmBaseTools new class frmXXDTNEWF new class XXDTNEWF.PRG -- modified

No retrofitting required

ENHANCEMENT: XXDTNEWF.PRG adds the DataEnvironment.BeforeOpenTables() line of code


When you press the <OK> button in the XXDTNEWF.PRG dialog, if the form you're about to create inherits from XXFW.VCX/frmData, the call to THISFORM.DEBeforeOpenTables() in the form's DataEnvironment.DEBeforeOpenTables() is added when the new form is created. XXDTNEWF.PRG -- modified XXTOOLS.VCX frmXXDTNEWF OKAction() -- modified

No retrofitting required

FEATURE: new tool class to update class/form PEMs programmatically


Check out the zReadMe regarding usage. XXTOOLS.VCX cusPEMTool new tool

No retrofitting required

MODIFICATION: XXWB.VCX "base" classes renamed


The "xxxBase" classes in XXWB.VCX have been renamed to "xxxWBBase" to remove ambiguity between them and the "xxxBase" classes in XXFW.VCX. Sometimes VFP gets confused regarding which .VCX it is "pointing" to and can redefine an XXWB.VCX/xxxBase component to an XXFW.VCX/xxxBase class.

Retrofitting Instructions
If you've used any XXWB.VCX "xxxBase" classes in your own tools/wizards/builders/etc., you'll have to redefine any that inherit from XXWB.VCX/"xxxBase" classes. Don't forget methods with scope resolution operator callbacks: xxxBase::Callback() xxxWBBase::Callback().

ENHANCEMENT: Explicit PEM developer tool enhanced, mostly to allow Modify


The XXDEPEM utility that allows searching the files in a project for objects with an explicit PEM setting (bold in the Properties Sheet) inherits from XXDTSRCH (XXTOOLS.VCX/frsTextSearch) and has therefore been enhanced to provide the same new features as that tool (see item above), where appropriate: <Modify> or Rightclick/Modify fires the appropriate editor for the selected file/class, if a method has been specified, the cursor is positioned in it Bitmaps quickly identify the file type Files are sorted alphabetically within each file type Shortcut menu from the listbox Tooltips added for several key controls
Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions VM4UPGRD.DOC

Page 65

XXTOOLS.VCX frsExplicitPEM modifications too numerous to list

No retrofitting required

ENHANCEMENT: Hacking tool allows font/size flexibility


The VMP "hacking" tool XXDTHACK (XXTOOLS.VCX/frmHackSV) has been enhanced to make it more useful in highresolution/presentation situations: A shortcut menu has been added on Form.RightClick() the shortcut menu allows you to toggle the FontBold property of all form members, useful when making a presentation in front of a group to make the tool more readable to the audience When running in high resolution, the form/tool and its members are enlarged to take advantage of the increased real estate; the shortcut menu allows toggling between the two predetermined form sizes XXTOOLS.VCX frmHackSV several modifications

No retrofitting required

ENHANCEMENT: XXDTPOPC.PRG utility handles .NULL.s, better support for large numbers of output files, unambiguous date constants
The XXTOOLS.VCX/cusCreatePopCode utility called by DOing XXDTPOPC has been enhanced to: handle .NULL. field values properly not "chain" together the programs, but rather call them all in a loop at the end of the first one create unambiguous date/datetime constants XXTOOLS.VCX cusCreatePopCode Init() modified NoCRLF() -- modified

No retrofitting required

ENHANCEMENT: XXDTPOPC.PRG utility supports free tables


XXDTPOPC.PRG/XXTOOLS.VCX/cusCreatePopCode now supports free tables. XXTOOLS.VCX cusCreatePopCode Init() modified XXDTPOPC.PRG -- modified

No retrofitting required

ENHANCEMENT: XXDTPOPC.PRG utility calls a dialog where you can enter information passed as parameters to XXTOOLS.VCX/cusCreatePopCode
XXDTPOPC.PRG now instantiates a dialog where you can easily enter information passed to XXTOOLS.VCX/cusCreatePopCode. XXTOOLS.VCX frmXXDTPOPC new class XXDTPOPC.PRG -- modified

No retrofitting required

FEATURE: new XXDTHIER.PRG developer tool


XXDTHIER.PRG is a new developer tool that prints out class hierarchies. XXDTHIER.PRG new

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 66

No retrofitting required

MISCELLANEOUS
MODIFICATION: no VFP 3.0b support
Starting with VMP v4.0, VFP 3.0b is no longer supported. If your applications must run in VFP 3.0b, use VMP 3.01. In addition to the fact that VFP 3.0b-specific code has been removed from various .PRGs and method code, the following other files have been affected: X3BLDTXT.SCX -- deleted XXBUILDR.PRG -- modified VMP3TO5.PRG deleted XXFW.VCX/frmBase.SetAllSelectedBackColor() -- deleted

No retrofitting required

ENHANCEMENT: ERRORLOG.DBF table PACKed/ZAPped automatically


A new XXFWLIBS.VCX/cusDBCSvc.PackTable() method is called from oApp.ReindexTables() and frmEventLog.cmdOK.Click() to "automatically" attempt to PACK (or ZAP, if all records have been deleted) the ERRORLOG.DBF free table, which can bloat significantly. XXFWLIBS.VCX cusDBCSvc PackTable() new method XXFW.VCX ctrApp ReindexTables() modified XXFWFRM.VCX frmEventLog cmdOK.Click() -- modified

No retrofitting required

MODIFICATION: Default Properties Sheet setting for custom character properties


All VMP custom properties are set to some default in the Properties Sheet. For character properties, this has been "=space(0)" in previous versions of VMP. However, custom builders/wizards can't set an expression-based property to a literal value, so all custom VMP properties of character data type that are simply initialized to an empty string in the Properties Sheet are instead set by entering a single space, which VFP converts to an empty string and displays "(None)" in bold text in the Properties Sheet. This modification affects all Visual MaxFrame Professional visual class libraries.

No retrofitting required

ENHANCEMENT: MSGSVC.PRG enhancements


The Public Domain MSGSVC.PRG that ships with VMP contains two enhancements. Buttons are made wider so that they better imitate standard message dialogs like MESSAGEBOX(). If MSGSVC.cBell = "Y" or "Yes" or "y" or "yes", the bell rings as the MSGSVC dialog is presented.

No retrofitting required

MODIFICATION: removed custom ilVM property, made icSubclassingPotential public


The custom ilVM property has been removed from all Visual MaxFrame base classes, and the custom icSubclassingPotential made to do double duty. All the existing checks for type("ilVM") have been replaced with checks for type(" icSubclassingPotential"), and the custom icSubclassingPotential property of each Visual MaxFrame base class has been changed from protected to public scope.

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 67

The note in XXFW.VCX/ctrApp.zReadMe() that explains icSubclassingPotential now adds a paragraph explaining that you can use icSubclasslingPotential as a "temporary property" at runtime, to store anything you want, because its value is never queried in the framework, only its existence . XXFW.VCX all xxxBase classes ilVM removed icSubclasslingPotential changed to public scope

Retrofitting Instructions
If you have any explicit code that references the removed ilVM property, you'll have to change those references to icSubclassingPotential instead. DO XXDTSRCH WITH "ilVM" to find any such references.

ENHANCEMENT: optional ERRORLOG.DBF memo fields


Five of the memo fields in the ERRORLOG.DBF are now optional (see XXERROR.PRG header comments). This allows you to delete any or all these memo fields when your app goes into heavy system testing by the QA team, keeping your ERRORLOG.FPT from getting very large very quickly, full of information you likely don't need during that testing phase. Then, when your app goes into production, you can delete the ERRORLOG.DBF table and let XXFW.VCX/cusInstallErrorHandler create a new one from scratch, including all fields. XXERROR.PRG -- modified XXFW.VCX cusInstallErrorHandler ErrorLogExists() comments updated

No retrofitting required

MODIFICATION: Localize() method established in cusBase


Several XXFW.VCX/cus.. classes had a Localize() method; this modification establishes a Localize() method at the cusBase level. XXFW.VCX cusBase Localize() new public method

No retrofitting required

ENHANCEMENT: better augmentation of a hooked RightClick


All the XXFW.VCX "base" classes that have a RightClick event method contain modified RightClick code that makes it easier to subclass. XXFW.VCX xxxBase RightClick() -- modified

No retrofitting required

ENHANCEMENT: performance enhancement on LOCATEs


Our informal testing shows that non-Rushmore-optimizable LOCATE commands are about 6% faster if the NOOPTIMIZE keyword is added to the LOCATE command. NOOPTIMIZE apparently prevents VFP from spending the time necessary to determine that the FOR clause is not optimizable. Qualifying LOCATEs throughout Visual MaxFrame and Visual MaxFrame Professional have been NOOPTIMIZEd.

No retrofitting required

FEATURE: Classy Components' QBF examples


The VM Example Application now contains VMDECUSQ.SCX and VMDECUSR.SCX, examples of the QBF Builder from Classy Components, a 3rd Party Tool. Both forms are available from the File/(Customers) variations menu. However, beware: if you don't have QBF.VCX installed, the forms will crash on instantiation if you do have QBF.VCX installed, the first time you run/modify either form, you'll have to <Locate> QBF.VCX if it's not in your VFP path

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 68

VMDECUSQ.SCX new form example VMDECUSR.SCX new form example VMMAIN.MNX -- modified

No retrofitting required

ENHANCEMENT: view manager LoadViews() accepts an optional parameter to specify view(s)


XXFWMISC.VCX/ctrViewMgr.LoadViews() has been modified to accept a parameter allowing you to specify a single view name or one-dimensional array of view names to load, rather than the default of loading all views in THISFORM's data session. XXFWMISC.VCX ctrViewMgr LoadViews() -- modified

No retrofitting required

ENHANCEMENT: view manager can handle expression-based view parameters


The view manager XXFWMISC.VCX/ctrViewMgr.iaParms array formerly only handled explicit values in column 3, but this enhancement adds a 4th optional column, which, when set to .T., indicates that the string in column 3 is an expression to be evaluated. XXFWMISC.VCX ctrViewMgr many methods modified iaParms changed scope from Protected to Public iaViews changed scope from Protected to Public

No retrofitting required

ENHANCEMENT: view manager iaParms array adds user-defined columns


The total number of XXFWMISC.VCX/ctrViewMgr.iaParms columns has been expanded to 10, columns 5-10 being unused by VMP and can be used for whatever you find a need. See XXFWMISC.VCX/ctrViewMgr.SetViewParameter() header comments. XXFWMISC.VCX ctrViewMgr several methods modified

No retrofitting required

ENHANCEMENT: utility to build/rebuild the VM.PJX project


The \VM\DVSTUFF directory/folder in the VM example application contains a new VMBLDPJX.PRG, to build/rebuild the VM.PJX project. VMBLDPJX.PRG new utility file

No retrofitting required

ENHANCEMENT: utility to switch the VM example app to run with/without the optional VMP user security system
The \VM\DVSTUFF directory/folder in the VM example application contains a new VMDVOSEC.PRG, to switch the VM example app to run with/without the optional VMP user security system. Just DO VMDVOSEC. VMDVOSEC.PRG new utility file

No retrofitting required

MODIFICATION: Size of USERPREFS.Prf_ItemValue increased


XXFWDATA.PRG increases the size of UserPrefs.Prf_ItemVal from C(100) to C(254). XXFWDATA.PRG

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 69

Retrofitting instructions
For existing apps, increase the size of UserPrefs.Prf_ItemVal from C(100) to C(254).

ENHANCEMENT: icMainAlias not required


Data-entry forms no longer require that icMainAlias be filled in. This makes it easier to create prototype/mock-up forms that run standalone or in the app context create forms that don't use VFP cursors as RecordSource/ControlSource (for example, Object.Property as ControlSource, although there are numerous other issues that have to be addressed in this scenario, usually requiring that you either override the "..Action()" methods of frmDataEntry and/or substitute your own "data-manager" object(s), called from the frmDataEntry "..Action()" methods. The modifications are too numerous to list individually here.

No retrofitting required

ENHANCEMENT: pass "Preview" to frmReportDestinationSPF


XXFWFRM.VCX/frmReportDestinationSPF.Init() has been modified so you can pass "V" instead of "S", forcing the "Screen" caption to "Preview", when passing the 3rd parameter explicitly. XXFWFRM.VCX frmReportDestinationSPF Init() -- modified

No retrofitting required

ENHANCEMENT: selection criteria objects handle BETWEEN


XXFWMISC.VCX/cusSelCriteria selection criteria objects can now generate a pair low range and high range view parameters (or SQL/FILTER BETWEEN clause) from a single selection criteria control. This allows presenting the user with a single control which, if they leave blank, indicates no filtering should take place, and if they enter a value, the records retrieved are filtered by that value. An "all or one" proposition. XXFWMISC.VCX cusSelCriteria cusSelCriteria() modified zReadMe() modified to explain this enhancement in a new section towards the end iuLowRangeValueIfLeftEmptyOrNull iuHighRangeValueIfLeftEmptyOrNull icHighRangeViewParameter

No retrofitting required

ENHANCEMENT: run developer-specific code after a VMP app finishes


The final code run by XXFWMAIN.PRG calls a file PostVMAp.PRG, if that file exists and the app is running in development. This allows you to run some standard code after a VMP app terminates, usually to customize the development environment. XXFWMAIN.PRG modified

No retrofitting required

ENHANCEMENT: display progress in OpenAllTables()


When tables are being opened in oLib.oDBCSvc.OpenAllTables(), the optional tlSayTables parameter is processed to display a thermometer status bar to the user. Before, this parameter was ignored in native VMP code, but passed on to SDT when it is installed. Now you get an informational display to the user, no matter which. XXFWFRM.VCX frmThermobar inMaxIterations changed from Protected scope to Public scope XXFWLIBS.VCX cusDBCSvc OpenData() modified to not ignore the tlSayTables parameter OpenAllTables() modified to not ignore the tlDisplay parameter

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 70

XXFW.VCX ctrApp SetupTables() modified to receive an optional 2nd tlDisplay parameter

No retrofitting required

ENHANCEMENT: Date/DateTime formatting option for remote data


When selection criteria objects are used to generate a string for use in SQL Pass-Thru (SPT), this enhancement allows you to set the new ilRemoteDTFormat property to .T., generating dates/datetimes without the native VFP {^YYYY-MM-DD} format that is not recognized by back-end databases. XXFWMISC.VCX cusSelCriteria ilRemoteDTFormat new property SelCriteria() -- modified

No retrofitting required

FEATURE: ENHANCEMENT: MODIFICATION:


text here FILENAME.VCX xxxClassName PEMName -- modified

No retrofitting required

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 71

Retrofitting Instructions
text here

Visual MaxFrame Revision History, version 4.0 1998-1999 Metamor Industry Solutions

VM4UPGRD.DOC

Page 72

Das könnte Ihnen auch gefallen