VFPUtils Article By: M. Asherman

  | Bottom | Unframe | Help |

Saver Development Tasks

Locate in Contents | (framed)

Locate in Discussion | (framed) 

Date Done
(not done)
use new Commander argument to simplify state-saving logic
Make use of the new abort-to-depth argument of Commander's CMDRM_AddFuncStep method to simplify the logic in SVM_Save methods.  Previously, the state-saving logic in the SVM_Save method of each Saver class was comprised of a serious of steps like this:

IF NOT this.svp_commander.CMDRM_AddFuncStep(this.svp_funcid, ;
  18, "m.cmdr_arg1.windowstate=" + ltrim(str(this.windowstate)))
    RETURN .F.

By using the new Commander argument, we can eliminate the surrounding IF ... ENDIF and RETURN .F., substituting the following equivalent single command line:

this.svp_commander.CMDRM_AddFuncStep(this.svp_funcid, ;
  18, "m.cmdr_arg1.windowstate=" + ltrim(str(this.windowstate)), -1)

Note that similar substitutions could also be made in all Saver-based applications (e.g. XFormDBF & BTCrit).  Since the bulk of application-specific Saver logic resides in SVM_Save methods, and these consist almost entirely of sequences like the one illustrated above, this change would be a major simplification.  Most importantly, SVM_Save methods would become much more compact, simpler to understand, and easier to maintain.  The effect of this change on performance would probably be negligible.

(not done)
fix problems in resizing behavior of the Switch To... dialog
There are a a some intermittent problems that occur when resizing the Saver dialog for picking a configuration:
  • gaps may appear in the listbox of available configs
  • gray areas may appear at edges of the editbox

These somewhat bizarre effects seem related to rapid mouse movement, and the problem is correctable by slowly resizing the dialog a bit more.  While this behavior may be due to a VFP bug, it's possible that a little additional refreshing logic could eliminate the problem altogether.

Another resizing issue that could be handled better is the possibility of shrinking the dialog to the point where the splitter bar is obscured from view, or the listbox's scroll bar is not completely visible, or pushbuttons get too crowded, etc.  These problems should be fixed by enforcing minimum dialog height and width properly.  It might also be useful to support proportional resizing, at least as an option, for the splittable portion of the dialog (listbox/editbox).

Nadya mentioned noticing problems resizing the Pick Configuration dialog in her posting of 3/28/01, but she didn't give any specific details.  (Reproducible test cases would be very helpful.)

(not done)
grid-based implementation of list in the Switch To... dialog
Use a Grid instead of the present Listbox-based design for presenting the list of available configurations to Switch To.  This would avoid a number of listbox limitations and problems with large lists.  Grids are more robust, provide much greater programming flexibility, and would immediately add such useful features as movable and resizable columns.  (Also see similar task xfma0077: switch from listbox to grid-based mappings on the Fields page)

In her message of 2/8/01 Nayda mentioned a bug in the Switch To... dialog when there is a large of configurations to choose from.  Nadya pointed out that this is probably due to VFP Listbox bugginess.when there are more than 65 items.  The change to a Grid-based implementation should fix any such problems.

(not done)
Print command for the Switch To ... dialog
Add a Print button in the dialog for picking a configuration.  This should generate a listing that displays columns for functionid, title, category, and description of the available configurations in order that they are listed.  It would also be useful to include the last update date, although this is not currently displayed in the dialog.

Nayda suggested a Print command for the pick config dialog in her XFormDBF Forum posting of 1/4/01, and again in her posting of 3/28/01, but note that this is really a Saver feature, which also applies to BTCrit, etc.

(not done)
support Saver Init arguments for cloning a template configuration
Introduce 2 new optional Saver Init arguments for specifying a template functionid and metafile from which to clone an initial default configuration.  This avoids the need for the clumsier approach previously used to accomplish this via the cmdrclon( ) UDF, and it would also facilitate supporting the latest error handling and diagnostic features.

Note that the forthcoming Saver2 classes already added an argument to the old version of Saver.  The proposed change would add two more arguments, bringing us to something like this:

