User Interface Creation without Programming
Visual FoxPro provides powerful controls that you add with the Form Designer which gives you interfaces that require little or no coding. For example, having the grid control linked to one of your tables makes developing one-to-many forms easy. Just drag a table onto a form to create the grid control. For consistency with other applications you can also create tabbed dialog boxes or your own builder interfaces with the page frame control.
Creating a One-to-Many Form
Visual FoxPro makes it easy to set up forms to display records from related tables. Using the Project Manager Window and the Form Designer you can just “drag and drop” the fields you need to set up a form.
One-to-many forms display data from related tables.
Try setting up a one-to-many form using two related tables, such as the Customers and Orders tables from Testdata.dbc.
After four steps, one-to-many forms are…
…ready to run.
Specify Tables and Views for Your Form in the Data Environment You can use the data environment for your form or a report to specify the tables or views used by your form. After you have added the tables and views that have the records you want to display in your form, you can drag the fields to the Form Designer.
Create Grids by Selecting Multiple Fields You can select multiple fields and drag them to a form to create a grid object. If you select multiple fields and drag them with the right mouse button, you can choose between a grid or multiple controls. You can also click the Fields item in a table and drag it onto a form to create a grid incorporating all fields in the table. If you right-click a single field and drag it onto a form, you can create a different object class than the one that is assigned as the default object class.
Giving Your Form a Professional Look
Be creative and customize your forms with layout, colors, shapes, and graphics.
Align Controls Exactly Use the Layout toolbar to quickly line up controls and space them evenly on the form.
Change the Background Color Use the Color Palette toolbar.
Add Graphics and Pictures Use the Line, Shape, and Image buttons on the Form Controls toolbar.
Control Display and Data Entry in a Combo Box You can set the Format Property and InputMask Property for a Combo Box control.
Remove a Border on a Combo Box or Spinner You can use the BorderStyle Property to remove a border from the control. For example, if you are using combo box or spinner controls in a grid, you can clean up the display by removing the extra lines the border adds to the grid.
Use Current Windows Colors for Form Colors You can set an additional option on the ColorSource Property that lets you set the form colors based on the current Windows color scheme.
Setting the Properties on Controls
You can enhance your user interface with the control properties in Visual FoxPro. Using the Properties Window you can see and set the properties associated with each object in your form to determine how a form control looks and behaves.
Use Data Binding with ActiveX Controls To bind data to ActiveX controls you can use the ControlSource Property (if the control supports it) in the Properties window to specify a field or variable to which the control is bound.
Control Navigation in Page Frames By setting the tab order on your page frame you can control the order that pages are displayed. This also adds the ability to navigate to the different pages in a page frame with the right and left arrow keys.
Control Item Selection in List Box and Combo Box Controls To collect the actual value of the selected item in the control, you can set the BoundTo Property to True. To collect the item’s list index number, set the BoundTo property to False.
Select More Than 60 Items in a List Box You can now select an unlimited number of multiple items in a ListBox Control.
Create Hidden Properties and Methods You can set accessibility properties on the properties and methods you create to Public, Protected, or Hidden. To change the accessibility of properties and methods, use the Members Tab, Class Info Dialog Box.
| For more information about | See |
|---|---|
| Creating forms | Creating Forms |
| Using form wizards | Help by pressing F1 from the wizard. |
| Using builders | Help by pressing F1 from the builder. |
| Using controls | Help by searching on the control name or Using Controls |
| Using forms in applications | Creating Forms |
Customizing Your Form Designer
To make your work easier, you can customize the Form Designer to match your work style and needs.
Save Changes Automatically You can set options so Visual FoxPro saves your forms automatically when you quit the Form Designer. In the Forms Tab, Options Dialog Box you can choose the option to Save Changes Before Running Form. If you select this option, you skip the confirmation dialog box, and the changes you made to the current form are saved automatically.
Change the Font in the Properties Window You can choose one of three font settings from the Properties window shortcut menu.
Use the Keyboard in the Property Window The Properties window supports keyboard navigation for scrolling through the hierarchy of objects, controls, and tab orders. Use CTRL+PGUP and CTRL+PGDN to move up and down through the list.
| For more information about | See |
|---|---|
| The Form Designer and form controls | Form Designer |
| Creating forms | Creating Forms |
Add Controls from a Class Library
When you need to add controls to a form so you can navigate through the records in it, you can choose from a library of controls, drag in the controls you need, and run the form. It’s that simple.
Adding VCR Controls to a One-to-Many Form
You can use the following example to see how easy it is to streamline your work using controls from class libraries.
Store complicated control sets in a class library for reuse.
Add VCR Controls to a Form By opening the sample button class library (Buttons.vcx) supplied with Visual FoxPro, you can easily add a set of VCR-style navigation control buttons to your form. The sample libraries are in the Visual FoxPro …\Samples\Classes directory.
A class for VCR controls can be added to your toolbar.
Controls are easy to add to your form.
Set the SkipTable Property Because this is a one-to-many form, you need to specify that the next record in the main table is selected when you choose the Next button. To do this, open the Properties Window and set the SkipTable property so that it refers to the main table.
The SkipTable property adds the final functionality to your control.
Expanding Your Class Libraries
You don’t have to wait for someone else to sell you their control classes and libraries; you can make your own.
Create Your Own Classes You can create your own controls and save them in class libraries. You can start with standard Visual FoxPro classes and customize them to create your own version, or you can create your own classes.
Point to Classes in Compiled Applications You can use the SET CLASSLIB Command to point to a class included in a compiled application.
Add and Keep Classes on the Forms Control Toolbar When you add a class to the Forms Control toolbar, the class remains on the toolbar until you click the View Classes button again and select Standard.
View Detailed Information about Your Classes Using the Class Browser Window, you can view the entire hierarchy of classes and objects in a class library or form.
Create Your Own Subclasses of ActiveX Controls You can create subclasses of all the ActiveX controls shipped with Visual FoxPro.
| For more information about | See |
|---|---|
| Using the Class Designer | Help by pressing F1 from the Class Designer. |
| Setting properties | Creating Forms |
| Creating classes and using class libraries | Object-Oriented Programming |
Creating a Menu Bar and Shortcut Menus
You can use the Menu and Shortcut Designers to add a menu bar and menus to forms in your application. With the Menu and Shortcut Designers you can create shortcut menus and menus for SDI forms.
When you create a menu, you have the option of adding a menu to the menu bar or creating a shortcut menu. The Shortcut Designer presents the familiar Menu Designer interface, but allows you to design shortcut menus rather than menu bars and menus.
After you have generated your shortcut menu, you can attach it to any control by running the menu in the control’s RightClick Event.
Creating Reports
When it’s time to print out important data, you don’t want to spend a lot of time formatting reports. That’s why Visual FoxPro provides report wizards to streamline the reporting process. With report wizards you can select the data you want from your tables and views, and present it in your choice of professional looking formats.
It’s easy to combine information from two different tables in a one-to-many report.
Using the Visual FoxPro report design features, you can:
Use the Preview Button The last screen of a report wizard has a Preview button so you can quickly see if your report is the way you like it. If not, use the Back button in the wizard and make the necessary adjustments.
Use Quick Report for Fast Results If you’re setting up your own report in the Report Designer, choose Quick Report from the Report menu to add selected fields from a table to a report.
Use Query or View Results in a Report Want to print out the results of a query? Choose the Report option in the Query Destination Dialog Box. You can send the query results to a pre-formatted report or send the query to a report wizard.
Create a One-To-Many Report The One-To-Many Report Wizard makes it easy to set up a report that shows fields from two tables joined in a one-to-many relationship. For example, try using the wizard to create a report from two related tables in Testdata.dbc.
Report Wizards retrieve records and format the report layout.
Use Other Report Wizards Try using the other report wizards. For simple one-table reports or summary reports with totals, choose Report Wizard.
Use the Report Designer If you want to customize your wizard-generated report further, just open it in the Report Designer and add the enhancements you need.
| For more information about | See |
|---|---|
| Report Wizards | Help by pressing F1 from the wizard. |
| Report Designer | Adding Reports and Labels |
Providing a Help System
You can add value to your application by creating a Help system. Using the Help compiler included with Visual FoxPro, you can turn your document files into a graphical Help system to distribute with your applications. If you prefer to use a Visual FoxPro table to store your help information, you can create .DBF-style help. You can find a sample, Ttrade.dbf, in the …\Samples\Taztrade\Help directory. For more information about creating WinHelp and HTML Help, see Creating Graphical Help or Creating .DBF-Style Help.
See Also
Overview of Visual FoxPro Features | Application Management with the Project Manager | Rapid Application Creation | Application Customization with Designers | Form Designer. | Creating Forms
Rapid Application Creation
You can develop applications rapidly with help from Visual FoxPro wizards, builders, toolbars, and designers. In addition, with the Visual FoxPro object and event model, you can create prototypes and implement applications quickly.
Getting Quick Results with Wizards and Builders
Using wizards and builders, you can have any or all of the components of your application completed in a matter of minutes. In addition, if any component you create with a wizard or builder does not fully meet your needs, you can alter the component using a designer.
Creating an Application Now
For quick results, wizards are the answer. They provide step-by-step prompts for common tasks you perform in Visual FoxPro. For example, the Table Wizard guides you through the process of creating a table, the Form Wizard creates a form, and the Web Publishing Wizard helps you create a Web page that searches your tables.
Take a look at what you can do:
- Develop Instant Applications Using the Application Wizard, you can quickly create an application by using your tables and forms, or by using a sample set of application components.
- Create an Internet Web Page You can create a Web page that provides Web surfers with search and retrieval access to your tables.
- Add Page Frames to Forms If you choose more fields than can fit on the form, you can add a page frame to display the additional fields on additional pages.
- Populate Pivot Tables through ODBC The PivotTable Wizard uses the Visual FoxPro ODBC driver.
- Show Nulls in a Cross-Tab Report The Cross-Tab Wizard now supports displaying null values.
- Move Your Data to a Back-End Server You can move Visual FoxPro databases, tables, and views from your system to a back-end server with the SQL Server Upsizing Wizard.
If you are in a hurry, use the table in Wizards Overview to select a wizard, and begin creating your application or component.
If you do not want to experiment with your own data and application components, use the samples provided with Visual FoxPro. You can work in the sample database Testdata.dbc, located in the …\Samples\Data directory.
Taking Shortcuts with Toolbars
Like other Microsoft applications, Visual FoxPro includes toolbars containing buttons that represent common tasks you perform or objects you use frequently. To perform a specific task or use a particular object, choose the appropriate button.
You can customize the toolbars that come with Visual FoxPro. You can also define custom toolbars for the applications you write. For more information about toolbars, see Customizing the Visual FoxPro Environment or Designing Menus and Toolbars.
Building Controls Quickly
Just as wizards can help to create reports and forms, builders are visual tools that help you design controls to your specifications. Builders can save you time when you are setting up many forms or prototyping applications. All you do is start the builder and answer a series of questions. Using your answers, the builder sets properties for the control you are adding.
Add a Combo Box to Your Form Suppose you want to enhance a simple form you created by adding the ability to select field values from a list, rather than moving through all the records with VCR buttons and viewing the values in a text box. Just replace the current text box with a combo box and use a builder to set the properties.
Modify Existing Controls with a Builder If you want to change an existing control, you can select the control and use a builder to help you set the control’s properties.
For example, the Combo Box Builder is a tabbed dialog box that helps you design a combo box on a form. A combo box gives you the same view of a value as a text box control, but allows you to choose from a list like a list box control. With this builder you can set properties of a combo box. As you set each property, the control on the form changes to match the settings.
The Builder Lock button and Combo Box button

