Randy Brown, Microsoft Corporation
September 1995
Microsoft® Visual FoxPro™ 3.0 now offers an open architecture for extending the Wizards and Builders beyond their current functionality. This whitepaper provides details regarding the new open architecture. And while the source code for the wizards remains proprietary, developers can write custom styles to extend the options of several of the wizards. In addition, developers can create their own wizards and builders to add to or replace the existing ones. We will touch on all of these topics in the following pages.
Wizards are not new to Visual FoxPro. They made their debut in the FoxPro 2.6 product line. As with the FoxPro 2.6 Wizards, the Visual FoxPro Wizards create new application components such as forms, reports, labels, queries, charts, and so on. In addition to offering a number of new wizards, Visual FoxPro now includes an open architecture for several of the more commonly used wizards. Developers can now create their own custom styles for the Form and Report Wizards. We will cover this topic in more detail later.
The best way to find out about the wizards provided with Visual FoxPro is to select the Wizards/All menu option from the Tools menu. A dialog is presented listing all available wizards which ship with Visual FoxPro. You won't find a whole lot of documentation about using the wizards because wizards by nature are meant to be self-explanatory. They provide assistance with common tasks developers perform when creating database applications.
Users new to Visual FoxPro often confuse wizards and builders. Probably the easiest way to discern the difference is to try both of them out. With Visual FoxPro 3.0, Builders for the most part are confined to interacting with forms and form controls. Builders work directly with the form designer while a form is in design mode and can be used to create new controls or adjust the appearance or behavior of existing controls. Wizards, on the other hand, do not work in design mode and cannot be used to modify an existing file. The Visual FoxPro Help file offers these definitions:
Wizards are interactive programs that help you quickly accomplish common tasks, such as creating forms, formatting reports, and setting up queries. By answering questions or choosing options on the series of wizard screens, you are telling the wizard to build a file or perform a task based on your responses.
Builders are tabbed dialog boxes that simplify creating and modifying forms and complex controls. Each builder displays a series of tabs so you can set the properties of the selected object. There are builders for some controls, for forms, for formatting controls, and for creating referential integrity between database tables.
Visual FoxPro leverages a common engine for both the Form Wizard and Form Builder. This means that you can create a single custom style for use with both tools.
That's about all you need to know to get started. Here is a list of wizards included with Visual FoxPro 3.0:
Wizard |
Description |
Form |
Creates a form based on a single table |
One-To-Many Form |
Creates a 1-Many form with a grid control for child table |
Report |
Creates a report based on a single table |
Group / Total Report |
Creates a report with groupings and totals |
One-To-Many Report |
Creates a 1-Many report |
Label |
Creates a mailing label report based on pre-defined styles |
Import |
Imports a foreign file format to a FoxPro table |
Documenting * |
Documents and formats FoxPro source files |
Table |
Creates a new table |
Local View |
Creates a view using local data |
Remote View |
Creates a view using remote data |
Query |
Creates a standard query |
Graph |
Creates a new graph using MS Graph |
Cross Tab |
Creates a new cross tab table based on existing data |
Pivot Table |
Creates an Excel PivotTable based on FoxPro data |
Mail Merge |
Creates a Word Mail Merge document based on FoxPro data |
Upsizing * |
Moves FoxPro data files to SQL Server files |
Setup * |
Creates installation program for distribution of custom apps |
* Included with Professional version only
And here are the Builders which come with Visual FoxPro:
Builder |
Description |
AutoFormat |
Formats a group of controls |
Combo Box |
Builds a combo box |
Command Group |
Builds a command group of buttons |
Edit Box |
Builds an edit box |
Form |
Builds a form |
Grid |
Builds a grid |
List Box |
Builds a list box |
Option Group |
Builds an option group of buttons |
Referential Integrity |
Creates referential integrity between database tables |
Text Box |
Builds a text box |
The remainder of this document focuses on extending the Visual FoxPro Wizards and Builders. We will discuss how you can create you own wizards and builders and register them in WIZARD.DBF or BUILDER.DBF so that they work seamlessly with Visual FoxPro. You can even override the main Wizard or Builder engines if you have special needs which cannot be satisfied by the existing ones. And finally, as already mentioned, we'll cover specifics in creating custom styles for Form and Report Wizards.
The Wizard registration table (WIZARD.DBF) is installed in your Visual FoxPro \WIZARDS directory. The Wizard registration table contains the information needed to run a specific wizard. If you do not like the way the shipping wizards function, you can change the values in this table to suit your own needs. For example, you can substitute your own Report Wizard by overwriting its corresponding Program field entry or even add a new Wizard record to the table. The registration table structure is as follows.
Field Name |
Data Type |
Width |
Description |
Name |
Char |
45 |
The name of the wizard as it appears in the Wizard selection dialog. |
Descript |
Memo |
4 |
The description of the wizard as it appears in the Wizard selection dialog. |
Bitmap |
Memo |
4 |
The name of the bitmap with qualified path which appears in the Wizard selection dialog. |
Type |
Char |
20 |
You can call the main wizard by type so that only wizards of a specific type appear in the Wizard selection dialog. |
Program |
Memo |
4 |
The APP file called to invoke a specific Wizard. |
Classlib |
Memo |
4 |
The VCX file containing the Wizard if not an APP file provided in the Program field. |
Classname |
Memo |
4 |
The class name of the Wizard if not an APP file provided in the Program field. |
Parms |
Memo |
4 |
Parameter(s) passed to Wizard APP file if needed. |
The following example shows the record contents for the One-To-Many Form Wizard:
Name: One-To-Many Form Wizard
Descript: Creates a data entry form for two related tables.
Bitmap: < empty-optional >
Type: FORM (Note: both Form and One-To-Many Form Wizards have this type)
Program: WZFORM.APP
Classlib: < empty-optional >
Classname: < empty-optional >
Parms: 1MANY (Note: since both Form and One-To-Many Form Wizards use the same WZFORM.APP file, this parameter is necessary.)
You should note that the main Wizard engine, WIZARD.APP, contains a base copy of the registration table, so it can be restored if you accidentally delete it. The restored file, however, will not contain any modifications you may have made to your original WIZARD.DBF. Therefore, it is a good idea to maintain a backup copy of your registration table if you intend to extend the wizard architecture to include your own wizards.
Visual FoxPro has a new global system variable called _WIZARD. Like other system variables (e.g., _GENSCRN and _GENMENU), _WIZARD contains a fully qualified path reference to the main wizard program, WIZARD.APP by default. This wizard program is responsible for reading the registration table (WIZARD.DBF) and calling the selected wizard.
The WIZARD.APP file is the main Wizard engine director. Some environment saving and restoring is provided, but the core functionality of the application is calling the specified wizard. Visual FoxPro has a number of hooks built into the product (e.g., in the New File dialog) which trigger a call to the program stored in _WIZARD. You probably won't need to write your own WIZARD.APP to replace the one provided by Microsoft. To provide custom wizard functionality, rewrite specific wizard applications (e.g., WZFORM.APP) and modify the Wizard registration table to run them through the WIZARD.APP file.
Each of the wizards can be called programmatically using the following call:
DO (_WIZARD) [WITH [cParm1] [,cParm2] […,cParm9]]
Visual FoxPro internally makes a similar call when it needs to invoke a specific wizard. For example, you can select the New File dialog, pick the Form option and click on the Wizard button. Visual FoxPro will internally make the following call:
DO (_WIZARD) WITH 'FORM'
And because WIZARD.APP looks up all Wizard types which match the parameter passed, you can easily override the existing Form Wizard and replace it with one of your own. You can see which keywords are used in the Type field of WIZARD.DBF and which optional parameters can be passed (Parms field). If you design your own wizards, you can pass a number of additional parameters such as preferences.
cParm1: Wizard type. This parameter controls which wizards WIZARD.APP displays in its selection dialog. For example, if you pass it 'FORM', you will see two wizards appearing in the selection dialog: Form Wizard and One-to-Many Form Wizard..
cParm2: Wizard name. If you want to call a specific wizard, you can pass its name here. For example, if you pass 'WZIMPORT', the Import Wizard will appear. WIZARD.APP first checks the Program field in WIZARD.DBF for a match of this parameter. If none is found, the Classname field is searched for a possible class instead.
uParm3-uParm9: The _WIZARD file accepts additional parameters which simply get passed through to the wizard being called. Parameter3 is special in that it can be used to lookup against the Parms field in WIZARD.DBF in case there is a conflict with the same wizard name. For example, some Wizard APP files (e.g., WZFORM.APP) are used by several wizards. This third parameter allows you to specify a particular one. For example:
DO (_WIZARD) WITH "","WZFORM","1MANY" DO (_WIZARD) WITH "AUTOFORM"
The following rules apply for passing parameters to WIZARD.APP:
If you pass no parameters, DO (_WIZARD), the standard Wizard Selection dialog is presented to let the user select a particular wizard. The description appearing at the bottom of this dialog is obtained from the Descript field of WIZARD.DBF.
You can filter the contents of the Wizard Selection dialog by passing a particular Wizard Type in the first parameter. The following dialog appears if you type DO (_WIZARD) WITH 'query'. If there is only one record which matches the Wizard Type mask, that wizard is launched without displaying the Wizard Selection dialog. If no wizard is found matching the filter an alert appears indicating this fact.
The second parameter provides a way to filter based on the specific Wizard application file as stored in the registration table Program field. If you pass a second parameter, it is important to know that the first parameter is ignored. Once again, if WIZARD.DBF contains multiple entries for the file name, the dialog is presented, otherwise the wizard is launched. The following dialog is displayed when you issue the following command:
DO (_WIZARD) WITH "","wzpivot"
Because WIZARD.APP passes nine parameters to a particular wizard, it is important that you design your custom wizards to handle these parameters. Even though you probably won't need all nine parameters, be sure to include placeholders for them in your PARAMETERS statement. This also applies to the Classname and Classlib fields, which offer an alternate way of invoking a wizard. If you choose this type of method for calling your wizard, make sure to place the nine parameters in the INIT event of the class stored in the Classname field.
Note: You cannot programmatically call a wizard which uses the Classname field as opposed to the Program field; however, a user can select it through the Wizard Selection dialog.
The third parameter which is passed to WIZARD.APP corresponds to the Parms field in the registration table. This parameter is used in conjunction with the second one to further distinguish which wizard within the single APP file to launch. The above dialog shows the two wizards stored in WZPIVOT.APP. If you wanted to directly launch one of these, you could make one of the following calls:
DO (_WIZARD) WITH "","wzpivot","pivot" && calls Pivot Wizard DO (_WIZARD) WITH "","wzpivot","xtab" && calls Cross Tab Wizard
If you take a look at the WIZARD.DBF table, you will see several records which represent unique methods for invoking a wizard. Both the Form and Report Wizards allow you to create a form/report on the fly without displaying the wizard screens. These two are represented as buttons on the Standard toolbar, and they only work if you have a table open.
DO (_WIZARD) WITH "AUTOFORM" DO (_WIZARD) WITH "AUTOREPORT"
The Cross Tab Wizard makes use of a new and improved _GENXTAB. The old GENXTAB.PRG program which shipped with FoxPro 2.x has been rewritten to take advantage of the Visual FoxPro object model and is now stored in VFPXTAB.PRG. In addition, several new enhancements have been added to allow various types of summary options. Since the Cross Tab Wizard calls _GENXTAB, you can subclass VFPXTAB or provide an alternative if you choose.
The Graph Wizard formally known as GENGRAPH.APP in FoxPro 2.x has also undergone a major transformation. The contents of the _GENGRAPH global now point to WZGRAPH.APP. Since the Graph Wizard can be called directly by the Wizard menu or via the Query/View Designer output destination, several methods exist for calling it. The Graph Wizard is called from the Query Designer using the last call shown below. Since the user has already selected the table(s) and fields, there is no need to start on the first screen. In addition, it doesn't make sense to create another query from within a query. In essence, you could go into an endless loop. The first two code examples below show how you can invoke it as if it were being called as a wizard outside of the Query Designers. The final example, which we will touch on later, illustrates how to programmatically use the Graph Wizard to automate the creation of a specific chart with control over certain preferences such as chart type and title.
DO (_WIZARD) WITH "","WZGRAPH" DO (_GENGRAPH) WITH "WIZARD" DO (_GENGRAPH) DO (_GENGRAPH) WITH "AUTOGRAPH",p2,p3,p4,p5,p6,p7,p8,p9
As seen above with the Graph Wizard, you can call wizards directly without going through the WIZARD.APP engine. Unless you have a specific reason to do so (i.e., the Graph Wizard), you should if at all possible go through the recommended channel—WIZARD.APP. The primary reason is that WIZARD.APP knows where to look for particular wizards, even if you decide to move your files (including VFP.EXE) around.
cParm1: Reference to output file name variable. This is a memory variable which gets passed back to VFP when the wizard is finished. It contains the name of the Wizard generated file. Since VFP hooks directly into the wizards, through the Project Manager, this option allows you to create a new file (e.g., Form) via the wizard and have it automatically registered in the PM.
cParm2: This parameter is the contents of the Parms field in the Wizard registration table.
uParm3–uParm9: These are extra parameters passed to _WIZARD. They are optional parameters which are not used by the standard shipping wizards, but can be used by your custom wizards.
The following rules apply for passing parameters from WIZARD.APP:
If you are writing your own custom wizards, you must make sure that you provide a PARAMETER statement with 9 parameters to handle the call made by WIZARD.APP.
The first parameter is a special hook if you want to have the output from your wizard added directly to the project. This option will only work if the wizard was invoked from the Wizard button on a Project's new file dialog. A follow-up action (such as modifying the file) can also be applied from within your custom wizard. The sample code following exhibits this.
* Sample main program for custom wizard showing Project interfacing. PARAMETER cVarName, p2, p3, p4, p5, p6, p7, p8, p9 ** add wizard code here *** * set the wizard generated file here cNewWizFile = 'offices.scx' &&example DO CASE CASE m.lmodifyform * add to project and modify output file &cVarName = '2' + m.cNewWizFile CASE m.lrunform * add to project and run output file &cVarName = '3' + m.cNewWizFile OTHERWISE * add to project &cVarName = '1' + m.cNewWizFile ENDCASE * EOF
Because of the open architecture, you can also obtain output information by passing a variable reference to the wizard directly.
** Sample code returning Wizard output information *** cOutPutContents = '' cParm1= 'cOutPutContents' DO WIZARDS\WZFORM WITH m.cParm1 ? m.cOutPutContents 1C:\OFFICES.SCX
At this point, we'll jump into extending the functionality of some of the wizards. The native Visual FoxPro Wizard architecture is open in the sense that you can add custom styles to both Form and Report Wizards. You can either overwrite or add to the existing visual styles in the Form Wizard (e.g., Standard, Chiseled, Shadowed, Boxed and Embossed) and button code styles (e.g., Text Buttons, Picture Buttons, and No Buttons). The same holds true with the visual styles associated with the Report Wizard (e.g., Presentation, Executive, and Ledger). In the case of Forms, the wizards use and read properties directly from an object instantiated from a style class that is based on a form. With Reports, styles are defined by report templates (FRX files). The actual wizards, which house the interface templates and process engines, are proprietary and can't be modified.
The extent to which one can alter the functionality of the Form Wizards through custom styles is indeed quite vast. As mentioned above, the styles can be visual or code based. Each of the styles is registered in the Form Wizard's style registration table (FRMSTYLE.DBF). Note: the Form Wizard has an internal version of this table which contains records for the 5 visual styles and 3 button styles that ship with Visual FoxPro 3.0. These styles are actually classes stored in the WIZSTYLE.VCX class library. You can alter any of these styles to your heart's content or add your own.
The Form Wizard (WZFORM.APP) attempts to locate FRMSTYLE.DBF when it is launched, otherwise it uses its own internal styles table. Therefore, it is important that you ensure the FRMSTYLE.DBF table is accessible in the \Wizards directory or along the SET PATH setting. If you do decide to provide your own FRMSTYLE.DBF, the shipping styles will not automatically appear on the Wizard style page. In order to do so, you will need to include records for each of them. This allows you to overwrite one of the shipping styles.
This is the styles registration table which contains a listing of all the styles used by the Form Wizard. The default styles are all contained in WIZSTYLE.VCX, which is described below, but you can add your own styles and include them in separate visual class files. The following fields are expected in FRMSTYLE.DBF:
Field Name |
Data Type |
Width |
Description |
Stylename |
Character |
20 |
Name of style class (must be Form) |
Vcxfile |
Memo |
VCX file name where style class exists |
|
Styledesc |
Character |
30 |
Description for Wizard listbox |
Styletype |
Character |
1 |
Type of style |
Wizard |
Logical |
Used by Wizards |
|
OneMany |
Logical |
Used by One-To-Many Wizard |
|
Builder |
Logical |
Used by Builders |
|
Bmpfile |
Memo |
BMP filename for Wizard visual style |
|
Premethod |
Character |
20 |
Method to call before style create generation |
Postmethod |
Character |
20 |
Method to call after style create generation |
The following program creates this table and inserts the default Form Wizard records:
CREATE TABLE frmstyle( ; Stylename C(20), ; Vcxfile M, ; Styledesc C(30), ; Styletype C(1), ; Wizard L, ; OneMany L, ; Builder L, ; Bmpfile M, ; Premethod C(20), ; Postmethod C(20)) INSERT INTO frmstyle VALUES ; ('standardform','wizstyle.vcx','Standard', ; 'V',.T.,.T.,.T.,'standard.bmp','','') INSERT INTO frmstyle VALUES ; ('chiselform','wizstyle.vcx','Chiseled', ; 'V',.T.,.T.,.T.,'chiseled.bmp','','') INSERT INTO frmstyle VALUES ; ('shadowform','wizstyle.vcx','Shadowed', ; 'V',.T.,.T.,.T.,'shadowed.bmp','','') INSERT INTO frmstyle VALUES ; ('boxform','wizstyle.vcx','Boxed', ; 'V',.T.,.T.,.T.,'boxed.bmp','','') INSERT INTO frmstyle VALUES ; ('embossedform','wizstyle.vcx','Embossed', ; 'V',.T.,.T.,.T.,'embossed.bmp','','') INSERT INTO frmstyle VALUES ; ('txtbtns','wizstyle.vcx','\<Text Buttons', ; '1',.T.,.T.,.F.,'','','') INSERT INTO frmstyle VALUES ; ('picbtns','wizstyle.vcx','\<Picture Buttons', ; '2',.T.,.T.,.F.,'','addbmps','') INSERT INTO frmstyle VALUES ; ('nobtns','wizstyle.vcx','N\<o Buttons','3',.T.,.T.,.F.,'','','')
The Styletype field describes the styles used by the Form Wizard. If you look at the Step 2 of the Form Wizard, which is the Style page, you can see styles from FRMSTYLES.DBF in the Style list box. The visual styles which appear in the list box all have a Styletype = 'V' for visual. The Form Wizard ships with 3 preset button styles (Text Buttons, Picture Buttons and No Buttons). The Styletype value for each of these option buttons is '1', '2', or '3'. You can provide your own button styles references using a Styletype = 'B'. These appear in a drop-down list beside the Custom option button, which is only visible if you have additional button styles. If you look at a button class (e.g., Txtbtns in WIZSTYLE.VCX), you can see that it is a container class of buttons. You may want to follow this approach if you create your own custom button styles.
The two Premethod and Postmethod fields allow you to provide a program to be called by the Form Wizard's engine before and/or after creation of the form. You may have special processing needs for your custom style which can be handled by one of these fields. For example, the Picture Buttons style needs to check to see if the button graphics .BMP files are properly installed, otherwise they are copied out of WZFORM.APP.
The Form Wizard automatically loads WIZSTYLE into the SET CLASSLIB setting. So if you want to add custom styles, they can easily be added to WIZSTYLE. However, if you decide to use your own VCX, you need to specify that in the Vcxfile field. Make sure you include a path here if you are not sure whether the Form Wizard can locate it.
WIZSTYLE.VCX is the visual class library containing the various styles used by the Form Wizard. All of the preset visual and button styles are stored in this library. You can edit existing classes or add your own. If you plan to edit existing classes, it would be a good idea to create a backup copy of the library before making your changes. The Form Wizard engine provides extensive style validation; however, there are unlimited things one can do to a style which may cause problems for the Form Wizard. If you stay within the guidelines of style creation as described below and use the shipping styles as references, your custom styles should plug-in and work just fine. In fact, you may want to simply subclass an existing style (e.g., embossedform) and work off of it. We'll next go into depth on the two types of styles, visual and code.
The Form Wizard's processor relies on custom styles for definition of the form attributes and field layout. To create a form style for wizard-generated forms:
Registering the new style has been discussed above. The other steps in the process are described in more detail below.
Create your style form by subclassing Baseform or one of the other form styles (e.g., Embossedform) in WIZSTYLE. You need to use Baseform or a class derived from the Baseform class since it contains all of the custom properties which allow you to set an assortment of options for your style.
The Form Wizard creates the form by instantiating the various style objects. Therefore, you need to be aware that any Init, Load, Activate, Deactivate or Destroy, etc. code you place in one of these classes could potentially break the Form Wizard. Be careful with how you handle this.
The following table shows a list of custom properties contained in the Baseform. While these properties, which are not case-sensitive, will allow you to add more power to your style design, they are not guaranteed to ensure good form design. Form design is a subjective thing, so you should explore using these various properties on your styles to achieve the results you desire.
Property |
Description |
wizbtnlayout |
Button position object (class) if one used for unique placement of buttons |
wizbtnpos |
Button position centering (0-none,1-hori,2-vert,3-both). By default buttons are centered in footer. You can use these settings for better control over how buttons are placed, especially if buttons are vertically laid out. |
wizbuffering |
Table buffering for opened tables |
wizbuttons |
Name of button class |
wizcaptions |
Whether to use DBC English field captions |
wizcboxlbl |
Whether to use the checkbox as the label |
wizcodestyle |
Whether to use code style or button style |
wizfield |
Class reference for a field |
wizformstretch |
Whether to shrink/expand form (height only) based on number of fields selected |
wizgrid |
Class reference for a Grid (1-Many) |
wizgridform |
Use a separate form for Grid |
wizlabel |
Class reference for label object |
wizlayout |
Class reference for layout object |
wizlblcap |
Label capitalization (proper, upper or lower) |
wizlbldefwid |
Whether to use constant label width for consistent look and alignment of fields on form |
wizlblspace |
Space between label and field |
wizlblsuffix |
Suffix which can be added to each field label |
wizlogic |
Class reference for a logic field (optional - if not used default to Wizfield) |
wizmaxcharfld |
Maximum width of char type field before converting it to memo (editbox) style |
wizmemo |
Class reference for a Memo field |
wizole |
Class reference for a General field |
wiztitle |
Class reference for title (usually a label) |
wizuser |
For use by user |
wizverify |
Whether to verify class objects (use for testing but can improve performance if turned. off) |
Most of these properties are self explanatory. I'll touch on a few of them below and how you can use them to enhance your styles.
WizVerify—This setting is used for testing your style. It verifies that each class (e.g., the one referenced by WizField) exists by instantiating each one. Once you have designed and tested your style so that it works fine, you can set this property to False (.F.).
WizFormStretch—There are situations where you may not want your form to stretch vertically to accommodate more fields. This property allows you to turn this feature off. For example, you may have some vertical buttons in the right-hand margin which would require a certain minimum form height in order to display correctly.
WizCboxLbl—If you are using the Wizlogic class which contains a check box, you can choose to use the check box caption or that of the label object (e.g., Wizlabel). This property controls which object is used for displaying the field label.
WizLblDefWid—This property allows you to control whether each label is sized the same fixed width or whether they are autosized. If you want to have your labels right-aligned, then set this option .T. so that the fields line up evenly.
WizBtnLayout—By default, the Form Wizard attempts to center (both vertically and horizontally) the buttons in the footer. You can choose to have them placed elsewhere by including an object (such as a shape) on the form style and referencing it through this property. When the Form Wizard goes to place the buttons, it will do so at the object position. Use this in conjunction with WizBtnPos.
WizButtons—You can override the button style chosen by the user in the Wizard by including a reference to a class containing buttons (or anything else). Use this in conjunction with WizBtnPos for positioning.
WizTitle—An optional Title object can be added to a form style. The Title object is represented by a label class that is referenced in the Wiztitle property. This object's caption will assume the text typed into the Form Wizard's Title textbox on the Finish page.
The second step in creating a custom form style for the Form Wizard is to add the Layout object (Layoutsty) to the form. The Layout object is a container of shapes which controls the horizontal/vertical spacing of objects (i.e., the fields) as they are laid out on the form. If you subclass one of the existing form styles, you can use and modify the Layoutsty object which has already been added. The Wizlayout custom property of baseform specifies the name of the layout class and is set by default to Layoutsty. Your form must have this property set to a valid layout class.
The Layout object provides dimensional information for field layout. There are 4 shapes and corresponding custom properties in the Layoutsty container class. The properties are used to reference the shapes:
Object |
Property |
Description |
Shape1 |
oDimensions |
Represents the physical boundary on which fields can be laid out. Everything above it is considered the header and everything below is the footer. You can think of oDimensions as being similar to the Detail band on a report. |
Shape2 |
oLabel1 |
The Left and Top properties of oLabel1 indicate the starting position for field layout. |
Shape3 |
oLabel2 |
The space between oLabel1 and oLabel2 indicates the vertical spacing between fields. |
Shape4 |
oCol2 |
The space between (oLabel1.Left + oLabel1.Width) and oCol2.Left indicates the column width if there are multiple columns of fields on the form. The Form Wizard attempts to layout fields vertically if it can fit all of the fields on the form, otherwise, it reverts to laying them out horizontally in columns based on the column width derived from this property. |
The Form Wizard will adjust the size of the form up to the size of the Maximum Design area setting in your Options dialog if the wizformstretch property on the baseform is set to True (.T.). Only the portion of the form covered by oDimensions is affected. The header and footer remained fixed in height. The Form Wizard only supports vertical stretching whereas the Form Builder can stretch horizontally.
The third step in creating a custom form style for the Form Wizard is to create and register classes for displaying field data on the form. Associated with each form class style is a set of classes used for adding fields based on their data type. For example, a separate class containing an edit box is used for memo fields. Logical fields use check boxes and general fields use oleboundcontrols.
Once you have created your set of data classes, they need to be registered under the following custom properties on the baseform derived style: Wizfield, Wizmemo, Wizlogic, Wizole and Wizlabel. Unlike the Layout object which needs to be added to the form style, the data classes are only registered with the style.
You need to be aware of the following points when you are creating and registering your custom styles for the Form Wizard:
Important: You cannot mix the two types of field classes for a visual style. They must either be all free control or all container. The Form Wizard will generate an error if you try to mix the two.
Value |
Description |
0 |
stretch and move with field |
1 |
stretch with label/field |
2 |
stretch over all |
The first option is commonly used for adding a special effect to just the data bound control. The Shadow and Chiseled styles use this effect. The second special effect causes stretching for vertically oriented objects such as in the Boxed style. The last option could be used to place a border shape around both label and field.
The Form Wizard engine uses the Visual FoxPro object technology to generate a form based on the visual and button styles selected by the user. The first step for the engine is to read and verify the style information. This means that the Form Wizard must instantiate the various style objects. For example, the Layoutsty object is instantiated to obtain the dimensional information. Once all of the settings and options are read in, a new Form object is created based on the visual form class. Field objects are then positioned onto the form based on the data type styles. Finally, the button class is added. If the user hits the Preview button, the Form is simply displayed. The form is only saved to an SCX file if the Finish button is pressed. And when this happens, a Data Environment object is created with the selected data sources.
The Form Wizard also allows for creation of custom button styles. Visual FoxPro ships with two styles, Text Buttons and Picture Buttons. The Text Button style is represented by the Txtbtns class contained in WIZSTYLE. Picbtns is simply a subclass of Txtbtns with pictures added.
You are free to overwrite and/or substitute your own button styles if the existing ones don't suit your particular needs. The above passage on the FRMSTYLE.DBF registration table gives instructions on how to register your button class properly so that it appears on the style page.
The Form Wizard has a Preview button on the final page which allows you to preview the form. Because you are actually previewing a live form, all of the controls will function just as if you made a DO FORM call. You can add code to your button class to have the buttons function in a unique way when the Preview button is pressed.
If you take a look at the Txtbtns class in WIZSTYLE, you will see two custom properties: PreviewMode and PreviewInit. The Form Wizard engine checks to see if your button class contains these properties and explicitly sets them to .T. when the Preview button is pressed. The Txtbtns class, for example, will render all edit buttons disabled when in PreviewMode so as not to allow editing of any data. The Txtbtns class also contains a number of additional custom properties which are used internally by that class and don't interface with the Wizard.
As you become more familiar with the custom style technology, you will come up with many cool and creative styles. Here are few ideas you might want to kick around.
The following form style uses vertically laid out buttons and field objects embedded in raised containers. The form itself was subclassed from the Embossedform class style. In order to create the proper layout for this style, you need to leave a wide right margin in the Layoutsty object for the buttons. The vertical button style (VertBtns in WIZSTYLE) was actually dropped onto the form style itself. I then set WizCodeStyle = .F. so that the Wizard would not add the button style chosen. I also set WizFormStretch = .F. so that the buttons would not get chopped off. Notice the field captions (WizLblSuffix = "..." and WizLblCap = "lower").
The next style is similar to the one above. Set WizCodeStyle = .F. so that no buttons appear. There is code in the Activate method of the form which triggers a toolbar.
Sample code contents of Activate method:
IF ATC("XSTYLE",SET("CLASS"))=0 SET CLASSLIB TO xstyle ADDITIVE ENDIF IF WEXIST("Wizard Buttons") IF !WVISIBLE("Wizard Buttons") SHOW WINDOW "Wizard Buttons" ENDIF ELSE PUBLIC mywiztoolbar mywiztoolbar = CREATE("xPicBtns") mywiztoolbar.caption = "Wizard Buttons" mywiztoolbar.show ENDIF
The last example shows a new set of buttons created to allow the user to only view data read-only. The View Buttons class is essentially the same as the Txtbtns class with the edit buttons removed.
As with the Form Wizard, you can create your own custom report style templates. Fortunately, customizing styles for the Report Wizard is very simple to do. Unlike the Form Wizard which utilizes the object technology, the Report Wizard still relies on the old FRX report structure. And custom styles are actually FRX files with special objects containing layout information.
Visual FoxPro ships with three Report Wizards. Group/Total, One-To-Many, and simple Report Wizards. If you have run through any of these wizards, you will know that you have the option to place the fields in either a horizontal or vertical orientation. The more common horizontal layout represents a listing of records which can have groupings, subtotaling and totaling of data. There is a separate report template (FRX) for both orientations. In addition, there is also a separate template for the One-To-Many Report Wizard. So, a custom style actually consists of three report files.
The one example below is that of the custom style used for horizontally listed fields. Because VFP reports are not objectified, there are no custom properties that can be used to control various attributes of the styles. Instead these attributes are provided by Style Triggers or Keywords embedded in the various objects on a report.
As with the Form Wizard, there are objects used for data types. Specifically, you must include a field, memo and OLE object. Optional labels for the title, page, and date can also be added. Notice the names (expressions) used for the object in the template below. These are important in that the Report Wizard relies on the exact wording as representation of a particular style. The Report Wizard automatically picks up the font attributes of layout objects.
The following table contains the various style triggers used by the Report Wizard to set specific style attributes. Take special note of the location because some of them go in the comment field while others go into the actual field expression or caption. The divider triggers are used by the Ledger style report to separate fields.
Property |
Location |
Description |
title |
Caption |
Name of object used for title. |
wiz_field |
Expr |
Name of object used for fields. |
label |
Caption |
Name of object used for field labels. |
wiz_memo |
Expr |
Name of object used for Memo fields. |
wiz_general |
Expr |
Name of object used for General fields. |
wiz_hstretch |
Comment |
Tells Report Wizard to stretch object as report stretches horizontally. Use with lines and shapes. |
wiz_hdivider |
Comment |
Denotes an object which horizontally separates fields in detail band. |
wiz_vdivider |
Comment |
Denotes an object which vertically separates fields in detail band. |
pageno |
Comment |
Denotes a field used as Page Number place holder. |
wiz_upper |
Comment |
Tells Report Wizard to force field labels to UPPER case. |
wiz_lower |
Comment |
Tells Report Wizard to force field labels to lower case. |
wiz_proper |
Comment |
Tells Report Wizard to force field labels to Proper case. |
The following illustration shows a One-To-Many custom style and how the fields are laid out. Note the Wiz_Parent label field. There is a ":" suffix at the end which tells the Report Wizard to place a ":" after each field caption. You can place a suffix in any label. For example, you can add an ellipses after the field caption by setting the label object's expression to "Wiz_Label...".
The Report Wizard also uses a registration table similar to that of the Form Wizard. If this table doesn't exist, then the table built into the Report Wizard is used. Below is the structure of the table. You should place it in your \WIZARDS directory so that the Report Wizard can locate it. Remember to use fully qualified path names for the various style FRX files.
Field Name |
Data Type |
Width |
Description |
Stylename |
Char |
20 |
Style description which appears in Wizard. |
Stylehbmp |
Memo |
4 |
BMP for horizontal style. |
Stylevbmp |
Memo |
4 |
BMP for vertical style. |
Stylembmp |
Memo |
4 |
BMP for one to many style. |
Stylehfile |
Memo |
4 |
File for horizontal style. |
Stylevfile |
Memo |
4 |
File for vertical style. |
Stylemfile |
Memo |
4 |
File for one to many style. |
There is a nice short-cut to the hassle of working with MS Graph directly to create charts. And while I recommend you spend some time learning OLE Automation in Visual FoxPro, you can use the Graph Wizard (_GENGRAPH) to accomplish many of the same tasks. The Graph Wizard will use the columns of the selected DBF/Cursor and make intelligent decisions on how the data is input. You can control the ordering and selection of fields by creating a SQL query/view prior to running _GENGRAPH.
Syntax:
DO (_GENGRAPH) WITH <parm1>[,<parm2>] [,<parm2>]...[,<parm9>] * parm1 - "AUTOGRAPH" &&required * parm2 - chart type (number) * parm3 - chart subtype (number) * parm4 - title (if not empty) * parm5 - series by row (.T.), by column (.F.) * parm6 - has legend (.T.) * parm7 - use autoformat (.F.) * parm8 - name of output DBF for graph * parm9 - don't show graph with MODIFY GENERAL (.f.)
Example:
DO (_GENGRAPH) WITH 'AUTOGRAPH',1,1,'OFFICES',.F.,.T.,.F.
Here are some recommendations for common charts. When choosing the autoformat option, you need to supply both the type and subtype for the chart.
Type |
Series in |
Chart Type |
AutoFormat |
Area |
Columns |
1 |
|
3D Area |
Columns |
9 |
|
Bar |
Rows |
2 |
|
3D Bar |
Rows |
10 |
|
Column |
Rows |
3 |
|
3D Column |
Rows |
11 |
|
Pie |
Columns |
5,6 |
|
3D Pie |
Columns |
14,6 |
|
Line |
Columns |
4 |
|
3D Line |
Columns |
12 |
I should mention a few words about the Macintosh® product. Mac Graph 5.0 does not support OLE Automation like its Windows counterpart. The Graph Wizard relies on using OLE Automation for setting chart properties such as type, title and legend. Because of this lack of OLE Automation support, it is likely that the Graph Wizard will have more limited functionality on the Mac product.
Currently, the Builder technology is limited to Forms and Form Controls because of the "live" state of the Form Designer surface. In addition, there is an RI Builder, but this is a slightly different beast. Once the object technology is carried over to menus, you can expect more Builders to follow.
Visual FoxPro has provided excellent documentation on using the ASELOBJ() function for accessing the Form Designer and creating your own Builders. In fact, there are a number of third parties working on extensions to the Builders. This small section discusses a few things you can do with the existing Builders.
The Builder registration table is the same format as the one used by the wizards. In fact, you can take a look at it in the \Wizards directory. One of the differences that you will notice is that all of the Builders are classes and not applications. This is because the Builders are self contained within the BUILDER.APP file. If no particular Builder exists for a specific object, then a dialog will indicate this. Visual FoxPro does not ship a Builder for each type of control, so you may want to create some to fill in the gaps. Or you might want to replace/augment existing ones. To do any of these enhancements/modifications, you must record them through the registration table if you intend on using the BUILDER.APP engine.
The Builder engine can actually use a specific user-defined Builder if the object being modified has a custom property named "Builder". This custom property must be set to the name of your replacement builder application. For example, you might create your own subclass of a unique Grid class that you like. By adding a custom property for this class, you can have BUILDER.APP bypass the usual Grid Builder and instead run the one you specified.
The Form Builder uses the same engine used by the Form Wizard. This means that you can create custom Builder styles just as you did for Wizards. In fact, you can have the same styles used for both. The Form Wizard style registration table has a Builder field which can be set to control whether a style is used with the Form Builder. The Form Builder merely lays out the fields. There is no placement of button objects as is done with the Form Wizard. The Builder is meant as a replacement for the old Quick Form option in FoxPro 2.x.