Init(funcid_arg, cmdr_arg, targob_arg, tmplid_arg, tmplfi_arg)


  • funcid_arg: is the functionid, as before
  • cmdr_arg: Commander metafile, as before
  • targob_arg: ErrHandler reference for target indirection
    This is the new argument already added in Saver2, which has the same meaning as it does in the new ErrHandler, upon which Saver2 is based.
  • tmplid_arg: template functionid - proposed new argument
  • tmplfi_arg: template metafile -  proposed new argument

Under the Saver2 architecture, XFormDBF (and BTCrit, when similarly updated) is a subclass of the new SaverForm foundation class, so it will be a simple matter to support these same additional Init arguments in XFormDBF (ditto for BTCrit).

Saver adjustments for compatibility with Commander changes
Make the necessary changes in Saver programs to accommodate Commander error handling changes (cmma0001).  Completed changes and testing for compatibility with cmma0001 changes on 11/4/00, including rebuilding/testing BTCrit (old version will suffice) and XFormDBF.

Additional Saver changes will also be required for Commander's revised internal naming conventions.  These require small Saver changes to preserve compatibility with Commander changes, as a preliminary step before the more substantial Saver changes to make use of Commander's new error handling features.  We may as well also make adjustments to XFormDBF to switch over to the new Commander names, although compatibility provisions should allow these changes to be deferred.  Rebuild BTCrit and test to confirm that it still works without any changes to VFP code.

preserve Z-ordering of child forms in SaverMain.SVM_Save
When child Saver-based forms are re-launched to restore the prior state, this should be done in such a way as to preserve the original window stacking sequence.  This could be accomplished by launching the child forms from back to front.  Note that VFP's main screen Forms collection lists windows from front to back, so we can just process this array in reverse order to go from back to front.
(not done)
Save Config As... command
Introduce a Save As... configuration command button and supporting logic to make it easier to perform the operation of saving the current configuration under a new functionid in a single step.  The equivalent procedure now requires these awkward and non-obvious steps:
  1. invoke Switch To...
  2. supply a New Functionid and click OK
  3. click on Save Config to save under new funcid

The new Save As... command would invoke the savrgetf.scx dialog, with the initial focus on the New Functionid field.  After the user enters a new functionid and exits from this dialog, the configuration would be automatically saved.  If an existing functionid is selected, the user would be prompted before replacing the old configuration.

new SaverCust foundation class
Introduce a foundation Custom class of Saver, based on the ErrHandler class.  The SaverCust class will serve as a convenient template for creating additional Saver foundation classes, and it will also be the parent for other Saver subclasses, such as SaverMain.  The easiest way to create SaverCust is by cloning and adapting the SaverForm class (in Saver2.vcx), using the following sequence of steps:
  1. copy SaverForm into temp.vcx
    drag and drop the class via VFP Project Designer against saver2.vcx.
  2. rename SaverForm to SaverCust in temp.vcx
    via VFP Project Designer.
  3. adjust records via browse against temp.vcx
    Make class alterations that can't be done via standard VFP tools like the Class Browser or Class Designer:
    1. replace class with 'errhandler' for objname = 'savercust'
    2. replace baseclass with 'custom' for objname = 'savercust'
    3. edit the properties memo field for objname = 'savercust'
      Remove lines for properties that don't pertain to Custom class, Caption and DoCreate.  Don't risk invoking Class Designer with these properties still attached.
  4. copy SaverCust from temp.vcx into saver2.vcx
  5. make remaining changes to class SaverCust via Class Designer
    Adjust comments, property sheet defaults, and method code as appropriate.  In order to minimize redundancy, we will want to introduce core Saver UDFs to handle generic aspects of logic.  Also continue to beef up error-handling logic at every opportunity.

A similar procedure would be use to create additional Saver foundation classes from SaverCust, to cover other VFP base classes as needed.  These foundation classes could then be subclassed by conventional use of the VFP Class Designer.