The tabs in the Combo Box Builder dialog box

Build a Grid Control To display a small spreadsheet-like view of your data, you can use a grid control. Even if you aren’t familiar with all the properties of a grid control, you can still take advantage of their functionality using a builder. The builder helps you choose the fields for your grid, select a style and layout, and establish relationships between tables bound to the grid control. As you make changes in the builder, they are reflected in the Form Designer.
Visual FoxPro offers a wide selection of builders.
| To | Use this builder |
|---|---|
| Format a group of controls | AutoFormat Builder |
| Build a combo box | Combo Box Builder |
| Build a command group | Command Group Builder |
| Build an edit box | Edit Box Builder |
| Create and edit expressions | Expression Builder |
| Build a form | Form Builder |
| Build a grid | Grid Builder |
| Build a list box | List Box Builder |
| Build an option group | Option Group Builder |
| Ensure referential integrity | Referential Integrity Builder |
| Build a text box | Text Box Builder |
The Advantages of More Power
Visual FoxPro is much more powerful than its predecessors. Object-oriented programming speeds up application development through features such as subclassing. The Visual FoxPro event model eliminates the need to use foundation READ or write event handlers. Optimizing your system settings and implementing Rushmore technology improves the performance of Visual FoxPro.
Harnessing the Power of Object-Oriented Programming
Using the Visual FoxPro object model, you can employ all the features of object-oriented programming including inheritance, encapsulation, polymorphism, and subclassing. For details about object-oriented programming with Visual FoxPro, see Object-Oriented Programming.
You can speed up application development by using classes. For example, you can create a basic form, toolbar, or page frame by using the form, toolbar, or page frame base class provided with Visual FoxPro.
Then you can reuse your code and forms by subclassing the classes you defined. For example, you can subclass the Form base class to create a custom class that automatically gives all the forms in your application the look and feel you want.
The Visual FoxPro class model gives you extensive control over the objects in your application. You have as much control of the appearance and behavior of objects on forms at run time as you do in the Form Designer at design time.
With Visual FoxPro, you can create classes visually with the Class Designer or programmatically with the DEFINE CLASS Command. For more information, see Object-Oriented Programming.
Handling Events with Ease
With Visual FoxPro you can create fully event-driven applications. You can access all standard Windows events such as mouse movements that permit dragging or dropping objects. You can control events visually through the Properties window or programmatically through the Visual FoxPro language. For more information about the event model, see Understanding the Event Model.
Testing and Debugging Immediately
Using the debug environment you can test and debug your code at the same time you design each component of your application and write the code. The Visual FoxPro language has been enhanced to include support for debugging capabilities, collection properties, checking the lock status of files and the current record, Value tips, and more. Also, the debugging tools work independently from the main application and do not interfere with the interface you are trying to test.
Test as You Design The enhanced Visual FoxPro development environment gives you more power to test your component design and code. For example, if you are designing a form, you can click the Run button to run the code. If you want to change something, just click the Design button and make your changes.
Catch Syntax Errors Early The editor now features color-coded editing: you can specify colors for syntax, normal text, variables, comments, and more in the Edit Properties Dialog Box. If you mistype a command or keyword, you’ll know right away because it’s the wrong color.
Debug with Power
You can debug and monitor your application components more easily in this version of Visual FoxPro using the Debugger Window.
- View Properties of an Object In the debugger you can view the elements within a collection or array using the Watch Window to show a hierarchical display of an object’s properties.
- Trace the Execution Process of Your Code In the Trace Window you can see each line of code as it executes and check the values of all variables, properties, and environment settings.
- Control Execution with Breakpoints Using breakpoints you can control when execution stops using one of four types of breakpoints. You can stop at a particular line, when a certain value changes, if a condition evaluates to true, or if a condition for a certain line is true.
- Set Asserts and Display Assert Messages You can use the ASSERT Command to specify conditions that verify that the code is running properly. When an error occurs, the Debug Output Output Window records the message.
- Check the Current Value of a Variable To quickly check values you can place the cursor over a variable in the Trace Window to display a Value Tip.
- Watch and Change Values In the Watch Window and Locals Window you can change values for properties or variables while you run the code.
- Display Output from Message Requests In the Debug Output Window you can conveniently display interactive or coded information requests in a separate window from the active window or screen.
- Use a Coverage Log File In the Debugger Window you can use the coverage option to log the execution information about your code such as how long the line took to execute, the line number, and more.
For more information about testing and debugging your application, see Testing and Debugging Applications.
Optimizing Your System
Visual FoxPro brings you improved performance across all these product areas:
- Engine
- Form/Object
- OLE
- Client/Server
- Wizards/Builders
- Language
You can also improve performance by enhancing startup speed and optimizing SET commands. For more information about optimizing your system, see Optimizing Your System.
Optimizing Applications with Rushmore Technology
You can dramatically improve the performance of queries by using Rushmore technology. Rushmore is an exclusive technology for rapidly selecting sets of records from tables. It can reduce query response times from hours or minutes to seconds. For more information about using the Rushmore technology, see Optimizing Applications.
Interaction with Other Applications
With Visual FoxPro you can share data with other applications such as Microsoft Excel and Word, use objects from other applications, and control other applications using Automation.
Sharing Data with Other Applications
You can take advantage of all the software tools on your desktop with Visual FoxPro.
Use Your FoxPro Data in Other Applications Sharing data with other applications is easy – for example, you can share Visual FoxPro data with Microsoft Excel by using the PivotTable Wizard, or with Microsoft Word by using the Mail Merge Wizard.
Display or Store Objects from Other Applications You can include objects from another application by linking or embedding them in tables or in forms. Then you can edit the objects directly, without leaving Visual FoxPro.
Editing included objects is easy in Visual FoxPro.

