Randy Brown
Microsoft Corporation
September 1996
Microsoft® Visual FoxPro™ version 5.0 offers an open architecture for extending wizards and builders beyond their current functionality. This technical article 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® version 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. As a result, developers can now create custom styles for the Form and Report Wizards.
To identify the wizards provided with Visual FoxPro, select the Wizards/All menu option from the Tools menu. A dialog box lists all available wizards that ship with Visual FoxPro. You won't find much 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 5.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
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
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. Tables 1 and 2 list the wizards and builders, respectively, that are included with Visual FoxPro 5.0.
Table 1. Wizards Included with Visual FoxPro 5.0
Wizard | Description |
Form | Creates a form based on a single table |
One-to-Many Form | Creates a One-to-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 One-to-Many report |
Label | Creates a mailing label report based on predefined styles |
Import | Imports a foreign file format to a Visual FoxPro table |
Documenting | Documents and formats Visual 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 Microsoft Graph |
Cross Tab | Creates a new cross tab table based on existing data |
Pivot Table | Creates a Microsoft Excel PivotTable based on Visual FoxPro data |
Mail Merge | Creates a Microsoft Word Mail Merge document based on Visual FoxPro data |
Upsizing | Moves Visual FoxPro data files to Microsoft SQL Server/Oracle files |
Application | Creates a predefined application or framework |
Setup | Creates installation program for distribution of custom apps |
Table 2. Builders Included with Visual FoxPro 5.0.
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 that cannot be satisfied by the existing engines. And finally, 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 each wizard. If you do not like the way the shipping wizards function, you can change the values in this table to suit your needs. For example, you can substitute your own Report Wizard by overwriting its corresponding Program field entry or you can add a new Wizard record to the table. The registration table structure is as follows:
Table 3. The Wizard Registration Table Structure
Field Name | Data Type | Width | Description |
Name | Char | 45 | The name of the wizard as it appears in the Wizard selection dialog box |
Descript | Memo | 4 | The description of the wizard as it appears in the Wizard selection dialog box |
Bitmap | Memo | 4 | The name of the bitmap with qualified path that appears in the Wizard selection dialog box |
Type | Char | 20 | Type of wizard to be called; allows only wizards of specific type to appear in Wizard selection dialog box |
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 the wizard .APP file if needed |
The following example shows the registration table 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 (for example _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 (for instance in the New File dialog box) that 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 (for example, 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 invokes a specific wizard. For example, you can select the New File dialog box, pick the Form option, and click on the Wizard button. Visual FoxPro will internally make the following call:
DO (_WIZARD) WITH 'FORM'
Because Wizard.app looks up all wizard types that 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 box. For example, if you pass 'FORM', you will see two wizards appearing in the selection dialog box: 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 to uParm9: The _WIZARD file accepts additional parameters that 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 (for example, 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:
Figure 1. The standard Wizard Selection dialog box
DO (_WIZARD) WITH 'query'.
If there is only one record that matches the Wizard Type mask, that wizard is launched without displaying the Wizard Selection dialog box. If no wizard is found matching the filter an alert appears indicating this fact.
Figure 2. A filtered Wizard Selection dialog box (first parameter)
DO (_WIZARD) WITH "","wzpivot"
Figure 3. Another filtered Wizard Selection dialog box (second parameter)
Note: You cannot programmatically call a wizard that uses the Classname field (as opposed to the Program field); however, a user can select it through the Wizard Selection dialog box.
DO (_WIZARD) WITH "","wzpivot","pivot" && calls Pivot Wizard
DO (_WIZARD) WITH "","wzpivot","xtab" && calls Cross Tab Wizard
DO (_WIZARD) WITH "AUTOFORM"
DO (_WIZARD) WITH "AUTOREPORT"
DO (_WIZARD) WITH "","WZGRAPH"
DO (_GENGRAPH) WITH "WIZARD"
DO (_GENGRAPH)
DO (_GENGRAPH) WITH "AUTOGRAPH",p2,p3,p4,p5,p6,p7,p8,p9
cParm1: Reference to output file name variable. This is a memory variable that gets passed back to Visual FoxPro when the wizard is finished. It contains the name of the wizard-generated file. Since Visual FoxPro hooks directly into the wizards through the Project Manager, this option allows you to create a new file (for example Form) via the wizard and have it automatically registered in the Project Manager.
cParm2: The contents of the Parms field in the wizard registration table.
uParm3 to uParm9: Extra parameters passed to _WIZARD. They are optional parameters that 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:
Figure 4. New Form dialog box
* 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
** Sample code returning Wizard output information ***
cOutPutContents = ''
cParm1= 'cOutPutContents'
DO WIZARDS\WZFORM WITH m.cParm1
? m.cOutPutContents
C:\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 (for example, Standard, Chiseled, Shadowed, Boxed, Embossed, and Fancy) and button code styles (for example, Text Buttons, Picture Buttons, and No Buttons). The same holds true with the visual styles associated with the Report Wizard (for example, 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 that the Form Wizard has an internal version of this table that contains records for the five visual styles and three button styles that ship with Visual FoxPro 5.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 that 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 fields in Table 4 are expected in Frmstyle.dbf.
Table 4. Fields 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 list box |
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 file name 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 code 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 ;
('fancyform','wizstyle.vcx','Fancy', ;
'V',.T.,.T.,.T.,'fancy.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 Step 2 of the Form Wizard, which is the Style page, you can see styles from Frmstyle.dbf in the Style list. The visual styles that appear in the list box all have a Styletype = 'V' for visual. The Form Wizard ships with three 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-style 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 (for example, 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 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 that can be handled by one of these fields. For example, the Picture Buttons style needs to check to see if the button graphic's .BMP files are properly installed; if not, they are copied out of Wzform.app.
The Form Wizard automatically loads Wizstyle.vcx into the SET CLASSLIB setting. So if you want to add custom styles, you can easily add them to Wizstyle.vcx. 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 that 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 (for example, Embossedform) and work off of it.
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.
1. Create the form class
Create your style form by subclassing Baseform or one of the other form styles (for example, Embossedform) in Wizstyle.vcx. You need to use Baseform, or a class derived from the Baseform class because it contains all of the custom properties that 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, Destroy (and so on) code you place in one of these classes could potentially break the Form Wizard. Be careful how you handle this.
Table 5 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.
Table 5. Custom Properties in the Baseform
Property | Description |
WizBtnLayout | Button position object (class) 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 laid out vertically |
WizBuffering | Table buffering for opened tables |
WizButtons | Name of button class |
WizCaptions | Whether to use DBC English field captions |
WizCboxLbl | Whether to use the check box 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 (One-to-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 that 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 (edit box) style |
WizMemo | Class reference for a Memo field |
WizOLE | Class reference for a General field |
WizPages | Allows use of pages for overflow of fields (0-none, 1-single column, 2-multicolumn) |
WizPageStyle | Class reference for Pageframe style |
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 explain how you can use them to enhance your styles.
2. Add the Layout object to the form
The second step in creating a custom form style for the Form Wizard is to add the Layout object (LayoutSty) to the form (Figure 6). The Layout object is a container of shapes that controls the horizontal/vertical spacing of objects (such as 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 that 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.
Figure 6. The Layout object
The Layout object provides dimensional information for field layout. There are four shapes and corresponding custom properties in the LayoutSty container class. The properties are used to reference the shapes.
Table 6. The Four Shapes in the LayoutSty Container Class
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 box 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 remain fixed in height. The Form Wizard only supports vertical stretching, whereas the Form Builder can stretch horizontally.
3. Specify control classes
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 (Figure 7). 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.
Figure 7. Creating classes for displaying field data on the form
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.
Figure 8. Registering data classes under custom properties
You need to be aware of the following points when you are creating and registering your custom styles for the Form Wizard:
The other type of field class is the container type, which is used by the Shadow, Chiseled, and Boxed visual styles. These classes are all derived from containers so that you can place a number of other objects inside. Each container must have a label and a data control (for example, a Textbox). Since the label is stored in the container, the WizLabel object is ignored. The primary purpose for using a container class is so that you can add special effects such as drop shadows, boxes, borders, and so on.
Important: You cannot mix the two types of field classes for a visual style. They must either be all free control classes or all container classes. The Form Wizard will generate an error if you try to mix the two.
Table 7. WizEffect Values and Descriptions
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 clicks the Preview button, the form is simply displayed. The form is only saved to an .SCX file if the Finish button is pressed. Then a Data Environment object is created with the selected data sources.
The Form Wizard also allows for the 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.vcx. Picbtns is simply a subclass of Txtbtns with pictures added.
Figure 9. The Text Button custom button style
You are free to overwrite and/or substitute your own button styles if the existing ones don't suit your particular needs. The section earlier in this article 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 that 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.vcx, 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 in order to prevent editing of any data. The Txtbtns class also contains a number of additional custom properties that 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.
Figure 10. An example form with vertical buttons
Figure 11. An example form with 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
Figure 12. Selecting button style and type
Figure 13. An example form with View Buttons
As with the Form Wizard, you can create custom report style templates. Fortunately, customizing styles for the Report Wizard is very simple to do. Unlike the Form Wizard, which utilizes object technology, the Report Wizard still relies on the old .FRX report structure. 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 that 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 example below shows the custom style used for horizontally listed fields. Because Visual FoxPro 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 in Figure 14. These are important because 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.
Figure 14. A custom style template
Table 8 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.
Table 8. Report Wizard Style Triggers
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 that horizontally separates fields in detail band |
wiz_vdivider | Comment | Denotes an object that 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 |
Figure 15 shows a One-to-Many custom style and how the fields are laid out. Note the Wiz_Parent label field. There is a (":")a suffix at the end, which tells the Report Wizard to place a colon after each field caption. You can place a suffix in any label. For example, you can add an ellipsis after the field caption by setting the label object's expression to "Wiz_Label...".
Figure 15. A One-to-Many custom style
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. Table 9 shows 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 paths for the various style .FRX files.
Table 9. Report Wizard Registration Table
Field Name | Data Type | Width | Description |
Stylename | Char | 20 | Style description that 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 Microsoft Graph directly to create charts. And while I recommend that 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 Structured Query Language (SQL) query/view prior to running _GENGRAPH. Use the following syntax:
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.)
parm10 - show nulls
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.
Table 10. Recommendations for Using Graph Wizard for Common Charts
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 Apple® Macintosh® product. MacGraph 5.0 does not support OLE Automation in the same fashion as its Microsoft Windows®–based 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 Macintosh product.
Visual FoxPro 5.0 allows you to extend the Table Wizard. This is new since Visual FoxPro 3.0. The Table Wizard includes a number of predefined tables such as Accounts, Artists, Books, and Customers. Each has common fields typically associated with these tables. In Visual FoxPro 3.0, these table definitions were bound to the Table Wizard itself. For version 5.0, we expose these tables so that users can edit or delete existing definitions or add new ones. The following tables are automatically copied out to the \Wizards directory when the Table Wizard is first run.
Table 11. Tables Automatically Copied to the \Wizards Directory
Tbwztbls.dbf | Contains all the table descriptions along with a their unique ID. The description is used for display in the wizard itself. |
Tbwzflds.dbf: | Contains a list of all unique fields along with their ID and description. |
Tbwzftyp.dbf | Contains field definition information such as width, decimals, and type. |
Tbwztfld.dbf | Links the table and field information together. |
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 a Referential Integrity (RI) Builder, but this is a slightly different beast. When the object technology is carried over to the 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 box 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 or augment existing ones. To do any of these enhancements or modifications, you must record them through the registration table if you intend to use 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.