(not done)
assorted Configuration page and dialog refinements
Further enhancements that should be made to the Container class SavrContConfig, which is used in Config pages and the savrconf.scx dialog (formerly savercg.scx), and the Saver configuration command button classes:
  • Close button and/or Escape support in savrconf dialog
    The Config dialog should be easy to exit, as mentioned previously.  Escape should not be supported it it interferes with normal escape-from-editing behavior.
  • compact graphical pushbuttons
    At least as an option, if not the default, supply small graphics for each of the generic Saver configuration button classes, as mentioned before.
  • let Config dialog be a nested Saver-based form
    I.e. the state of the Config dialog's layout really should be saved and restored, and this would be most cleanly accomplished by using a nested Saver.  The parent configuration would then only need to store the Config dialog's configuration id.
  • maybe use two rows of buttons for very narrow layouts
    This may become necessary as more controls are added.  Mentioned previously.
  • maybe support a modeless Config dialog
    As mentioned before, this may be doable, but I'm not sure how useful it would be, so wait and see. 

Also see the following related tasks, which are listed separately:

(not done)
automatic state-saving and prompting options
Give the user an easy way to disable automatic state-saving, but still allow explicit Save operations.  As noted previously, suppression of state-saving behavior can currently be accomplished only by setting functionid to empty value, but we also want a separate flag to suppress saving without having to clear the configuration's functionid.  Also there should be an option specifying whether to prompt the user whether to save the state; the present logic always saves when the form is terminated, except if functionid is blank.

Another potentially desirable option is whether to prompt for destination or auto-creation of saved states.  As previously mentioned, the current implementation always auto-creates the state-saving meta-file if it's missing; this logic is handled in Commander.  We may want to provide prompting option(s) to control this at the Saver level.

These new generic Saver properties would be incorporated as check boxes on the generic Config page/form.

(not done)
packing facilities for Saver meta-files
Saver's state-saving logic entails deleting the old configuration and writing out a series of meta-file records, which use memo fields.  Even with the reuse of deleted records, this process causes a steady growth in the size of the .FPT file, because VFP makes no attempt to reuse free space dynamically in its memo files.  Consequently it is advisable to run PACK or PACK MEMO against Saver-generated meta-files on a regular basis, and there should be some features to make this easier.

Add a way to explicitly PACK the current meta-file, e.g. via Saver command button and corresponding generic Saver method plus supporting core UDF.  Also add one or more properties to provide some reasonable automatic packing behavior, which should require no explicit user action.  As mentioned previously, a tricky complication is the need for an EXCLUSIVE opening in order to PACK.

(not done)
category restrictions in the Pick Config dialog
As previously mentioned, there should be a way to use categories to limit the set of configurations listed in the savrgetf.scx dialog (formerly called savrpick.scx).  A reasonable mechanism might be a textbox in which the user can enter a pattern matching string to compare against the configuration's category.  Contrast this filtering mechanism with another way of limiting by functionid prefix, which is somewhat less flexible.
(not done)
configuration/application version compatibility mechanisms
Introduce the necessary properties and logic for marking saved configurations with version information, and comparing this with version information in the current Saver classes.  Provide a hook for adding version-specific logic to handle automatic conversion of old configurations.  Introduce a generic configuration compatibility dialog for notifying the user and prompting as to automatic conversion.  Also support a way of suppressing the prompt, and just auto-converting as necessary.
(not done)
new SaverEditbox foundation class
Create an example of a "normal" Saver-based control class, to demonstrate the feasibility of extending the Saver2 model to diverse types of non-container objects.  Substitute a SaverEditbox class control for the vanilla editbox in demoform as an example of further nesting down to the control level, and how to add Saver-based members at design time.  As with all Saver2 foundation classes, SaverEditbox would be based on an error-handling class, ErrHEditbox.
notes about updating from old Saver to new Saver2 classes
Assemble an outline of steps required to convert an existing Saver-based form, such as XFormDBF or BTCrit, to the new Saver2 classes and supporting programs.  Note that this will also require a procedure for converting old configuration meta-files.  (Since I ended up doing the BTCrit conversion myself, the notes I produced in the course of doing xfma0072 were sufficient.)
(not done)
Saver property for restricting functionid prefix
Add a new property, svp_funcprefix, which specifies a default functionid prefix for any type of Saver-based object.  If empty, impose no restriction.  This setting would affect the behavior of the Pick Configuration dialog, savrgetf.scx, by limiting the view of displayed configurations and setting a default prefix in the New functionid textbox.  We would also want to add a textbox for this item in the SavrContConfig class, which is used in Config pages and the savfconf.scx dialog.

