[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7] [ 8 ] [ 9 ]

Menu templates <PJXNAME>_MAIN,_TOP,_APPEND, and _GO

There are four template menus provided for each generated application. Three of the menus correspond to each of the three "application types" to which the Application Builder gives you access. The Application Builder fills the application object's cStartupMenu properties with appropriate information, depending on the app type you pick.

If you have not created top form menus in the past, you may find some of the Cleanup code in the _TOP.MNX generated menu quite unusual. For example:

IF EMPTY(APP_GLOBAL.cHelpFile)
   SET SKIP OF BAR 1 OF (a_menupops[9]) .T.
ENDIF

Note the use of an array element, rather than an explicit popup name, in this code. The framework takes advantage of GENMENU's ability to provide menu popups with unique generated names for all top form application menus. This can be important if you have an application that juggles several independent frames on the desktop.

The framework uses the fourth menu to add a navigation context menu to existing menu bars, for forms that you've indicated (in the metatable) should have such a menu. The Application Builder fills the app object's cGoMenuFile property with appropriate information and also switches information in the MNX to toggle this menu between a top form and standard menu.

Document register/metatable, <PJXNAME>_APP.DBF

This table has already been mentioned briefly, and will be described in detail in the section on Project Hook and Application -driven project components, below. The Application Wizard creates it, but the real work of filling it out happens later.

A few miscellaneous text files

A generated CONFIG.FPW appears in your project directory, with appropriate values you will want to consider when you create EXEs for framework-enabled applications. This is really just a convenience for you, and an education for your beginning developers, since the values here are common-sense recommendations for most EXEs. As with the generated .H file, you'll find plenty of notes within the CONFIG.FPW.

There's also a generated file with the name <PJXNAME>_APP.TXT. This file allows project hook objects a chance to register actions they take on your project, throughout the project's life. The shipping project hook object does not add many details to a log, but we'll subclass the project hook object in this session's examples, to perform this service among others.

Change the Wizard-generated components

The Application Wizard uses a table named _FRAMEWK.DBF to generate all the pieces of your application. You should find this table in the HOME()\WIZARDS directory, with _FRAMEWK.VCX/VCT and the header file used by the _FRAMEWK superclasses, _FRAMEWK.H.

_FRAMEWK.DBF contains all these pieces in memo fields, as files. Therefore, to change what the Wizard generates, you change what's inside _FRAMEWK.DBF.

The OOP pieces are all straight subclasses of _FRAMEWK.VCX classes. They go into the _FRAMEWK.DBF as the contents records labelled T_META.VCX and T_META.VCT. These items don't become part of your classes' inheritance tree; effectively they are the application-level classes, with different names. T_META.VCX/VCT exists so the Application Wizard can avoid generating these subclasses when it generates the rest of the application.

The standard Application Wizard implementation has a number of constraints:

  • Your application subclasses descend directly from _FRAMEWK.VCX. This prevents your adding superclass levels with your own enhancements to the framework, and you certainly can't specify different superclasses when you generate different "styles" of applications
  • Your copies of the ancestor classes, in _FRAMEWK.VCX and FFC libraries, are presumed to be in the HOME()+ "Wizards" and HOME()+ "FFC" directories. Because these ancestor classes are built into your framework applications, and therefore require recompilation during a Build, you have to give all team members write privileges to these locations, or they can't use the Application Wizard to start new framework applications. In addition, the fixed locations hamper version control; you may wish to retain versions of ancestor classes specific to older framework applications, even when Microsoft delivers new FFC and Wizards folders.
  • Your non-OOP components are always generated out of HOME()+ "Wizards\_FRAMEWK.DBF". The templates are not easily accessible for editing. The assumed location of _FRAMEWK.DBF prevents you from using different customized template versions for different types of apps, and also presents the same location problems (write privileges, versioning) that affect your use of the framework class libraries. As with your application subclasses, you can't designate different templates when you generate different types of applications.
  • You have no opportunity to assign a custom project hook to the project, to suit needs of your own classes, use of other Framework components, or general style of work.

Some (but not all) of these constraints occur because the VFP 6 Application Wizard actually calls the older VFP 5 Application Wizard to do much of its work.

In the APPWIZ folder of your source code for this session you'll find an "improved" version of the Application Wizard. It has the following advantages:

  • It addresses, and fixes, the problems and constraints listed above.
  • It makes it easier for you to subclass the Wizard and create additional Wizard features of your own in your subclasses
  • Although it calls the VFP 5 Application Wizard just as the old one did, it is designed to use a more streamlined code base eventually.

If you DO NEWAPPWIZ.PRG, provided in the NEWWIZ folder, you will get a dialog almost identical to the shipping VFP 6 Application Wizard and functionally equivalent to the original dialog. The only difference you'll notice is a request, on startup, asking you if you wish to register this wizard in your HOME()+ "Wizards\WIZARD.DBF" table for future use (see the next figure).

Executing NEWAPPWIZ.PRG gives you a version of the VFP 6 Application Wizard that looks exactly like the shipping one, but is different "underneath".

Execute NEWAPPWIZ.PRG again, this time with a second parameter indicating a different Wizard subclass to instantiate:

DO NEWAPPWIZ WITH , "AppWizReinherit"
   * don't forget that leading comma!

You should get another messagebox, similar to what you saw before, asking you if you want to register this subclass in the WIZARD.DBF table. When you've dismissed the messagebox, you see the dialog in the next figure.

App Wizard with "reinherit" features.

The first page in this dialog handles the "standard" Wizard requirements, and each subsequent page addresses one of the constraints mentioned earlier. Because some of these requirements require you to understand the relationship between different framework components, each page delivers an explanation of its task. In the next figure you can see the dialog's second and third pages.

The "Reinherit Wizard" allows your team to take control of the components the Application Wizard uses to generate a VFP 6 framework application.

[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7] [ 8 ] [ 9 ]