Importing and Exporting Data
You can import and export data between Visual FoxPro and many other applications using a variety of file formats: text, spreadsheets, and tables, to name a few. The data can be appended to or copied from existing tables easily. The Import Wizard helps you make decisions about the structure you want the data to take in Visual FoxPro.
For more information, see Importing and Exporting Data.
Integrating with Automation
With Visual FoxPro you have the power to fully integrate your application with other applications.
Control Other Applications You can extend the power of your application by controlling other applications programmatically. For example, you can direct Microsoft Excel to perform some calculations, instruct Microsoft Graph to chart the results, and then store the chart in a General field of a Visual FoxPro table, all from Visual FoxPro code. Or, you can add ActiveX controls that you or someone else developed.
Optimize Automation Requests You can determine how much time your system uses for requests and how long it takes for messages to appear for your user. For example, you can control how much time your system spends retrying Automation requests before displaying a “server busy” message.
You can also control the number of milliseconds that pass during user input, such as using the mouse or keyboard while an Automation request is pending, and a “busy” message appearing.
Control Visual FoxPro from Other Applications Using Visual FoxPro as an Automation server, you can create references to Visual FoxPro objects, execute Visual FoxPro commands, and run Visual FoxPro programs from other applications.
For more information on Automation, see Adding OLE.
Creating Active Documents
Active Documents are non-HTML documents viewed in a web browser such as Microsoft Internet Explorer. You can now create Active Document applications in Visual FoxPro. A Visual FoxPro Active Document is an application (.app) created from a Visual FoxPro project whose main file is set to a class based on the ActiveDoc base class.
Use the Project Manager and the Class Designer to create your Active Doc application. For more information on creating Visual FoxPro Active Documents, see Interoperability and the Internet. See ActiveDoc Object for details on its properties events and methods.
Client/Server Solution Development
You can use Visual FoxPro as a front end for developing robust client/server applications. Visual FoxPro combines the higher-level support of updatable views of server data with direct access to native server syntax using SQL pass-through. This gives you a solid foundation on which to build versatile client/server solutions. A full-featured data dictionary, local and remote views, null support, transactions, international application support, and access to any ODBC data source all contribute to the features you need for client/server development.
Increasing Client/Server Performance
You can increase the performance of your client/server application using the properties and ODBC driver provided in Visual FoxPro.
Controlling Performance with Properties
You can increase performance by using the following cursor and remote view properties:
- CompareMemo
- FetchAsNeeded
- Prepared
You can display these properties using the DBGETPROP( ) Function and CURSORGETPROP( ) Function functions, or set the properties with the DBSETPROP( ) Function and CURSORSETPROP( ) Function functions.
Include or Exclude Memo Fields in Update Detection You can use the CompareMemo property to control when memo fields are used to detect update conflicts. This view and cursor property determines whether memo fields (types M or G) are included in the update WHERE clause. The default setting, True (.T.), means that memo fields are included in the WHERE clause. If you set this property to False (.F.), memo fields don’t participate in the update WHERE clause, regardless of the settings of UpdateType.
Optimistic conflict detection on Memo fields is disabled when CompareMemo is set to False (.F.). For conflict detection on memo values, CompareMemo should be set to True (.T.).
Fine Tune Record Fetching Use the FetchAsNeeded property to specify if all rows are fetched progressively, or only those within the row set determined by the FetchSize property. If you want to fetch all of the rows in the result set using the Visual FoxPro idle loop, use the default setting, False (.F.). If you want to fetch only when the user scrolls beyond the row set determined by the FetchSize property, set FetchAsNeeded to True (.T.) to fetch the next row set.
Speed Up Re-query Operations on Parameterized Views Using the Prepared property, you can set whether the query for the view is prepared before it is executed. If you set this property to True (.T.), Visual FoxPro sends a request to the ODBC driver to prepare or compile the SQL query that defines the view. If the ODBC driver for your back-end data source supports the use of prepared statements, subsequent re-queries on the open view are executed faster.
Using ODBC for Quick Access to Visual FoxPro Data
The Visual FoxPro ODBC Driver provides quick access to Visual FoxPro data. End users and developers of many applications, including Microsoft Access, Microsoft Excel, Visual C++, and Visual Basic, can use this driver to retrieve, manipulate and update Visual FoxPro data. For more information about the Visual FoxPro ODBC Driver, see the Drvvfp.hlp file.
Defining Rules with the Data Dictionary
Visual FoxPro databases (.dbc files) provide a data dictionary that allows you to add rules, views, triggers, persistent relationships, and connections to every table in a database.
Within a database you can define:
- Field-level or record-level rules that Visual FoxPro enforces wherever the table is used in an application.
- Primary and candidate index keys.
- Local and remote views.
- Triggers.
- Persistent relationships between database tables.
- Connections to remote data sources.
- Stored procedures.
- Default values on fields.
- Long table and field names.
In addition, you can enforce referential integrity for every persistent relationship by using the Referential Integrity Builder to define rules for inserts, updates, and deletes.
Visual FoxPro also supports null values in tables, greatly improving compatibility and connectivity with other data sources such as Microsoft Access, Visual Basic, and SQL-based servers. For details about null values, search for “null” and “null values”.
Each Visual FoxPro database is completely user-extensible, with access through language enhancements and the visual designers. For more information about databases and data dictionaries, see Creating Databases.
View Local, Remote, and Offline Data You can design and test a client/server application on your local computer using data from remote, local, or multiple-table heterogeneous views. Local views use tables on your local computer rather than tables on a remote server, and multiple table views use related data from separate tables. You can create parameterized views to minimize the amount of data you download from the server, take the data on the road, or update remote data from your Visual FoxPro application. For more information about views see Creating Views.
Manage Shared Access with Transactions You can design your application to provide shared access to data. Shared access involves sharing data among users and restricting access when necessary. Transactions and buffering — pessimistic or optimistic, record-level or table-level — mean less programming for you. Built-in batch processing and detailed control over handling update conflicts simplifies updating data in a multiuser environment. For details about designing your application for shared access, see Programming for Shared Access.
Develop International Applications Visual FoxPro provides several areas of support for developing international applications. For example, Visual FoxPro supports several code pages. The code pages for Greek and Russian are supported on MS-DOS, Microsoft Windows, and Macintosh platforms. Visual FoxPro also supports double-byte character sets for languages such as Japanese, Korean, Traditional Chinese, and Simplified Chinese. In addition, Visual FoxPro supports collation sequences for languages such as Japanese, German, Traditional Chinese, and Icelandic. For more information about international applications, see Developing International Applications.
Implement a Client/Server Application In addition to using views for client/server development, you can send any native server syntax you want directly to a server with Visual FoxPro SQL pass-through functions. These functions permit additional server access and control beyond the capability of views. For details about SQL pass-through see Implementing a Client/Server Application.
After designing your application locally, you can upsize and implement it against a back-end data source. Upsizing applies the benefits of client/server architecture to the local application and allows you to create a remote server database with the same table structure and data as the original Visual FoxPro tables. When you upsize, you choose which tables move to the server and which remain locally for more immediate access. For details about upsizing see Upsizing Visual FoxPro Databases.
Visual FoxPro and XML
Extensible Markup Language (XML) is the standard language for describing and delivering data on the Web, just as Hypertext Markup Language (HTML) is the standard language for creating and displaying Web pages. XML uses tags and attributes to delimit pieces of data, and leaves the interpretation of the data completely to the application that reads it. For more details, see XML Functions.
To make it possible for you to more easily implement data exchange via XML, Visual FoxPro provides new functions and functionality in the following functions:
- CURSORTOXML( ) Converts a Visual FoxPro cursor into XML.
- XMLUPDATEGRAM( ) Creates an XML UpdateGram from changes made to a buffered table or cursor.
- XMLTOCURSOR( ) Converts XML data to a Visual FoxPro cursor or table.
Miscellaneous XBase Features
Visual FoxPro includes a number of new and improved XBase features, those written in the Visual FoxPro language itself. These include new tools such as the Task List Manager, Object Browser, IntelliSense Manager, Accessibility Browser, Automated Test Harness and Web Services wizard. These are described in more detail in other What’s New topics.
In addition to the above-mentioned features, Visual FoxPro contains a wealth of other XBase improvements.
- New Foundation Classes have been added for use with Microsoft Agent, Regular Expressions, Cryptography, Enhanced File Open dialog boxes, Windows 2000 Logo information, and Web Services.
- The SQL Server Upsizing wizard contains a number of new improvements.
- New Solution samples have been added to better illustrate some of the new Visual FoxPro features and foundation classes.
- A new set of COM+ Service samples show how you can use Visual FoxPro servers with COM+ Services such as Transactions, Queued Components, COM+ Events and Compensating Resource Managers. Many of these samples use new Visual FoxPro server enhancements.
- GENMENU has been updated to support new image support for menus. A new directive (#IMAGEPATHS) has been added to control if full paths are generated for menu images.
Visual FoxPro OLE DB Provider
The Visual FoxPro OLE DB Provider makes it possible for application developers to access Visual FoxPro data from other languages and applications, as well as from Visual FoxPro when appropriate. The Visual FoxPro provider exposes OLE DB interfaces to consumers wanting access to data on one or more Visual FoxPro databases. You can use it as part of an OLE DB consumer for Visual FoxPro databases.
The Visual FoxPro OLE DB Provider supports new Visual FoxPro features, such as database container (DBC) events, access to stored procedures, and the ability to create, modify, and delete functions and procedures in the DBC stored procedure module.
In the Visual FoxPro OLE DB Provider, you will find an improved threading model for better scalability and all the functionality of the Visual FoxPro ODBC driver of earlier versions of FoxPro.
Behavior Changes since the Previous Version
This section describes behavioral characteristics of Visual FoxPro that differ from those of the previous version. It is possible that these changes affect existing code.
- _SCREEN and _VFP coordinate properties (Top, Left, Height, Width) have been changed to better distinguish between the two windows they represent. The _VFP coordinates represent the entire Visual FoxPro application window (including menu and status bars). The _SCREEN coordinates represent the desktop area (for example, the window to which ? output is directed).
- For performance reasons, the CreateObject( ) function no longer adds a sequential number to the value for a dynamically created Name property. This applies to class definitions in .PRG files that do not have an explicitly set Name property and base classes.
- Because of new support for IntelliSense and COM server typing (for example, LOCAL cName AS string), the use of a variables list separated by spaces only (for example, LOCAL x y z) is no longer allowed. You must separate variables with commas (for example, LOCAL x, y, z).
- The Session class now hides intrinsic properties, methods, and events in the generated type library for an OLEPUBLIC subclass. Additionally, when using a private data session with a Session object, the default setting for SET TALK, SET EXCLUSIVE, SET SAFETY is now OFF.
- The VERSION( ) format has changed. The Build number is now the last set of digits. This also might affect usage of the AGETFILEVERSION() function in your code.
- Some of the values of HOME([n]) have changed. Some of these changes only apply to an installation of Visual Studio. The location of the Samples and Graphics folders is now under the Visual FoxPro root directory.
- The new default location to save files has been changed for compliance with Windows 2000 Logo guidelines. You can view (and change) this location from the Options dialog box (File Locations tab).
- The format for menus (MNX file) has changed to include new Picture support.
- The format for a database (DBC) file will be altered if DBC Events is enabled. This will render the DBC incompatible with prior versions of Visual FoxPro and the ODBC driver. You can restore backward compatibility by disabling DBC events for the DBC. The Visual FoxPro OLE DB provider does support DBC Events.
- The Command window contents are now persisted between sessions of Visual FoxPro. The contents are stored in a file named _command.prg.
- The resource file (for example, FOXUSER) is now opened shared, so you can run multiple instances of Visual FoxPro using the same FOXUSER file. As in prior versions, you can set the resource file from the Options dialog box.
- The Visual FoxPro run-time libraries (for example, VFP7T.DLL) are no longer installed in the WinSys directory. Additionally, resource files for other languages are now installed with the English product.
- The Properties window stays open when it is set as Dockable, even if the current form/class designer is closed.
- Old FoxBASE+ support for FOXGRAPH, FOXVIEW, FOXGEN, FOXCODE, CENTRAL, and ASSIST is no longer supported.
- The Windows Explorer shell open functionality for known Visual FoxPro file types now launches a new instance of Visual FoxPro. Additionally, Program and Query files support both Open and Run support. The default for Program files is now Open instead of Run as in previous versions.
- The Class/Form Designer surface grid now displays in actual grid coordinates instead of the behavior of previous versions of Visual FoxPro, which was to display in 2x actual setting.
- Grid column headers now allow for display of keyboard shortcuts. This is for display only, so developers must write code to handle the shortcut action.
- Search path for #INCLUDES has been extended for PRGs, SCXs and VCXs.
- The format of the event-tracking log generated using the SET EVENTTRACKING command now includes a TimeStamp column.
- The _DBLCLICK system variable no longer controls incremental search duration for controls such as list boxes. Now this is handled by a new system variable called _INCSEEK.
- A startup application (for example, VFP7Strt.app) no longer ships with Visual FoxPro.
- The nStartPos parameter for ASCAN() will only produce an error if a value of 0 is passed. Values passed which are larger than the length of the array will return 0.
- In previous versions,
CREATE TABLE ... NAME LongTableNamesubstituted spaces with underscores (“_”) for the LongTableName when called programmatically. This would not occur when specified in the Table Designer. In this version, spaces are now preserved, which is now consistent with the behavior of the Table Designer.
Feature Changes since the Previous Version of Visual FoxPro
The following features from the previous version of Visual FoxPro have been removed from the product:
- The Spell Checker is no longer included with the product.
- The Setup wizard is no longer included with the product. A Microsoft Installer based deployment tool will be available. For details, see Distributing Applications.
- The Graph runtime is no longer included, because it was primarily for distribution with the Setup wizard.
- The Run ActiveDoc menu item is no longer in the product, but the program is still available and can be called from the Do menu.
- Several of the MSDN menu items have been removed from the Help menu. Online documentation for the product is available in a stand-alone help file as well as in the MSDN Library. Additionally, the Microsoft on the Web submenu has been replaced with a single Visual FoxPro on the Web menu item.
- The Calendar, Outline, and FoxHWnd controls no longer ship with Visual FoxPro.
- The Visual FoxPro ODBC Driver no longer ships with Visual FoxPro. This is available from the Visual FoxPro Web site (http://msdn.microsoft.com/vfoxpro/). The Visual FoxPro OLE DB Provider is the preferred solution for clients accessing Visual FoxPro data remotely.
Classes and Objects: The Building Blocks of Applications
Classes and objects are closely related, but they are not the same. A class contains information about how an object should look and behave. A class is the blueprint or schematic of an object. The electrical schematic and design layout of a telephone, for example, would approximate a class. The object, or an instance of the class, would be a telephone.
Objects Have Properties
An object has certain properties, or attributes. For example, a phone is a certain color and size. When you put a phone in your office, it has a certain position on your desk. The receiver can be on or off the hook.
Objects you create in Visual FoxPro also have properties that are determined by the class the object is based on. These properties can be set at design time or at run time.
For example, some of the properties that a check box can have are listed in the following table:
| Property | Description |
|---|---|
| Caption | The descriptive text beside the check box. |
| Enabled | Specifies whether a user can choose the check box. |
| ForeColor | The color of the caption text. |
| Left | The position of the left side of the check box. |
| MousePointer | How the mouse pointer looks when over the check box. |
| Top | The position of the top of the check box. |
| Visible | Specifies whether the check box is visible. |
Objects Have Associated Events and Methods
Each object recognizes and can respond to certain actions called events. An event is a specific and predetermined activity, initiated by either a user or the system. Events, in most cases, are generated by user interaction. For example, with a phone, an event is triggered when a user takes the receiver off the hook. Events are also triggered when the user presses the buttons to make a call.
In Visual FoxPro, user actions that trigger events include clicks, mouse moves, and key presses. Initializing an object and encountering a line of code that causes an error are system-initiated events.
Methods are procedures that are associated with an object. Methods are different from normal Visual FoxPro procedures: methods are inextricably bound with an object and are called differently than normal Visual FoxPro procedures are called.
Events can have methods associated with them. For example, if you write method code for the Click event, that code is executed when the Click event occurs. Methods can also exist independently of any events. These methods must be explicitly called in code.
The event set, while extensive, is fixed. You can’t create new events. The method set, however, is infinitely extendible.
The following table lists some of the events associated with a check box:
| Event | Description |
|---|---|
| Click | User clicks the check box. |
| GotFocus | User selects the check box by clicking it or tabbing to it. |
| LostFocus | User selects another control. |
The following table lists some of the methods associated with a check box:
| Method | Description |
|---|---|
| Refresh | The value of the check box is updated to reflect any changes that may have occurred to the underlying data source. |
| SetFocus | The focus is set to the check box just as though the user had pressed the TAB key until the check box was selected. |
Classes in Visual FoxPro
All of the properties, events, and methods for an object are specified in the class definition. In addition, classes have the following characteristics that make them especially useful for creating reusable, easily maintained code:
- Encapsulation
- Subclasses
- Inheritance
Hiding Unnecessary Complexity
When you include a phone in your office, you probably don’t care how the phone internally receives a call, initiates or terminates connections to electronic switchboards, or translates key presses into electronic signals. All you need to know is that you can lift the receiver, dial the appropriate numbers, and talk to the person you want to talk to. The complexity of making that connection is hidden. The benefit of being able to ignore the inner details of an object so you can focus on the aspects of the object you need to use is called abstraction.
Encapsulation, which involves packaging method and property code together in an object, contributes to abstraction. For example, the properties that determine the items in a list box and the code that executes when you choose an item in the list can be encapsulated in a single control that you add to a form.
Leveraging the Power of Existing Classes
A subclass can have all the functionality of an existing class, plus any additional controls or functionality you want to give it. If your class is a basic telephone, you can have subclasses that have all the functionality of the original telephone and any specialized features you want to give them.
Subclassing is one way to decrease the amount of code you have to write. Start with the definition of an object that is close to what you want, and customize it.
Streamlining Code Maintenance
With inheritance, if you make a change to a class, that change is reflected in all subclasses based on the class. This automatic update saves you time and effort. For example, if a phone manufacturer wanted to change from dial to push-button style phones, it would save a lot of work to be able to make the change to the master schematic and have all previously manufactured phones based on that master schematic automatically inherit this new feature, rather than having to add the new feature to all the existing phones individually.
Inheritance doesn’t work with hardware, but you do have this capability in software. If you discover a bug in your class, instead of having to go to each subclass and change the code, you fix it once in the class and the change propagates throughout all subclasses of the class.
Containers and Non-Containers
The two primary types of Visual FoxPro classes, and by extension Visual FoxPro objects, are container classes and control classes.
Container Classes
Containers can contain other objects and allow access to the objects contained within them. For example, if you create a container class that consists of two list boxes and two command buttons, and then add an object based on this class to a form, each individual object can be manipulated at run time and design time. You can easily change the positions of the list boxes or the captions of the command buttons. You can also add objects to the control at design time; for example, you can add labels to identify the list boxes.
The following table lists what each container class can contain:
| Container | Can contain |
|---|---|
| Command button groups | Command buttons |
| Container | Any controls |
| Control | Any controls |
| Custom | Any controls, page frame, container, custom |
| Form sets | Forms, toolbars |
| Forms | Page frames, any controls, containers, custom |
| Grid columns | Headers and any objects except form sets, forms, toolbars, timers, and other columns |
| Grids | Grid columns |
| Option button groups | Option buttons |
| Page frames | Pages |
| Pages | Any controls, containers, custom |
| Project | Files, servers |
| Toolbars | Any controls, page frame, container |
Control Classes
Control classes are more completely encapsulated than container classes are, but can be less flexible for that reason. Control classes do not have an AddObject method.
Preparation for Class Creation
You want to be able to use classes in many different contexts. Smart planning will enable you to most effectively decide what classes to design and what functionality to include in the class.
Deciding When to Create Classes
You could create a class for every control and every form you might ever use, but this isn’t the most effective way to design your applications. You’ll likely end up with multiple classes that do much the same thing but must be maintained separately.
Encapsulate Generic Functionality
You can create a control class for generic functionality. For example, command buttons that allow a user to move the record pointer in a table, a button to close a form, and a help button, can all be saved as classes and added to forms any time you want the forms to have this functionality.
You can expose properties and methods on a class so that the user can integrate them into the particular data environment of a form or form set.
Provide a Consistent Application Look and Feel
You can create form set, form, and control classes with a distinctive appearance so that all the components of your application have the same look. For example, you could add graphics and specific color patterns to a form class and use that as a template for all forms you create. You could create a text box class with a distinctive appearance, such as a shadowed effect, and use this class throughout your application any time you want to add a text box.
Deciding What Type of Class to Create
Visual FoxPro allows you to create several different kinds of classes, each with its own characteristics. You specify the type of class you want to create in the New Class dialog box or in the AS clause in the CREATE CLASS command.
The Visual FoxPro Base Classes
You can create subclasses of most of the Visual FoxPro base classes in the Class Designer.
Visual FoxPro Base Classes
* These classes are an integral part of a parent container and cannot be subclassed in the Class Designer.
All Visual FoxPro base classes recognize the following minimum set of events:
| Event | Description |
|---|---|
| Init | Occurs when the object is created. |
| Destroy | Occurs when the object is released from memory. |
| Error | Occurs whenever an error occurs in event or method procedures of the class. |
All Visual FoxPro base classes have the following minimum set of properties:
| Property | Description |
|---|---|
| Class | What type of class it is. |
| BaseClass | The base class it was derived from, such as Form, Commandbutton, Custom, and so on. |
| ClassLibrary | The class library the class is stored in. |
| ParentClass | The class that the current class was derived from. If the class was derived directly from a Visual FoxPro base class, the ParentClass property is the same as the BaseClass property. |
Extending the Visual FoxPro Base Classes
You can subclass these classes to set your own default control properties. For example, if you want the default names of controls you add to forms in your applications to automatically reflect your naming conventions, you can create classes based on the Visual FoxPro base classes to do this. You can create form classes with a customized look or behavior to serve as templates for all the forms you create.
You could also subclass the Visual FoxPro base classes to create controls with encapsulated functionality. If you want a button to release forms when the button is clicked, you can create a class based on the Visual FoxPro command button class, set the caption property to “Quit” and include the following command in the Click event:
THISFORM.Release
You can add this new button to any form in your application.
Creating Controls with Multiple Components
Your subclasses aren’t limited to single base classes. You can add multiple controls into a single container class definition. Many of the classes in the Visual FoxPro sample class library fall into this category.
Creating Non-Visual Classes
A class based on the Visual FoxPro custom class doesn’t have a run-time visual element. You can create methods and properties for your custom class using the Class Designer environment. For example, you could create a custom class named StrMethods and include a number of methods to manipulate character strings. You could add this class to a form with an edit box and call the methods as needed. If you had a method called WordCount, you could call it when needed:
THISFORM.txtCount.Value = ; THISFORM.StrMethods.WordCount(THISFORM.edtText.Value)
Non-visual classes (like the custom control and the timer control) have a visual representation only at design time in the Form Designer. Set the picture property of the custom class to the .bmp file you want displayed in the Form Designer when the custom class is added to a form.
Operating the Class Designer
When you specify what class your new class is based on and the library to store the class in, the Class Designer opens.
The Class Designer provides the same interface that the Form Designer does, allowing you to see and edit the properties of your class in the Properties window. Code editing windows allow you to write code to be executed when events occur or methods are called.
Adding Objects to a Control or Container Class
If you base the new class on the control or container class, you can add controls to it the same way you add controls in the Form Designer: choose the control button on the Form Controls toolbar and drag to size in the Class Designer.
No matter what type of class you base the new class on, you can set properties and write method code. You can also create new properties and methods for the class.
IF you press and hold the CTRL key while dragging objects from the toolbar to a form class, you disengage the default snap-to-grid behavior.
Adding Properties and Methods to a Class
You can add as many new properties and methods to the new class as you want. Properties hold values; methods hold procedural code to be run when you call the method.
Creating New Properties and Methods
When you create new properties and methods for classes, the properties and methods are scoped to the class, not to individual components in the class.
To add a new property to a class
- From the Class menu, choose New Property.
- In the New Property dialog box, type the name of the property.
- Specify the visibility: Public, Protected, or Hidden. A Public property can be accessed anywhere in your application. Protected and Hidden properties and methods are discussed in Protecting and Hiding Class Members.
- Choose Add. You can also include a description of the property that will be displayed at the bottom of the Properties window in the Class Designer and in the Form Designer when the control is added to a form. Caution When you add a property to a class that can be set by a user of the class, the user could enter an invalid setting for your property that could cause run-time errors. You need to explicitly document the valid settings for the property. If your property can be set to 0, 1, or 2, for example, say so in the Description box of the New Property dialog box. You might also want to verify the value of the property in code that references it.
To create an array property
- In the Name box of the New Property dialog box, specify the name, size, and dimensions of the array. For example, to create an array property named
myarraywith ten rows and two columns, type the following in the Name box: myarray[10,2]
The array property is read-only at design time and is displayed in the Properties window in italics. The array property can be managed and redimensioned at run time. For an example of using an array property, see Managing Multiple Instances of a Form, Creating Forms.
To add a new method to a class
- From the Class menu, choose New Method.
- In the New Method dialog box, type the name of the method.
- Specify the visibility: Public, Protected, or Hidden.
- Select the Access check box to create an Access method, select the Assign check box to create an Assign method, or select both check boxes to create Access and Assign methods.
Access and Assign methods let you execute code when the value of a property is queried or when you attempt to change the property’s value.
The code in an Access method is executed when the value of a property is queried, typically by using the property in an object reference, storing the value of the property to a variable, or displaying the value of property with a question mark (?).
The code in an Assign method is executed when you attempt to change the value of a property, typically by using the STORE or = command to assign a new value to the property.
You can also include a description of the method.
Creating Classes
You can create new classes in the Class Designer and you can see how each object will appear to the user as you design it.
To create a new class
- In the Project Manager, select the Classes tab and choose New. -or-
- From the File menu, choose New, select Class, and choose New File. -or-
- Use the CREATE CLASS command.
The New Class dialog box lets you specify what to call the new class, the class to base the new class on, and the library to store it in.
Modifying a Class Definition
Once you have created a class, you can modify it. Changes made to a class affect all the subclasses and all the objects based on this class. You can add an enhancement to a class or fix a bug in the class, and all the subclasses and objects based on the class will inherit the change.
To modify a class in the Project Manager
- Select the class you want to modify.
- Choose Modify. The Class Designer opens.
You can also modify a visual class definition with the MODIFY CLASS command.
Caution Don’t change the Name property of a class if the class is already being used in any other application components. Otherwise, Visual FoxPro will not be able to locate the class when needed.
Subclassing a Class Definition
You can create a subclass of a user-defined class in one of two ways.
To create a subclass of a user-defined class
- In the Project Manager New Class dialog box, click the dialog button to the right of the Based On box.
- In the Open dialog box, choose the class you want to base the new class on. -or-
- Use the CREATE CLASS command. For example, to base a new class,
x, onparentclassin Mylibrary.vcx, use this code: CREATE CLASS x OF y AS parentclass ; FROM mylibrary
Class Member Protection and Hiding
Properties and methods in a class definition are Public by default: code in other classes or procedures can set the properties or call the methods. Properties and methods that you designate as Protected can be accessed only by other methods in the class definition or in subclasses of the class. Properties and methods designated as Hidden can be accessed only by other members in the class definition. Subclasses of the class cannot “see” or reference hidden members.
To ensure correct functioning in some classes, you need to prevent users from programmatically changing the properties or calling the method from outside the class.
The following example illustrates using protected properties and methods in a class.
The stopwatch class included in Samples.vcx, in the Visual FoxPro …\Samples\Classes directory, includes a timer and five labels to display the elapsed time:
The Stopwatch class contains labels and a timer.
Property Settings for the Stopwatch Class
| Control | Property | Setting |
|---|---|---|
| lblSeconds | Caption | 00 |
| lblColon1 | Caption | : |
| lblMinutes | Caption | 00 |
| lblColon2 | Caption | : |
| lblHours | Caption | 00 |
| tmrSWatch | Interval | 1000 |
This class also has three protected properties, nSec, nMin, and nHour, and one protected method, UpdateDisplay. The other three custom methods in the class, Start, Stop, and Reset, are not protected.
Tip Choose Class Info on the Class menu to see the visibility of all properties and methods of a class.
The protected properties are used in internal calculations in the UpdateDisplay method and the Timer event. The UpdateDisplay method sets the captions of the labels to reflect the elapsed time.
The UpdateDisplay Method
| Code | Comments |
|---|---|
| cSecDisplay = ALLTRIM(STR(THIS.nSec)) cMinDisplay = ALLTRIM(STR(THIS.nMin)) cHourDisplay = ALLTRIM(STR(THIS.nHour)) | Convert the numeric properties to Character type for display in the label captions. |
| THIS.lblSeconds.Caption = ; IIF(THIS.nSec < 10, ; “0” ,””) + cSecDisplay THIS.lblMinutes.Caption = ; IIF(THIS.nMin < 10, ; “0”, “”) + cMinDisplay THIS.lblHours.Caption = ; IIF(THIS.nHour < 10, ; “0”, “”) + cHourDisplay | Set the label captions, retaining the leading 0 if the value of the numeric property is less than 10. |
The following table lists the code in the tmrSWatch.Timer event:
The Timer Event
| Code | Comments |
|---|---|
| THIS.Parent.nSec = THIS.Parent.nSec + 1 IF THIS.Parent.nSec = 60 THIS.Parent.nSec = 0 THIS.Parent.nMin = ; THIS.Parent.nMin + 1 ENDIF | Increment the nSec property every time the timer event fires: every second.If nSec has reached 60, reset it to 0 and increment the nMin property. |
| IF THIS.Parent.nMin = 60 THIS.Parent.nMin = 0 THIS.Parent.nHour = ; THIS.Parent.nHour + 1 ENDIF THIS.Parent.UpdateDisplay | If nMin has reached 60, reset it to 0 and increment the nHour property. Call the UpdateDisplay method when the new property values are set. |
The stopwatch class has three methods that are not protected: Start, Stop, and Reset. A user can call these methods directly to control the stopwatch.
The Start method contains the following line of code:
THIS.tmrSWatch.Enabled = .T.
The Stop method contains the following line of code:
THIS.tmrSWatch.Enabled = .F.
The Reset method sets the protected properties to zero and calls the protected method:
THIS.nSec = 0 THIS.nMin = 0 THIS.nHour = 0 THIS.UpdateDisplay
The user cannot directly set these properties or call this method, but code in the Reset method can.
Specifying the Default Value for a Property
When you create a new property, the default setting is false (.F.). To specify a different default setting for a property, use the Properties window. In the Other tab, click on your property and set it to the desired value. This will be the initial property setting when the class is added to a form or form set.
You can also set any of the base class properties in the Class Designer. When an object based on the class is added to the form, the object reflects your property settings rather than the Visual FoxPro base class property settings.
Tip If you want to make the default setting of a property an empty string, select the setting in the Property Editing box and press the BACKSPACE key.
Specifying Design-Time Appearance for a Class
You can specify the toolbar icon and the container icon for your class in the Class Info dialog box.
To set a toolbar icon for a class
- In the Class Designer, choose Class Info from the Class menu.
- In the Class Info dialog box, type the name and path of the .bmp file in the Toolbar icon box. Tip The bitmap (.bmp file) for the toolbar icon is 15 by 16 pixels. If the picture is larger or smaller, it is sized to 15 by 16 pixels and might not look the way you want it to.
The toolbar icon you specify is displayed in the Form Controls toolbar when you populate the toolbar with the classes in your class library.
You can also specify the icon to be displayed for the class in the Project Manager and Class Browser by setting the container icon.
To set a container icon for a class
- In the Class Designer, choose Class Info from the Class menu.
- In the Container icon box, type the name and path of the .bmp file to be displayed on the button in the Form Controls toolbar.
Creating, Copying, and Removing Class Library Files
Every visually designed class is stored in a class library with a .vcx file extension.
Creating a Class Library
You can create a class library in one of three ways.
To create a class library
- When you create a class, specify a new class library file in the Store In box of the New Class dialog box. -or-
- Use the CREATE CLASS command, specifying the name of the new class library. For example, the following statement creates a new class named
myclassand a new class library namednew_lib: CREATE CLASS myclass OF new_lib AS CUSTOM -or- - Use the CREATE CLASSLIB command. For example, type the following command in the Command window to create a class library named
new_lib: CREATE CLASSLIB new_lib
Copying and Removing Class Library Classes
Once you add a class library to a project, you can easily copy classes from one library to another or simply remove classes from libraries.
To copy a class from one library to another
- Make sure both libraries are in a project (not necessarily the same project).
- In the Project Manager, select the Classes tab.
- Click the plus sign (+) to the left of the class library that the class is now in.
- Drag the class from the original library and drop it in the new library. Tip For convenience and speed, you might want to keep a class and all the subclasses based on it in one class library. If you have a class that contains elements from many different class libraries, these libraries must all be open, so it will take a little longer to initially load your class at run time and at design time.
To remove a class from a library
- Select the class in the Project Manager and choose Remove. -or-
- Use the REMOVE CLASS command.
To change the name of a class in a class library, use the RENAME CLASS command. Remember, however, that when you change the name of a class, forms that contain the class and subclasses in other .vcx files continue to reference the old name and will no longer function correctly.
Visual FoxPro includes a Class Browser to facilitate using and managing classes and class libraries. For more information, see Class Browser.
Adding Classes to Forms
You can drag a class from the Project Manager to the Form Designer or to the Class Designer. You can also register your classes so that they can be displayed directly on the Form Controls toolbar in the Class Designer or Form Designer and added to containers the same way the standard controls are added.
To register a class library
- From the Tools menu, choose Options.
- In the Options dialog box choose the Controls tab.
- Select Visual Class Libraries and choose Add.
- In the Open dialog box, choose a class library to add to the registry and choose Open.
- Choose Set as Default if you want the class library to be available in the Form Controls toolbar in future sessions of Visual FoxPro.
You can also add your class library to the Form Controls toolbar by choosing Add in the submenu of the View Classes button. To make these classes available in the Form Controls toolbar in future sessions of Visual FoxPro, you still need to set the default in the Options dialog box.
Default Property Setting Override
When you add objects based on a user-defined class to a form, you can change the settings of all the properties of the class that are not protected, overriding the default settings. If you change the class properties in the Class Designer later, the settings in the object on the form are not affected. If you have not changed a property setting in the form and you change the property setting in the class, the change will take effect in the object as well.
For example, a user could add an object based on your class to a form and change the BackColor property from white to red. If you change the BackColor property of the class to green, the object on the user’s form will still have a background color of red. If, on the other hand, the user did not change the BackColor property of the object and you changed the background color of the class to green, the BackColor property of the object on the form would inherit the change and also be green.
Calling Parent Class Method Code
An object or class based on another class automatically inherits the functionality of the original. However, you can easily override the inherited method code. For example, you can write new code for the Click event of a class after you subclass it or after you add an object based on the class to a container. In both cases, the new code is executed at run time; the original code is not executed.
More frequently, however, you want to add functionality to the new class or object while keeping the original functionality. In fact, one of the key decisions you have to make in object-oriented programming is what functionality to include at the class level, at the subclass level, and at the object level. You can optimize your class design by using the DODEFAULT( ) function or scope resolution operator (::) to add code at different levels in the class or container hierarchy.
Adding Functionality to Subclasses
You can call the parent class code from a subclass by using the DODEFAULT( ) function.
For example, cmdOK is a command button class stored in Buttons.vcx, located in the Visual FoxPro …\Samples\Classes directory. The code associated with the Click event of cmdOk releases the form the button is on. CmdCancel is a subclass of cmdOk in the same class library. To add functionality to cmdCancel to discard changes, for example, you could add the following code to the Click event:
IF USED( ) AND CURSORGETPROP("Buffering") != 1
TABLEREVERT(.T.)
ENDIF
DODEFAULT( )
Because changes are written to a buffered table by default when the table is closed, you don’t need to add TABLEUPDATE( ) code to cmdOk. The additional code in cmdCancel reverts changes to the table before calling the code in cmdOk, the ParentClass, to release the form.
Writing Class Definitions Programmatically
You can define classes visually in the Class Designer and the Form Designer or programmatically in .PRG files. This section describes how to write class definitions. For more information about forms, see Creating Forms.
In This Section
Programmatic Class Definitions Displays the syntax of the basic shell for class creation. Protection and Hiding of Class Members Through example, illustrates how to protect or hide properties and methods in a class definition with keywords of the DEFINE CLASS command. Creation of Objects from Classes Describes how to create an object based on a saved visual class. Addition of Objects to a Container Class Details how to add objects to a container through use of the ADD OBJECT clause in the DEFINE CLASS command or the AddObject method. Method and Event Code Guidelines Lays out the rules for authoring event code and methods. Creating a Set of Table Navigation Buttons Provides an explanation of how to design and build table navigation buttons through code. Definition of a Grid Control Outlines how to define grid control programmatically. Object Reference Creation Explains how to make a reference to an object, and describes the benefits of creating references over making copies of objects. Arrays of Members and Objects Tells how to define members of classes as arrays and how to build arrays of objects. Data Storage with Objects Describes when and how to store data in objects. Object and Data Integration Contains information on why integrating objects and data is important.
Related Sections
Programming in Visual FoxPro Microsoft® Visual FoxPro® is a powerful interactive data management tool, but you also can access the full power of Visual FoxPro by creating applications. Understanding object-oriented programming techniques and the event-driven model can maximize your programming productivity. Application Development As you develop an application, organize its pieces with the Project Manager, an integrated way to build and test your application as you go. Object-Oriented Programming With object-oriented programming, you can create self-contained application components that respond to user actions and to the system and which can be easily maintained and reused. Understanding the Event Model The event model defines when and how user and system interactions occur.
Programmatic Class Definitions
In a program file, you can have program code prior to the class definitions, but not after the class definitions, in the same way that program code cannot come after procedures in a program. The basic shell for class creation has this syntax:
DEFINE CLASS ClassName1 AS ParentClass [OLEPUBLIC] [[PROTECTED | HIDDEN PropertyName1, PropertyName2 ...] [Object.]PropertyName = eExpression ...] [ADD OBJECT [PROTECTED] ObjectName AS ClassName2 [NOINIT] [WITH cPropertylist]]... [[PROTECTED | HIDDEN] FUNCTION | PROCEDURE Name[_ACCESS | _ASSIGN] [NODEFAULT] cStatements [ENDFUNC | ENDPROC]]... ENDDEFINE
Protection and Hiding of Class Members
You can protect or hide properties and methods in a class definition with the PROTECTED and HIDDEN keywords of the DEFINE CLASS command.
For example, if you create a class to hold employee information, and you don’t want users to be able to change the hire date, you can protect the HireDate property. If users need to find out when an employee was hired, you can include a method to return the hire date.
DEFINE CLASS employee AS CUSTOM
PROTECTED HireDate
First_Name = ""
Last_Name = ""
Address = ""
HireDate = { - - }
PROCEDURE GetHireDate
RETURN This.HireDate
ENDPROC
ENDDEFINE
Creation of Objects from Classes
When you have saved a visual class, you can create an object based on it with the CREATEOBJECT( ) function. The following example demonstrates running a form saved as a class definition in the class library file Forms.vcx:
Creating and Showing a Form Object Whose Class Was Designed in the Form Designer
| Code | Comments |
|---|---|
SET CLASSLIB TO Forms ADDITIVE | Set the class library to the .vcx file that the form definition was saved in. The ADDITIVE keyword prevents this command from closing any other class libraries that happen to be open. |
| frmTest = CREATEOBJECT(“TestForm”) | This code assumes that the name of the form class saved in the class library is TestForm. |
| frmTest.Show | Display the form. |
Addition of Objects to a Container Class
You can use the ADD OBJECT clause in the DEFINE CLASS command or the AddObject method to add objects to a container.
For example, the following class definition is based on a form. The ADD OBJECT command adds two command buttons to the form:
DEFINE CLASS myform AS FORM ADD OBJECT cmdOK AS COMMANDBUTTON ADD OBJECT PROTECTED cmdCancel AS COMMANDBUTTON ENDDEFINE
Use the AddObject method to add objects to a container after the container object has been created. For example, the following lines of code create a form object and add two command buttons to it:
frmMessage = CREATEOBJECT("FORM")
frmMessage.AddObject("txt1", "TEXTBOX")
frmMessage.AddObject("txt2", "TEXTBOX")
You can also use the AddObject method in the method code of a class. For example, the following class definition uses AddObject in the code associated with the Init event to add a control to a grid column.
DEFINE CLASS mygrid AS GRID
ColumnCount = 3
PROCEDURE Init
THIS.Column2.AddObject("cboClient", "COMBOBOX")
THIS.Column2.CurrentControl = "cboClient"
ENDPROC
ENDDEFINE
Adding and Creating Classes in Method Code
You can programmatically add objects to a container with the AddObject method. You can also create objects with the CREATEOBJECT( ) function in the Load, Init, or any other method of the class.
When you add an object with the AddObject method, the object becomes a member of the container. The Parent property of the added object refers to the container. When an object based on the container or control class is released from memory, the added object is also released.
When you create an object with the CREATEOBJECT( ) function, the object is scoped to a property of the class or a variable in the method that calls this function. The parent property of the object is undefined.
Method and Event Code Guidelines
In addition to writing code for the methods and events of an object, you can extend the set of methods in subclasses of Visual FoxPro base classes. Here are the rules for writing event code and methods:
- The event set for the Visual FoxPro base classes is fixed and cannot be extended.
- Every class recognizes a set of fixed default events, the minimum set of which includes Init, Destroy, and Error events.
- When you create a method in a class definition with the same name as an event that the class can recognize, the code in the method is executed when the event occurs.
- You can add methods to your classes by creating a procedure or function within the class definition.
- You can create Access and Assign Methods for your classes by creating a procedure or function with the same name as a class property and _ACCESS or _ASSIGN appended to the procedure or function name.
Calling Event Code up the Class Hierarchy
When you create a class, the class automatically inherits all the properties, methods, and events of the parent class. If code is written for an event in the parent class, that code is executed when the event occurs with respect to an object based on the subclass. You can, however, overwrite the parent class code by writing code for the event in the subclass.
To explicitly call the event code in a parent class when the subclass has code written for the same event, use the DODEFAULT( ) function.
For example, you could have a class named cmdBottom based on the command button base class that has the following code in the Click event:
GO BOTTOM THISFORM.Refresh
When you add an object based on this class to a form, named, for example, cmdBottom1, you might decide that you also want to display a message for the user so that he or she knows that the record pointer is at the bottom of the table. You could add the following code to the Click event of the object to display the message:
WAIT WINDOW "At the Bottom of the Table" TIMEOUT 1
When you run the form, however, the message is displayed, but the record pointer doesn’t move because the code in the Click event of the parent class is never executed. To make sure the code in the Click event of the parent class is also executed, include the following lines of code in the Click event procedure of the object:
DODEFAULT( ) WAIT WINDOW "At the Bottom of the Table" TIMEOUT 1
Note You can use the ACLASS( ) function to determine all the classes in an object’s class hierarchy.
Preventing Base Class Code from Executing
Sometimes you’ll want to prevent the base class default behavior from taking place in an event or method. You can do this by including the NODEFAULT keyword in the method code you write. For example, the following program uses the NODEFAULT keyword in the KeyPress event of a text box to prevent the typed characters from being displayed in the text box:
frmKeyExample = CREATEOBJECT("test")
frmKeyExample.Show
READ EVENTS
DEFINE CLASS test AS FORM
ADD OBJECT text1 AS TEXTBOX
PROCEDURE text1.KeyPress
PARAMETERS nKeyCode, nShiftAltCtrl
NODEFAULT
IF BETWEEN(nKeyCode, 65, 122) && between 'A' and 'z'
This.Value = ALLTRIM(This.Value) + "*"
ACTIVATE SCREEN && send output to main Visual FoxPro window
?? CHR(nKeyCode)
ENDIF
ENDPROC
PROCEDURE Destroy
CLEAR EVENTS
ENDPROC
ENDDEFINE
Creating a Set of Table Navigation Buttons
A common feature of many applications is a series of navigation buttons that allow users to move through a table. These typically include buttons to move the record pointer to the next or prior record in the table, as well as to the top or bottom record in the table.
Designing the Navigation Buttons
Each of the buttons will have some characteristics and functionality in common, so it is a good idea to create a navigation button class. Then the individual buttons can easily derive this common appearance and functionality. This parent class is the Navbutton class defined later in this section.
Once the parent class is defined, the following subclasses define the functionality and appearance specific to each of the four navigation buttons: navTop, navPrior, navNext, navBottom.
Finally, a container class, vcr, is created and each of the navigation buttons is added to the container class. The container can be added to a form or a toolbar to provide table navigation functionality.
NAVBUTTON Class Definition
To create Navbutton, save the following six class definitions (Navbutton, navTop, navBottom, navPrior, navNext, and vcr) to a program file such as Navclass.prg.
Definition of the Generic Navigation Commandbutton Class
| Code | Comments |
|---|---|
| DEFINE CLASS Navbutton AS COMMANDBUTTON Height = 25 Width = 25 TableAlias = “” | Define the parent class of the navigation buttons. Give the class some dimensions. Include a custom property, TableAlias, to hold the name of the alias to navigate through. |
| PROCEDURE Click IF NOT EMPTY(This.TableAlias) SELECT (This.TableAlias) ENDIF ENDPROC | If TableAlias has been set, this parent class procedure selects the alias before the actual navigation code in the subclasses is executed. Otherwise, assume that the user wants to navigate through the table in the currently selected work area. |
| PROCEDURE RefreshForm _SCREEN.ActiveForm.Refresh ENDPROC | Using _SCREEN.ActiveForm.Refresh instead of THISFORM.Refresh allows you to add the class to a form or a toolbar and have it function equally well. |
| ENDDEFINE | End the class definition. |
The specific navigation buttons are all based on the Navbutton class. The following code defines the Top button for the set of navigation buttons. The remaining three navigation buttons are defined in the following table. The four class definitions are similar, so only the first one has extensive comments.
Definition of the Top Navigation Button Class
| Code | Comments |
|---|---|
| DEFINE CLASS navTop AS Navbutton Caption = “|<“ | Define the Top navigation button class and set the Caption property. |
| PROCEDURE Click | Create method code to be executed when the Click event for the control occurs. |
| DODEFAULT( ) GO TOP THIS.RefreshForm | Call the Click event code in the parent class, Navbutton, so that the appropriate alias can be selected if the TableAlias property has been set.Include the code to set the record pointer to the first record in the table: GO TOP. Call the RefreshForm method in the parent class. It is not necessary to use the scope resolution operator (::) in this case because there is no method in the subclass with the same name as the method in the parent class. On the other hand, both the parent and the subclass have method code for the Click event. |
| ENDPROC | End the Click procedure. |
| ENDDEFINE | End the class definition. |
The other navigation buttons have similar class definitions.
Definition of the Other Navigation Button Classes
| Code | Comments |
|---|---|
| DEFINE CLASS navNext AS Navbutton Caption = “>” | Define the Next navigation button class and set the Caption property. |
| PROCEDURE Click DODEFAULT( ) SKIP 1 IF EOF( ) GO BOTTOM ENDIF THIS.RefreshForm ENDPROC ENDDEFINE | Include the code to set the record pointer to the next record in the table. End the class definition. |
| DEFINE CLASS navPrior AS Navbutton Caption = “<“ | Define the Prior navigation button class and set the Caption property. |
| PROCEDURE Click DODEFAULT( ) SKIP –1 IF BOF( ) GO TOP ENDIF THIS.RefreshForm ENDPROC ENDDEFINE | Include the code to set the record pointer to the previous record in the table. End the class definition. |
| DEFINE CLASS navBottom AS Navbutton Caption = “>|” | Define the Bottom navigation button class and set the Caption property. |
| PROCEDURE Click DODEFAULT( ) GO BOTTOM THIS.RefreshForm ENDPROC ENDDEFINE | Include the code to set the record pointer to the bottom record in the table. End the class definition. |
The following class definition contains all four navigation buttons so that they can be added as a unit to a form. The class also includes a method to set the TableAlias property of the buttons.
Definition of a Table Navigation Control Class
| Code | Comments |
|---|---|
| DEFINE CLASS vcr AS CONTAINER Height = 25 Width = 100 Left = 3 Top = 3 | Begin the class definition. The Height property is set to the same height as the command buttons it will contain. |
| ADD OBJECT cmdTop AS navTop ; WITH Left = 0 ADD OBJECT cmdPrior AS navPrior ; WITH Left = 25 ADD OBJECT cmdNext AS navNext ; WITH Left = 50 ADD OBJECT cmdBot AS navBottom ; WITH Left = 75 | Add the navigation buttons. |
| PROCEDURE SetTable(cTableAlias) IF TYPE(“cTableAlias”) = ‘C’ THIS.cmdTop.TableAlias = ; cTableAlias THIS.cmdPrior.TableAlias = ; cTableAlias THIS.cmdNext.TableAlias = ; cTableAlias THIS.cmdBot.TableAlias = ; cTableAlias ENDIF ENDPROC | This method is used to set the TableAlias property of the buttons. TableAlias is defined in the parent class Navbutton.You could also use the SetAll method to set this property: IF TYPE ("cTableAlias") = 'C'This.SetAll("TableAlias", "cTableAlias")ENDIFHowever, this would cause an error if an object were ever added to the class that did not have a TableAlias property. |
| ENDDEFINE | End class definition. |
Once you have defined the class, you can subclass it or add it to a form.
Creating a Subclass Based on the New Class
You can also create subclasses based on vcr that have additional buttons such as Search, Edit, Save, and Quit. For example, vcr2 includes a Quit button:
Definition of a Table Navigation Control Subclass
| Code | Comments |
|---|---|
| DEFINE CLASS vcr2 AS vcr ADD OBJECT cmdQuit AS COMMANDBUTTON WITH ; Caption = “Quit”,; Height = 25, ; Width = 50 Width = THIS.Width + THIS.cmdQuit.Width cmdQuit.Left = THIS.Width – ; THIS.cmdQuit.Width | Define a class based on vcr and add a command button to it. |
| PROCEDURE cmdQuit.CLICK RELEASE THISFORM ENDPROC | When the user clicks cmdQuit, this code releases the form. |
| ENDDEFINE | End class definition. |
Vcr2 has everything that vcr does, plus the new command button, and you don’t have to rewrite any of the existing code.
Changes to VCR Reflected in the Subclass
Because of inheritance, changes to the parent class are reflected in all subclasses based on the parent. For example, you could let the user know that the bottom of the table has been reached by changing the IF EOF( ) statement in navNext.Click to the following:
IF EOF( ) GO BOTTOM SET MESSAGE TO "Bottom of the table" ELSE SET MESSAGE TO ENDIF
You could let the user know that the top of the table has been reached by changing the IF BOF( ) statement in navPrior.Click to the following:
IF BOF() GO TOP SET MESSAGE TO "Top of the table" ELSE SET MESSAGE TO ENDIF
If these changes are made to the navNext and navPrior classes, they will also apply automatically to the appropriate buttons in vcr and vcr2.
Adding VCR to a Form Class
Once vcr is defined as a control, the control can be added in the definition of a container. For example, the following code added to Navclass.prg defines a form with added navigation buttons:
DEFINE CLASS NavForm AS Form ADD OBJECT oVCR AS vcr ENDDEFINE
Running the Form Containing VCR
Once the form subclass is defined, you can display it easily with the appropriate commands.
To display the form
- Load the class definition: SET PROCEDURE TO navclass ADDITIVE
- Create an object based on the
navformclass: frmTest = CREATEOBJECT(“navform”) - Invoke the Show method of the form: frmTest.Show
If you don’t call the SetTable method of oVCR (the VCR object in NavForm) when the user clicks the navigation buttons, the record pointer moves in the table in the currently selected work area. You can call the SetTable method to specify what table to move through.
frmTest.oVCR.SetTable("customer")
Note When the user closes the form,
frmTestis set to a null value (.NULL.). To release the object variable from memory, use the RELEASE command. Object variables created in program files are released from memory when the program is completed.
Definition of a Grid Control
A grid contains columns, which in turn can contain headers and any other control. The default control contained in a column is a text box, so that the default functionality of the grid approximates a Browse window. However, the underlying architecture of the grid opens it up to endless extensibility.
The following example creates a form that contains a Grid object with two columns. The second column contains a check box to display the values in a logical field in a table.
Grid control with a check box in one column

Definition of a Grid Class with a Check Box in a Grid Column
| Code | Comments |
|---|---|
| DEFINE CLASS grdProducts AS Grid Left = 24 Top = 10 Width = 295 Height = 210 Visible = .T. RowHeight = 28 ColumnCount = 2 | Start the class definition and set properties that determine the grid appearance. When you set the ColumnCount property to 2, you add two columns to the grid. Each column contains a header with the name Header1. In addition, each column has an independent group of properties that determines its appearance and behavior. |
| Column1.ControlSource =”prod_name” Column2.ControlSource =”discontinu” | When you set the ControlSource of a column, the column displays that field’s values for all the records in the table.Discontinu is a logical field. |
| Column2.Sparse = .F. | Column2 will contain the check box. Set the column’s Sparse property to .F. so that the check box will be visible in all rows, not just in the selected cell. |
| Procedure Init THIS.Column1.Width = 175 THIS.Column2.Width = 68 THIS.Column1.Header1.Caption = ; “Product Name” THIS.Column2.Header1.Caption = ; “Discontinued” THIS.Column2.AddObject(“chk1”, ; “checkbox”) THIS.Column2.CurrentControl = ; “chk1” THIS.Column2.chk1.Visible = .T. THIS.Column2.chk1.Caption = “” ENDPROC | Set column widths and header captions. The AddObject method allows you to add an object to a container — in this case, a check box named chk1.Set the CurrentControl of the column to the check box so that the check box will be displayed. Make sure that the check box is visible. Set the caption to an empty string so that the default caption “chk1” won’t be displayed. |
| ENDDEFINE | End of the class definition. |
The following class definition is the form that contains the grid. Both class definitions can be included in the same program file.
Definition of a Form Class that Contains the Grid Class
| Code | Comments |
|---|---|
| DEFINE CLASS GridForm AS FORM Width = 330 Height = 250 Caption = “Grid Example” ADD OBJECT grid1 AS grdProducts | Create a form class and add an object, based on the grid class, to it. |
| PROCEDURE Destroy CLEAR EVENTS ENDPROC ENDDEFINE | The program that creates an object based on this class will use READ EVENTS. Including CLEAR EVENTS in the Destroy event of the form allows the program to finish running when the user closes the form. End of the class definition. |
The following program opens the table with the fields to be displayed in the grid columns, creates an object based on the GridForm class, and issues the READ EVENTS command:
CLOSE DATABASE
OPEN DATABASE (HOME(2) + "data\testdata.dbc")
USE products
frmTest= CREATEOBJECT("GridForm")
frmTest.Show
READ EVENTS
This program can be included in the same file with the class definitions if it comes at the beginning of the file. You could also use the SET PROCEDURE TO command to specify the program with the class definitions and include this code in a separate program.
Object Reference Creation
Instead of making a copy of an object, you can create a reference to the object. A reference takes less memory than an additional object, can easily be passed between procedures, and can aid in writing generic code.
Returning a Reference to an Object
Sometimes, you might want to manipulate an object by means of one or more references to the object. For example, the following program defines a class, creates an object based on the class, and returns a reference to the object:
*--NEWINV.PRG
*--Returns a reference to a new invoice form.
frmInv = CREATEOBJECT("InvoiceForm")
RETURN frmInv
DEFINE CLASS InvoiceForm AS FORM
ADD OBJECT txtCompany AS TEXTBOX
* code to set properties, add other objects, and so on
ENDDEFINE
The following program establishes a reference to the object created in Newinv.prg. The reference variable can be manipulated in exactly the same way as the object variable can:
frmInvoice = NewInv() && store the object reference to a variable frmInvoice.SHOW
You can also create a reference to an object on a form, as in the following example:
txtCustName = frmInvoice.txtCompany txtCustName.Value = "Fox User"
Tip Once you’ve created an object, you can use the DISPLAY OBJECTS command to display the object’s class hierarchy, property settings, contained objects, and available methods and events. You can fill an array with the properties (not the property settings), events, methods, and contained objects of an object with the AMEMBERS( ) function.
Releasing Objects and References from Memory
If a reference to an object exists, releasing the object does not clear the object from memory. For example, the following command releases frmInvoice, the original object:
RELEASE frmInvoice
However, because a reference to an object belonging to frmInvoice still exists, the object is not released from memory until txtCustName is released with the following command:
RELEASE txtCustName
Checking to See if an Object Exists
You can use the TYPE( ), ISNULL( ), and VARTYPE( ) functions to determine if an object exists. For example, the following lines of code check to see whether an object named oConnection exists:
IF TYPE("oConnection") = "O" AND NOT ISNULL(oConnection)
* Object exists
ELSE
* Object does not exist
ENDIF
NoteISNULL( ) is necessary because .NULL. is stored to the form object variable when a user closes a form, but the type of the variable remains “O”.
Arrays of Members and Objects
You can define members of classes as arrays. In the following example, choices is an array of controls:
DEFINE CLASS MoverListBox AS CONTAINER
DIMENSION choices[3]
ADD OBJECT lstFromListBox AS LISTBOX
ADD OBJECT lstToListBox AS LISTBOX
ADD OBJECT choices[1] AS COMMANDBUTTON
ADD OBJECT choices[2] AS COMMANDBUTTON
ADD OBJECT choices[3] AS CHECKBOX
PROCEDURE choices.CLICK
PARAMETER nIndex
DO CASE
CASE nIndex = 1
* code
CASE nIndex = 2
* code
CASE nIndex = 3
* code
ENDCASE
ENDPROC
ENDDEFINE
When the user clicks a control in an array of controls, Visual FoxPro passes the index number of the control to the Click event procedure. In this procedure, you can use a CASE statement to execute different code depending on which button was clicked.
Creating Arrays of Objects
You can also create arrays of objects. For example, MyArray holds five command buttons:
DIMENSION MyArray[5]
FOR x = 1 TO 5
MyArray[x] = CREATEOBJECT("COMMANDBUTTON")
ENDFOR
There are some considerations to keep in mind with arrays of objects:
- You can’t assign an object to an entire array with one command. You need to assign the object to each member of the array individually.
- You can’t assign a value to a property of an entire array. The following command would result in an error: MyArray.Enabled = .F.
- When you redimension an object array so that it is larger than the original array, the new elements are initialized to false (.F.), as is the case with all arrays in Visual FoxPro. When you redimension an object array so that it is smaller than the original array, the objects with a subscript greater than the largest new subscript are released.
Data Storage with Objects
In object-oriented languages, a class offers a useful and convenient vehicle for storing data and procedures related to an entity. For example, you could define a customer class to hold information about a customer as well as a method to calculate the customer’s age:
DEFINE CLASS customer AS CUSTOM
LastName = ""
FirstName = ""
Birthday = { - - }
PROCEDURE Age
IF !EMPTY(THIS.Birthday)
RETURN YEAR(DATE()) - YEAR(THIS.Birthday)
ELSE
RETURN 0
ENDIF
ENDPROC
ENDDEFINE
However, data stored in objects based on the customer class are stored only in memory. If this data were in a table, the table would be stored on disk. If you had more than one customer to keep track of, the table would give you access to all of the Visual FoxPro database management commands and functions. As a result, you could quickly locate information, sort it, group it, perform calculations on it, create reports and queries based on it, and so on.
Storing and manipulating data in databases and tables is what Visual FoxPro does best. There are times, however, when you’ll want to store data in objects. Usually, the data will be significant only while your application is running and it will pertain to a single entity.
For example, in an application that includes a security system, you would typically have a table of users who have access to the application. The table would include user identification, password, and access level. Once a user has logged on, you won’t need all the information in the table. All you need is information about the current user, and this information can be easily stored and manipulated in an object. The following class definition, for example, initiates a logon when an object based on the class is created:
DEFINE CLASS NewUser AS CUSTOM
PROTECTED LogonTime, AccessLevel
UserId = ""
PassWord = ""
LogonTime = { - - : : }
AccessLevel = 0
PROCEDURE Init
DO FORM LOGON WITH ; && assuming you have created this form
This.UserId, ;
This.PassWord, ;
This.AccessLevel
This.LogonTime = DATETIME( )
ENDPROC
* Create methods to return protected property values.
PROCEDURE GetLogonTime
RETURN This.LogonTime
ENDPROC
PROCEDURE GetAccessLevel
RETURN This.AccessLevel
ENDPROC
ENDDEFINE
In the main program of your application, you could create an object based on the NewUserclass:
oUser = CREATEOBJECT('NewUser')
oUser.Logon
Throughout your application, when you need information about the current user, you can get it from the oUser object. For example:
IF oUser.GetAccessLevel( ) >= 4 DO ADMIN.MPR ENDIF
Object and Data Integration
In most applications, you can best utilize the power of Visual FoxPro by integrating objects and data. Most Visual FoxPro classes have properties and methods that allow you to integrate the power of a relational database manager and a full object-oriented system.
Properties for Integrating Visual FoxPro Classes and Database Data
| Class | Data properties |
|---|---|
| Grid | RecordSource, ChildOrder, LinkMaster |
| All other controls | ControlSource |
| List box and combo box | ControlSource, RowSource |
| Form and form set | DataSession |
Because these data properties can be changed at design or run time, you can create generic controls with encapsulated functionality that operate on diverse data.
For more information about integrating data and objects, see Creating Forms, and Using Controls
Setting Properties
You can set the properties of an object at run time or design time.
To set a property
- Use this syntax: Container.Object.Property = Value For example, the following statements set various properties of a text box named
txtDateon a form namedfrmPhoneLog: frmPhoneLog.txtDate.Value = DATE( ) && Display the current date frmPhoneLog.txtDate.Enabled = .T. && The control is enabled frmPhoneLog.txtDate.ForeColor = RGB(0,0,0) && black text frmPhoneLog.txtDate.BackColor = RGB(192,192,192) && gray background
For the property settings in the preceding examples, frmPhoneLog is the highest-level container object. If frmPhoneLog were contained in a form set, you would also need to include the form set in the parent path:
frsContacts.frmPhoneLog.txtDate.Value = DATE( )
Setting Multiple Properties
The WITH … ENDWITH structure simplifies setting multiple properties. For example, to set multiple properties of a column in a grid in a form in a form set, you could use the following syntax:
WITH THISFORMSET.frmForm1.grdGrid1.grcColumn1 .Width = 5 .Resizable = .F. .ForeColor = RGB(0,0,0) .BackColor = RGB(255,255,255) .SelectOnEntry = .T. ENDWITH
Calling Methods
Once an object has been created, you can call the methods of that object from anywhere in your application.
To call a method
- Use this syntax: Parent.Object.Method
The following statements call methods to display a form and set the focus to a text box:
frsFormSet.frmForm1.Show frsFormSet.frmForm1.txtGetText1.SetFocus
Methods that return values and are used in expressions must end in open and closed parentheses. For example, the following statement sets the caption of a form to the value returned from the user-defined method GetNewCaption:
Form1.Caption = Form1.GetNewCaption( )
Note Parameters passed to methods must be included in parentheses after the method name; for example,
Form1.Show(nStyle). passesnStyleto Form1’s Show method code.

Leave a comment