This feature will be especially useful when a single meta-file contains a mixture of saved states belonging to a variety Saver classes, e.g. for parent SaverMain states plus child SaverForm states, as in the new Saver2 demo scenario.

Because the configuration meta-file records are indexed on functionid, this form of restriction can be highly efficient on large files.  Compare this with the more flexible, but less efficient capability of restricting configurations by category.

(not done)
demonstrate variant subclasses of Saver-based forms
Extend the Saver2 demo to illustrate variations of Saver-based forms defined by subclassing, for VFP form properties that can't be altered at run-time, e.g. Desktop, ScrollBars, ShowWindow, etc.  This will require switching to a class-based demo form, instead of the earlier SCX-based demoform.  Introduce a wrapper UDF to launch various demo form subclasses.
(not done)
generic saver context menu
Create a program to generate a context (shortcut) menu for various generic Saver commands, as an alternative to the Saver command buttons (Config..., Save, Restore, Switch To..., Copy..., Abandon, Delete).  This will become more important as additional non-Form Saver control classes are introduced.  Use a PRG-based implementation of menuing for greater flexibility than possible with VFP's menu builder.  Eventually we may want to introduce class-based menuing facilities, but deal with that issue separately.
generic Saver core UDFs
Break out generic inline code from methods of SaverForm, creating a set of core Saver UDFs, savrinit, savrrest, and savrsave.prg, which can be applied across all VFP base classes.  The same gimmick was used for the error-handling foundation classes, in order to minimize redundancy.  This change will be needed in order to introduce a new Custom-based Saver foundation class, as well as various other non-Form flavors of VFP controls.
(not done)
new svm_... methods for support of Saver command buttons
Introduce generic Saver methods in SaverForm to do the real work behind the configuration-related Saver command button classes, SavrCmd and its subclasses.  These methods should support appropriate error-handling logic, as with other existing SaverForm methods
supply error-handling logic for all methods of SaverForm
Having demonstrated how to incorporate error-handling for the Init method, apply similar logic to cover other methods of SaverForm, i.e. Destroy, SVM_Save, and SVM_Restore.  Define new macros for error codes and messages in saver2.h.

A prerequisite for comprehensive error handling in the SVM_Save and SVM_Restore methods will be to incorporate error-handling into the generic Commander facilities.  This can be done along similar lines to what was previously done for Querier, XFormDBF, and Saver.  Also see these related tasks:

(not done)
Saver demo changes for new error-handling classes
Revise the Saver demo application to build on the new Saver classes, SaverForm and SaverMain.  Introduce a simple main menu with command(s) for launching new demoform instances.  The new demo demonstrates a more general facility for nested Saver-based applications, built entirely on the new Saver2 classes, with enhanced error-handling.  Outstanding details:
  • fix ON SHUTDOWN handler for modal dialog cases
    Be sure that this works for cases where a modal dialog is in progress.
  • fix no-op state restoration of main modeless Config dialog
    Initial testing is aimed at confirming support of no-op Savers.
  • testing/debugging of modeless Config dialog usage
    Especially review logic for issues related to the sequence of termination steps.  Check for implicit closing of associated modeless Config dialog.
  • enable state-saving & restoration for main Config dialog
    Once the no-op case is fully debugged, let the modeless Config dialog behave like other state-saving forms.
  • support optional args to demomain.prg
    Which would be passed on to demomain.init, i.e. the standard Saver2 Init args: funcid_arg, cmdr_arg, targob_arg.
  • relaunching of child form should use path canonicalization
    To avoid the necessity of storing absolute pathnames in state-saving metafiles.
  • introduce additional trace levels, as needed
(not done)
Saver foundation class for main VFP window and its application(s)
Support an extended model of nested Saver-based applications by introducing subclass SaverMain, based SaverCust (based on ErrHandler, based on VFP's Custom class).  SaverMain supports a main program that can contain multiple SaverForm objects.  Also handle state-saving and restoration for the main VFP window, environment settings, and other global parameters.  Support properties for enablement/disablement of each group of attributes.  The SaverMain class will be used to implement a revamped Saver2 demo application.
incorporate generic error-handling into new Saver2 classes
Introduce new Saver foundation classes (version 2) based on ErrHandler classes.  Use generic error-handling facilities to provide clean, thorough error detection and reporting during state-saving and restoration logic.  Also note previous mention of generic error-handling in Saver, including diagnostic options and the potential relationship to configuration conversion issues.

The Saver2 foundation classes will include a new SaverForm class (based on ErrHForm, not to be confused with the old Custom-based SaverForm class) for forms that support state-saving and restoration.  Other Saver foundation classes will eventually be needed to support additional non-Form types that can use state-saving and restoration, e.g. Custom, Toolbar, Container, Grid, assorted control classes, etc.

The old Saver classes (used by XFormDBF and BTCrit) can eventually be phased out, because they will be superseded by the new error-handling Saver classes.  Both flavors will be allowed to coexist (in separate applications) to allow for a transition period.  In order to avoid needless complexity, there will be a separate project, class library, and supporting forms for the new Saver2 facilities.  This will also give me an opportunity to make another pass at improving some internal conventions.  The following module substitutions will be made in going from the old Saver facilities to the new version 2:

Description New Version Replaces Old
demo project file saver2.pjx saver.pjx
Saver class library saver2.vcx saver.vcx
include file saver2.h saver.h
pick-a-config dialog savrgetf.scx/prg savrpick.scx/prg
config form savrconf.scx savercfg.scx
demo form and main program demoform.scx savrdemo.scx, saver.prg
demo config meta-file saver2.dbf commandf.dbf

Note that in the old model, the Saver subclass object was added as a member to a form, which was based on the error-handling form class, ErrHForm.  In the new Saver2 model, a SaverForm class based on ErrHForm is used, eliminating the need for a separate Saver subclass member object.

In addition to the primary objective of introducing a Saver foundation Form class based on an error-handling class, the following general Saver refinements were included:

  • extended argument syntax, allowing meta-file path
  • clean conventions for Saver property and method names
  • added error checking logic for Init method
    Also see additional methods yet to be adjusted.
  • introduced selective saving toggle properties
  • reduced size and complexity of state-saving
  • simplified the Saver class hierarchy and demo app
deliver Saver & XFormDBF changes  for svma0006 to BT server
Upload and test the latest Saver and XFormDBF programs on the BT server.  This update pertains to svma0006: support flexible ordering options in the Pick Config (Switch To...) dialog.  The principal change was to the savrpick.scx dialog, which necessitated rebuilding XFormDBF (but there are no other XFormDBF changes).  The following mdacomm updates were made:
  • update savrpick.scx/sct
  • delete obsolete saver.txt
    Superseded by Old Notes About the Saver Application.
  • add link to to the new Saver forum
  • delete saver.app
    This demo app should never have been in mdacomm in the first place.
  • update xformdbf.app
(not done)
assimilate old saver.txt task list into this web page
Go through the old Saver task list and create updated entries in the new Saver task list (this table and its outline) for selected issues that are still of interest.
(not done)
support user-selectable configuration meta-files
In the current implementation there is no easy way for the user to switch to a different meta-file once a Saver-based application has been launched.  Allow the user to switch to a different meta-file by providing a pushbutton and/or editable textbox, instead of the present display-only meta-file textbox in the SavrContConfig class, which is used by both the Config page and dialog savercfg.scx.  This change would be helpful when multiple meta-files are used to organize saved configurations, as Nadya mentioned on 7/12/00.
support flexible ordering options in the Pick Config dialog
The savrpick.scx dialog, which is launched by the Switch To... button, currently lists the available configuration choices in a default ordering that is not particularly useful.  Add a way of allowing the user to easily sort the listed configurations by functionid, title, or category, e.g. by clicking on the column headers.  This is a long-standing request that was noted previously, and again raised by Nadya on 7/12/00.
(not done)
work out conventions for including Saver help into app help
HTLM Help supports a fairly transparent way of combining separately compiled help files into a larger help file.  Experiment to find the best way of using this feature so that a single Saver help file can be included in the help for any Saver-based application, like XFormDBF or BTCrit.

The simplest, most instructive way of doing this would be to start with the Saver demo application.  Create a simple help file for savrdemo.scx that uses the HTML Help "Merge Files"  mechanism to include generic saver.htm into the demo application's help file.  Make further VFP programming changes to support context-sensitive help in the Saver demo application (as opposed to the generic Saver dialogs, already so adjusted).  Confirm and document this approach, so that similar adjustments can be made in help for XFormDBF, BTCrit, etc.
(not done)
support context-sensitive help in generic Saver dialogs
Provide contextids and related VFP programming changes to support "What's This" help in the generic Saver dialogs and Config page.  This should be done in such a way that Saver-based applications, like XFormDBF and BTCrit, can inherit Saver's help with minimum hassle or redundancy.  Compare with previous work done to support What's This help in XFormDBF.

Creation of the new help pages for Saver's Config and Switch To... dialogs, described separately, are prerequisites for making the VFP programming changes to support context-sensitive invocation of HTML Help.  Also it will be necessary to create the HTML Help project (.HHP) and context mapping files (.H and .ALI) in order to generate a compiled saver.chm help file.
(not done)
help for the Pick Configuration (Switch To...) dialog
Create end-user oriented help for the dialog used to select a new configuration, which is launched by the Switch To... button.  Adapt and expand the preliminary version of this help that was previously included in XFormDBF Help - Config Page.  This should be covered in a separate page of generic Saver help, so it can be shared by other custom applications, like BTCrit.
(not done)
help for the Configuration dialog and/or Config page
Create end-user oriented help for the Configuration dialog and the equivalent Config page used in tabbed forms.  Much of this has already been done in a preliminary way in XFormDBF Help - Config Page, but this really should be covered as generic Saver help, so it can be shared by other custom applications, like BTCrit.
(not done)
create developer-oriented Saver help documentation
Supply help pages aimed at explaining how to use the Saver facility and what it is, from a programmer's point of view.  Compare with SplitCon Help - Design Overview and help documentation for the ErrHandler classes, other examples of developer-oriented help.  Topics to be covered for Saver include:
  • the Saver demo application
    Saver includes a standalone demo, which is useful for development and testing as well as being an illustration of the general facility.  As of Saver2, the demo was extended to give an example of nested Saver usage.  This needs to be explained clearly, because it goes beyond simpler non-nested Saver applications (like BTCrit and XFormDBF).  Sample screen shots would also be helpful.
  • the Saver foundation class library and core functions
    The Saver foundation classes handle state-saving and restoration for specific base classes of objects, and these are further subclassed as necessary.  The class library also includes a variety of Saver-related command button classes and a generic configuration container class, SavrContConfig.  All of this should be documented in detail.
  • generic Saver dialog forms
    There are two dialog forms, a resizable "Configuration" dialog and a "Pick Configuration" dialog, which should be documented.
  • related underlying applications
    Saver uses the ErrHandler, Commander, and SplitCon applications.  The relationship to these other components should be clearly explained.  Also note include files and minor generic utilities used by Saver.
  • using Saver within a higher level VFP application
    Explain how to go about incorporating Saver into an arbitrary VFP application, e.g. as done for XFormDBF and BTCrit.  Also discuss how to adapt an existing framework to make use of Saver.
  • configuration meta-files
    Mention assorted information and related issues of general interest about the configuration meta-files that Saver generates.

| Top | Unframe |


Copyright 2000- 2002, SpaceTime Systems