Visual FoxPro
Visual FoxPro (VFP) is a data-centric, object-oriented programming language and integrated development environment (IDE) developed by Microsoft, featuring a built-in relational database management system (RDBMS) designed for rapid application development of database-driven applications.[1] It supports procedural and object-oriented programming paradigms, with strong compatibility to the xBase language family, enabling developers to build scalable desktop, client-server, and web-based solutions.[2]
Originally derived from FoxPro 1.0, first released in 1989 by Fox Software, the technology evolved after Microsoft acquired Fox Software in 1992 for approximately $175 million to bolster its database offerings amid competition from products like Microsoft Access.[3][4] The inaugural version, Visual FoxPro 3.0, launched in June 1995, introducing key innovations such as the database container (.dbc) for centralized management of tables, indexes, and relations, with native support for the Windows platform; a version for Power Macintosh followed in 1996.[4][5] Subsequent releases, including versions 5.0 (1996), 6.0 (1998), 7.0 (2001), 8.0 (2003), and the final 9.0 (December 2004), enhanced features like XML support, .NET interoperability, and web service integration, positioning VFP as a versatile tool for enterprise data applications.[6][7]
Microsoft ceased new development of Visual FoxPro with the release of version 9.0 Service Pack 2 in 2007, announcing it as the last major update while committing to extended support until January 2015.[8][6] Despite its discontinuation, VFP remains in use for legacy systems in industries requiring robust, data-focused applications, though migration to modern platforms like .NET or cloud-based databases is increasingly recommended due to security and compatibility concerns. As of 2025, over 5,400 companies worldwide still use Visual FoxPro, according to market intelligence platform Enlyft.[9][10]
History
Origins from FoxPro
Fox Software, founded in 1984 by David Fulton along with Bill Ferguson and other programmers, developed FoxBase as a high-performance alternative to dBASE II, the dominant database management system of the era. Released in December 1984, FoxBase maintained full compatibility with the dBASE II command set and file structures, including the DBF format for data storage, but delivered faster execution through optimized code and reduced overhead. This positioned it as an attractive option for developers building business applications on early PCs.[11][4]
The product line evolved with the release of Multi-User FoxBase in 1985, which added network file locking and concurrent access capabilities for shared environments, and FoxBASE+ in 1986, expanding language support to a superset of dBASE III commands. A significant advancement occurred in 1989 with FoxPro 1.0, which introduced a compiler that translated .prg source files into native executable code (.fxp), yielding substantial runtime performance gains compared to interpreted xBase systems. FoxPro 1.0 also enhanced multi-user functionality, supporting distributed data access over networks for collaborative applications.[4]
FoxPro 2.0, launched in July 1991, brought further innovations, including the proprietary Rushmore query optimization engine, which leveraged existing indexes to evaluate filter conditions via bitmaps, enabling rapid searches and operations on large datasets without full table scans. This technology exemplified FoxPro's focus on efficient data handling, often outperforming competitors in benchmark tests for indexing and retrieval. In 1992, FoxPro 2.0 extended support to Windows platforms, integrating graphical user interface elements like screen builders and menus, which signaled a transition toward more intuitive, visual development tools.[12][4]
These developments culminated in Microsoft acquiring Fox Software in June 1992, integrating FoxPro's core engine and reorienting it toward the Visual FoxPro brand.[4]
Microsoft era and evolution
In March 1992, Microsoft announced its acquisition of Fox Software Inc., the creator of the FoxPro database management system, for approximately $173 million in stock, marking the software giant's first major entry into the database market.[13] The transaction was completed in June 1992, integrating FoxPro into Microsoft's expanding portfolio of developer tools and allowing the company to leverage the product's established strengths in xBase-compatible relational database technology.[14]
Under Microsoft's stewardship, the product evolved rapidly, with the release of FoxPro 2.5 in January 1993, which significantly improved compatibility with Microsoft Windows environments and added native support for local area network (LAN) operations to facilitate multi-user data sharing.[15][16] This version retained and enhanced core innovations from the Fox Software era, such as the Rushmore query optimization technology, which accelerated data retrieval by intelligently utilizing indexes.[17]
A pivotal advancement came in June 1995 with the launch of Visual FoxPro 3.0, rebranded as the first fully visual iteration of the tool, shifting from command-line paradigms to a graphical interface for development.[16] Central to this release was the introduction of the database container (.DBC) file, a structured repository that centralized management of database tables, indexes, views, and relationships, enabling more robust data organization and integrity.[18]
Visual FoxPro 3.0 quickly emerged as a prominent rapid application development (RAD) platform for client-server applications, prized for its drag-and-drop form designer that streamlined the creation of interactive user interfaces without extensive coding. This focus on visual tooling and connectivity positioned it as a competitive alternative in enterprise development, appealing to developers building scalable, data-driven solutions.
Version timeline
Visual FoxPro's development under Microsoft spanned from 1995 to 2004, with subsequent service packs, marking a progression toward enhanced object-oriented programming, integration with emerging technologies like COM and XML, and improved performance for database applications. The following timeline outlines the major releases, focusing on pivotal updates that influenced its adoption for rapid application development.
| Version | Release Date | Key Features |
|---|
| Visual FoxPro 3.0 | June 1995 | Introduced object-oriented programming (OOP) capabilities, a database container for centralized management of tables, indexes, and relations, and visual designers for forms and reports, enabling more intuitive graphical application development.[19][4] |
| Visual FoxPro 5.0 | October 1996 | Added support for ActiveX controls and COM automation to facilitate component-based development, an improved debugger for enhanced troubleshooting, and integration with Visual SourceSafe for version control.[20][19] |
| Visual FoxPro 5.0a | October 1997 | Service release addressing compatibility issues and minor enhancements to the core features of 5.0, including bug fixes for broader platform support.[19][4] |
| Visual FoxPro 6.0 | May 18, 1998 | Enhanced XML support for data exchange, introduced web publishing tools for generating dynamic web content, and added multithreading capabilities to improve application responsiveness and performance in data-intensive scenarios.[7][4] |
| Visual FoxPro 7.0 | June 27, 2001 | Featured improved SQL optimization for faster query execution, cursor adapters for streamlined remote data access, and enhanced automation server capabilities to support distributed COM components.[21][4][22] |
| Visual FoxPro 8.0 | February 1, 2003 | Introduced IntelliSense for code completion and syntax assistance in the IDE, enhancements to report previewing for better design-time testing, and improved interoperability with .NET frameworks for hybrid application development.[23][24][4] |
| Visual FoxPro 9.0 | December 22, 2004 (with SP2 on October 16, 2007) | The final major release, incorporating advanced data manipulation via XML and SQL extensions, enhanced security features such as user authentication and encryption, and an automation object for external scripting integration.[25][6][26] |
These releases progressively shifted Visual FoxPro toward a more integrated tool for building scalable, data-centric applications, aligning with Microsoft's broader ecosystem.[7]
Core Features
Database engine
Visual FoxPro's database engine provides native support for DBF files as the primary format for tables, allowing individual files to reach up to a 2 GB size limit.[27] Field names in these DBF tables are limited to 10 characters, enabling more descriptive naming compared to earlier dBase formats while maintaining compatibility.[28] For handling large text or binary data, memo fields store content in separate FPT files, with the table header containing only a 4-byte pointer to the memo block, thus avoiding bloat in the main DBF structure.[29]
Relational integrity is enforced through the database container (.DBC), a special table that manages persistent relationships between tables, along with triggers and stored procedures to maintain data consistency.[30] The .DBC stores definitions for relations, allowing automatic enforcement of rules such as cascading updates or deletes, while triggers execute code on insert, update, or delete events at the record or field level.[31] Stored procedures, saved as code fragments within the .DBC, support custom logic for validation, defaults, or business rules tied to database events.[30]
Rushmore technology, inherited from earlier FoxPro versions, optimizes query performance by leveraging structural and regular indexes to evaluate conditions without scanning entire tables.[32] For operations like SELECT with WHERE clauses, Rushmore identifies matching index tags to retrieve only relevant records, significantly reducing I/O operations and enabling optimizations across multiple tables in SQL queries.[33] This index-based approach supports ad-hoc temporary indexes when needed, ensuring efficient data access even for complex filters.[32]
The engine also facilitates access to remote data sources through cursor adapters, which provide an object-oriented interface for connecting to ODBC-compliant databases, as well as native drivers for systems like SQL Server and Oracle.[34] Cursor adapters enable bidirectional data flow, supporting updatable cursors that can be configured for remote or local use.[34] Additionally, remote views can be upsized to server-side SQL structures or downsized to local equivalents, allowing seamless transitions between standalone and client-server architectures.[35]
Programming capabilities
Visual FoxPro retains strong procedural programming roots derived from the xBase family of languages, such as dBASE, enabling developers to structure code modularly using commands like DO for executing programs or procedures, PROCEDURE for defining reusable code blocks without return values, and FUNCTION for creating subroutines that return values.[36][2] This procedural foundation allows for straightforward, imperative scripting of business logic, data processing, and application flow, making it accessible for developers familiar with earlier database-centric languages.[36]
The language provides comprehensive object-oriented programming (OOP) support, introduced in Visual FoxPro 3.0, which extends its xBase heritage with features like classes, objects, inheritance, and polymorphism to promote code reusability and maintainability.[36][37] Developers can define classes as blueprints for objects, inheriting properties and methods from parent classes—such as overriding behaviors in subclasses—while polymorphism enables methods with the same name to execute differently based on the object type, supporting dynamic binding in class hierarchies.[37][2] Visual FoxPro includes a set of built-in base classes, including Form for application windows, Label for static text displays, and Grid for tabular data presentation, which serve as foundational elements for building user interfaces and custom components.[37][38]
At its core, Visual FoxPro employs an event-driven programming model that facilitates responsive, interactive applications by allowing controls and forms to react to user actions through predefined methods.[39][2] For instance, the Init() method initializes objects upon creation, setting up properties and bindings, while the Click() method handles user interactions like button presses, enabling seamless integration of procedural code within an object-oriented framework.[39] This model exposes the Windows event loop, supporting modeless operations and custom event handling for enhanced application dynamism.[36][38]
Error handling in Visual FoxPro is robust, featuring the TRY...CATCH...FINALLY structure for structured exception management, where the TRY block encloses potentially erroneous code, CATCH processes exceptions with optional conditions, and FINALLY ensures cleanup execution regardless of outcomes.[40][41] Introduced in version 8.0, this mechanism allows nesting for granular control and escalation via THROW if needed, improving application reliability.[40] Additionally, the ASSERT command, available since version 5.0 and controlled by SET ASSERTS, aids debugging by testing conditions during development and displaying messages or halting execution if assertions fail.[42][43]
Visual FoxPro provided an integrated development environment (IDE) that streamlined the creation, testing, and deployment of database applications through a suite of visual and productivity tools. Central to this environment were visual designers for forms, reports, labels, and menus, which employed drag-and-drop interfaces to facilitate rapid prototyping and layout. Developers could place controls such as text boxes, buttons, and grids onto canvases intuitively, while property sheets offered detailed customization options, including adjustments to appearance (e.g., fonts, colors), behavior (e.g., events, methods), and data binding, all accessible via a graphical interface without manual coding for basic setups.[44][2]
The Project Manager served as the organizational hub of the IDE, enabling developers to assemble and manage project files such as program files (.prg), form classes (.scx), and report files (.frx) within a hierarchical structure. It supported the inclusion of diverse assets like tables, queries, and libraries, allowing for easy navigation and editing directly from a tree-view interface. Compilation options were configurable through the Project Manager, facilitating the building of standalone executables (EXEs) or dynamic link libraries (DLLs) with settings for compression, encryption, and resource embedding to optimize distribution and performance.[45][46]
Debugging capabilities were robust, featuring a dedicated Debugger window with tools for setting breakpoints at specific code lines, monitoring variables via watch and locals windows, examining the call stack for execution flow, and using trace windows to log runtime events. The integrated profiler complemented these by analyzing code performance, identifying bottlenecks through metrics like execution time and function calls, thus aiding in optimization. Event tracking and coverage logging further enhanced troubleshooting by recording object interactions and code path usage during sessions.[47][48]
The Report Writer integrated seamlessly into the IDE as a visual tool for designing data-driven outputs, supporting banding for structured layouts (e.g., detail, header, footer bands), grouping by fields for summarized views, and interactive previews to iterate designs in real-time. It allowed for complex expressions in calculations and conditional formatting, with export capabilities to formats including PDF for printable documents, HTML for web viewing, and XML for data interchange, ensuring versatility in report deployment.[49][50][2]
Language Syntax
Procedural and object-oriented elements
Visual FoxPro supports a procedural programming paradigm through a variety of built-in commands that facilitate screen management, user input, and control flow structures. The CLEAR command erases the contents of the main screen, a user-defined window, or the entire Visual FoxPro window, providing a simple way to reset the display during program execution.[51] Similarly, the INPUT command captures data entered by the user from the keyboard and stores it in a memory variable or array element, supporting various data types such as characters, numbers, dates, and logicals.[52] For more structured screen output and input, the @ command is used in combinations like @ ... SAY to display text or expressions at specified row and column positions on the screen, and @ ... GET to create input fields that allow users to enter data at those positions, often activated collectively with a READ command.[53]
Control flow in procedural code is managed through looping constructs, enabling repetitive execution of commands based on conditions or counters. The DO WHILE ... ENDDO structure executes a block of commands repeatedly as long as a specified logical expression evaluates to true, with each DO WHILE requiring a matching ENDDO to close the loop.[54] In contrast, the FOR ... ENDFOR loop iterates over a range defined by an initial value, an upper limit, and an optional step increment, executing the enclosed commands until the counter reaches the limit or encounters an ENDFOR or NEXT directive.[55] These procedural elements form the foundation for writing straightforward, imperative programs in Visual FoxPro, often used in conjunction with its event-driven model for handling user interactions.[56]
In addition to procedural capabilities, Visual FoxPro incorporates object-oriented programming features, allowing developers to define reusable classes that encapsulate data and behavior. Classes are defined using the DEFINE CLASS command, which specifies a class name and optionally inherits from a parent class via the AS clause, such as DEFINE CLASS MyClass AS Custom.[57] Within the class definition, properties—variables that store object state—are declared using access specifiers like PUBLIC for accessible from anywhere, PRIVATE for internal use only, or PROTECTED for subclass access. Methods, which define object behavior, are implemented as either PROCEDURE for subroutines that do not return values or FUNCTION for those that do, placed within the class block.[56]
Objects are instantiated from classes using the CREATEOBJECT() function, which returns a reference to a new instance, as in oObj = CREATEOBJECT("MyClass"), enabling runtime creation without prior compilation.[58] Once created, properties and methods are accessed via dot notation, such as oObj.Property to read or set a value or oObj.Method() to invoke a procedure or function. Inheritance is facilitated by the AS superclass clause in the DEFINE CLASS syntax, allowing subclasses to extend or override parent behaviors, while the ADD OBJECT clause composes objects into a class or form for modular design.[56] These OOP elements integrate seamlessly with Visual FoxPro's procedural syntax, supporting hybrid development approaches.
Data manipulation commands
Visual FoxPro provides a suite of commands for manipulating data in tables, cursors, and queries, enabling developers to perform operations such as opening tables, adding or updating records, and executing SQL-like statements directly in the language. These commands are integral to the xBase heritage of Visual FoxPro, allowing procedural control over data without requiring external database engines for local operations. The syntax is concise and optimized for rapid development, often leveraging the Rushmore query optimization engine for efficient filtering and indexing.[59]
Table Operations
Table operations in Visual FoxPro begin with the USE command, which opens a table file (.DBF) in a work area for manipulation. The basic syntax is USE TableName [IN nWorkArea], where TableName specifies the .DBF file, and nWorkArea is an optional alias or work area number (1-255); if omitted, Visual FoxPro assigns the next available work area. This command makes the table the active work area, allowing subsequent commands to reference it implicitly. For example, USE Customers opens the Customers.DBF table. Once opened, records can be added using APPEND BLANK, which adds a new empty record to the end of the table and positions the record pointer there; the syntax is simply APPEND BLANK, and it supports scoping with ALL, REST, or NEXT n to add multiple records. This is particularly useful for buffered tables to avoid triggering validation rules prematurely.[60][61][62]
To update field values, the REPLACE command assigns expressions to one or more fields across a scope of records. Its syntax is REPLACE Field1 WITH eExpression1 [, Field2 WITH eExpression2 [...]] [SCOPE] [FOR lExpression], where Field is the target field name, eExpression is the value or expression to assign, SCOPE limits the operation (e.g., ALL, NEXT 10), and FOR applies a conditional filter. For instance, REPLACE ALL Price WITH Price * 1.1 FOR Category = "Electronics" increases prices by 10% for electronics records. REPLACE operates on the active table or cursor and can handle multiple fields in a single statement for efficiency.[63][64]
Record deletion uses the DELETE command to mark records as deleted without physically removing them, preserving data integrity for potential recovery. The syntax is DELETE [SCOPE] [FOR lExpression], marking records in the specified scope or those meeting the FOR condition; for example, DELETE FOR Status = "Inactive". Deleted records remain accessible but are skipped by default in operations unless SET DELETED OFF is issued. To unmark records, RECALL reverses the deletion with identical syntax: RECALL [SCOPE] [FOR lExpression], such as RECALL ALL to restore all deleted records. Physical removal of marked records requires the PACK command after confirming no further RECALL is needed.[65][60][66]
Query Syntax
Visual FoxPro's native SQL implementation, invoked via the SELECT command, allows retrieval and transformation of data from tables or cursors into a new cursor. The core syntax is SELECT [AS|INTO] eSelectList FROM cSourceTable [WHERE lFilter] [GROUP BY cGroupExpr] [HAVING lHavingExpr] [ORDER BY cOrderExpr], where eSelectList specifies fields or expressions (e.g., Field1, [SUM](/page/Sum)(Field2) AS Total), cSourceTable is the source (supporting aliases like Table1 AS T1), WHERE filters rows, GROUP BY aggregates, HAVING filters groups, and ORDER BY sorts results. For example:
SELECT CustomerID, OrderDate, Total
FROM Orders
WHERE OrderDate > {^2000-01-01}
ORDER BY Total DESC
INTO CURSOR HighValueOrders
SELECT CustomerID, OrderDate, Total
FROM Orders
WHERE OrderDate > {^2000-01-01}
ORDER BY Total DESC
INTO CURSOR HighValueOrders
This creates a cursor named HighValueOrders with filtered and sorted data. SELECT supports INNER, LEFT, RIGHT, and FULL OUTER JOINs via FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID, as well as UNION for combining result sets. The command leverages Rushmore for optimized execution on local tables when possible.[67][68][69]
Cursor Management
Cursors, temporary work tables created by SELECT or other operations, are managed through commands that facilitate viewing, iteration, and searching. The BROWSE command displays the active cursor or table in an interactive grid for editing and navigation, with syntax BROWSE [FIELDS FieldList] [RANGE lExpression] [KEY cKeyExpr] [TITLE cTitle] [WINDOW wWindow], allowing customization of fields, filters, and display options; for example, BROWSE FIELDS Name, Balance FOR Balance > 1000 shows only high-balance records. BROWSE supports immediate editing, including APPEND, REPLACE, and DELETE within the interface.[70][59]
For programmatic looping, SCAN...ENDSCAN iterates over records meeting a condition, executing code for each: SCAN [WHILE lWhileExpr] [FOR lForExpr] [RANGE lRangeExpr] ... ENDSCAN. The record pointer advances automatically, and the loop exits on EOF or failure of conditions; an example is:
SCAN FOR Active = .T.
REPLACE LastAccess WITH DATETIME()
ENDSCAN
SCAN FOR Active = .T.
REPLACE LastAccess WITH DATETIME()
ENDSCAN
This updates the LastAccess field for all active records. SEEK performs indexed searches on the current cursor or table, with syntax SEEK vKeyExpr, positioning the pointer to the matching record if the controlling index matches vKeyExpr; it returns .T. if found. For non-indexed searches, LOCATE is an alternative, but SEEK is faster on indexed data. Cursor management also includes commands like GO TOP/BOTTOM for positioning and REQUERY for refreshing remote cursors.[71][72]
Upsizing
For applications requiring connectivity to remote servers, SQLEXEC executes SQL statements against ODBC data sources, facilitating upsizing from local DBF files. The function syntax is SQLEXEC(nConnection, cSQLStatement [, aParameterArray] [, cCursorName]), where nConnection is a handle from SQLSTRINGCONNECT or SQLCONNECT, cSQLStatement is the SQL (e.g., native to the backend like SQL Server), aParameterArray binds parameters for dynamic queries (using ? placeholders), and cCursorName specifies the output cursor. It returns 1 on success, -1 on error, or the number of result sets for SELECTs. For example:
lcSQL = "UPDATE Customers SET Balance = ? WHERE ID = ?"
lnResult = SQLEXEC(lnConnHandle, lcSQL, {lnNewBalance, lnCustID})
lcSQL = "UPDATE Customers SET Balance = ? WHERE ID = ?"
lnResult = SQLEXEC(lnConnHandle, lcSQL, {lnNewBalance, lnCustID})
This passes parameterized updates to the server, supporting dynamic SQL while preventing injection risks. SQLEXEC is essential for hybrid applications mixing local and remote data.[73][74][75]
Integration and extensibility
Visual FoxPro provides robust integration with external systems through COM/ActiveX automation, enabling developers to instantiate and control objects from other applications such as Microsoft Excel or Word. The CREATEOBJECT() function creates an instance of a specified OLE automation server or Visual FoxPro class, returning an object reference that can be used to invoke methods and properties. For example, CREATEOBJECT("Excel.Application") launches an Excel application instance, allowing programmatic manipulation of spreadsheets for data export or reporting tasks.[76] Additionally, Visual FoxPro can act as a COM server, exposing its classes via the IMPLEMENTEDBY clause in class definitions, which facilitates automation from client applications and supports event handling for bidirectional communication. This extensibility was enhanced in version 7.0 with strong typing and interface implementation from external type libraries, improving performance through early binding.[21]
For database connectivity beyond its native DBF format, Visual FoxPro leverages ODBC to interface with heterogeneous data sources like SQL Server or Oracle. The SQLEXEC() function executes passthrough SQL statements on an open ODBC connection handle, enabling direct queries and updates without relying on remote views. This approach supports parameterized queries for efficiency and handles result sets by populating cursors with returned data, as in SQLEXEC(nHandle, "SELECT * FROM Table WHERE Condition", nResultArray).[74] ODBC integration requires establishing a connection via SQLCONNECT(), which returns a handle for subsequent operations, ensuring secure and standardized access to non-native databases.
XML support in Visual FoxPro facilitates data exchange with web services and structured documents, with the XMLTOCURSOR() function parsing XML strings or files into table cursors for native processing. This utility maps XML elements to cursor fields, handling attributes and nested structures while supporting namespaces for complex schemas introduced in version 7.0.[77] Complementing this, the _GenHTML system variable and related utilities like MODIFY REPORT...TO HTML generate web-ready output from reports, labels, or forms, converting Visual FoxPro objects into static HTML pages suitable for email distribution or intranet deployment. These features, bolstered by CURSORTOXML() for bidirectional conversion, enable seamless integration in n-tier web applications.[21][78]
Later versions of Visual FoxPro, particularly 9.0, introduced limited interoperability with the .NET Framework through COM interop, allowing calls to .NET assemblies through COM interop or tools like wwDotnetBridge for registration-free activation. Developers can invoke .NET methods and access classes from Visual FoxPro code, facilitating hybrid applications that leverage .NET's richer ecosystem for tasks like advanced data processing, though this requires careful handling of data types and exceptions due to the bridging layer's constraints. This capability extends Visual FoxPro's lifespan by integrating with modern .NET components without full migration.[79][80]
Practical Examples
Object instantiation
In Visual FoxPro, object instantiation involves creating instances of classes using the CREATEOBJECT() function, which constructs an object from a specified class definition and returns a reference to it. This process triggers the Init event of the object for initialization, allowing developers to set initial properties or perform setup tasks. User-defined classes must be defined using the DEFINE CLASS command in a program file (.prg) or stored in a class library (.vcx) before instantiation.[76][81]
A simple class definition and instantiation can be illustrated with a basic custom class inheriting from the Session base class, which includes an Init procedure to set a property. The following code defines the class Test:
DEFINE CLASS Test AS Session
Message = ""
PROCEDURE Init
This.Message = "Hello"
ENDPROC
ENDDEFINE
DEFINE CLASS Test AS Session
Message = ""
PROCEDURE Init
This.Message = "Hello"
ENDPROC
ENDDEFINE
To instantiate this class and access its property, use CREATEOBJECT():
oTest = CREATEOBJECT("Test")
? oTest.Message && Outputs: Hello
oTest = CREATEOBJECT("Test")
? oTest.Message && Outputs: Hello
This creates an object reference oTest, executes the Init procedure during instantiation to assign "Hello" to the Message property, and displays the value. The object remains in memory until explicitly released with RELEASE oTest.[81][76]
Event handling in object-oriented programming with Visual FoxPro often occurs within form classes, where methods respond to user interactions such as clicks. For example, consider a form class that includes a command button and a label; the Click event can be handled by defining a procedure in the button's method. The class definition might look like this:
DEFINE CLASS MyForm AS Form
ADD OBJECT cmdButton AS CommandButton WITH ;
Top = 10, Left = 10, Caption = "Click Me"
ADD OBJECT Label1 AS Label WITH ;
Top = 10, Left = 50, Caption = "Ready"
PROCEDURE cmdButton.Click
ThisForm.Label1.Caption = "Clicked"
ENDPROC
ENDDEFINE
DEFINE CLASS MyForm AS Form
ADD OBJECT cmdButton AS CommandButton WITH ;
Top = 10, Left = 10, Caption = "Click Me"
ADD OBJECT Label1 AS Label WITH ;
Top = 10, Left = 50, Caption = "Ready"
PROCEDURE cmdButton.Click
ThisForm.Label1.Caption = "Clicked"
ENDPROC
ENDDEFINE
Instantiating the form with CREATEOBJECT("MyForm") and showing it via oForm.Show() allows the Click event to execute the procedure when the button is pressed, updating a label's caption accordingly. This demonstrates how events integrate with object methods for interactive behavior.[82][81]
Inheritance in Visual FoxPro enables subclasses to extend base classes using the AS clause in DEFINE CLASS, inheriting properties and methods while allowing overrides. For instance, a parent class Parent might define a method, and a child class can inherit and override it. Here's an example:
DEFINE CLASS Parent AS Session
PROCEDURE Greet
? "Hello from Parent"
ENDPROC
ENDDEFINE
DEFINE CLASS Child AS Parent
ADD PROPERTY childprop AS String && Adds a new property
PROCEDURE Greet && Overrides parent's Greet
::Greet && Calls parent's version
? This.childprop + " from Child"
ENDPROC
ENDDEFINE
DEFINE CLASS Parent AS Session
PROCEDURE Greet
? "Hello from Parent"
ENDPROC
ENDDEFINE
DEFINE CLASS Child AS Parent
ADD PROPERTY childprop AS String && Adds a new property
PROCEDURE Greet && Overrides parent's Greet
::Greet && Calls parent's version
? This.childprop + " from Child"
ENDPROC
ENDDEFINE
Instantiation proceeds as oChild = CREATEOBJECT("Child"), followed by oChild.childprop = "Hi" and oChild.Greet, which outputs both messages by invoking the parent method via the :: scope resolution operator. This approach promotes code reuse while customizing behavior in subclasses.[83][81]
Database operations
Visual FoxPro provides a suite of procedural commands for performing common database operations on tables and cursors, enabling developers to query, append, update, and iterate through data efficiently. These commands operate directly on the Rushmore query optimization engine, which can accelerate processing for indexed fields, though complex joins may require manual optimization.[67]
A fundamental operation is querying data using the SELECT command, which retrieves records from one or more tables based on specified criteria and outputs the results to a cursor for further manipulation. For instance, to fetch all records from a customers table where the city is "NY" and store them in a temporary cursor, the following code can be used:
SELECT * FROM customers WHERE city = "NY" INTO CURSOR [temp](/page/Temp)
SELECT * FROM customers WHERE city = "NY" INTO CURSOR [temp](/page/Temp)
This creates a read-only cursor named [temp](/page/Temp) containing the filtered records, allowing subsequent operations without altering the source table.[67]
Appending data is handled by the APPEND FROM ARRAY command, which adds multiple records to the end of the current table by populating them from a two-dimensional array, where each row corresponds to a new record and each column to a field value. An example involves an array aData structured to match the table's fields:
SELECT temp
APPEND FROM ARRAY aData
SELECT temp
APPEND FROM ARRAY aData
This command assumes the array dimensions align with the table structure; mismatches can lead to errors or partial data insertion.[84]
Updating records across a table uses the REPLACE command, which modifies field values based on an expression, often scoped to all records or filtered subsets for bulk operations like salary adjustments. For example, to increase all salaries in an employees table by 10%:
REPLACE ALL salary WITH salary * 1.1 IN employees
REPLACE ALL salary WITH salary * 1.1 IN employees
This applies the update atomically to the specified scope, with the IN clause targeting a particular table if not current.[63]
Transaction control ensures data integrity during multi-step updates by grouping operations, allowing commits or rollbacks. Visual FoxPro supports nested transactions up to five levels deep, initiated with BEGIN TRANSACTION and concluded with END TRANSACTION for commits or ROLLBACK for reversals. A basic example wraps updates to related tables:
BEGIN TRANSACTION
REPLACE salary WITH salary * 1.1 IN employees
REPLACE bonus WITH bonus * 1.05 IN bonuses
END TRANSACTION
BEGIN TRANSACTION
REPLACE salary WITH salary * 1.1 IN employees
REPLACE bonus WITH bonus * 1.05 IN bonuses
END TRANSACTION
If an error occurs mid-transaction, issuing ROLLBACK reverts all changes, preventing partial updates.[85]
For interactive viewing and programmatic iteration, the BROWSE command displays table records in a grid window for manual inspection and editing, while SCAN provides a loop construct for automated processing. To open a browse window on an inventory table:
USE inventory
BROWSE
USE inventory
BROWSE
This launches an editable grid; options like FIELDS or FOR can limit displayed data.[86] Similarly, to scan for low-stock items and output their names:
[SCAN](/page/Scan) FOR qty < 10
? item
END[SCAN](/page/Scan)
[SCAN](/page/Scan) FOR qty < 10
? item
END[SCAN](/page/Scan)
The SCAN loop advances the record pointer sequentially, executing the body for each matching record until EOF, and is optimized for indexed conditions.[87]
External connectivity
Visual FoxPro provides robust mechanisms for connecting to external data sources and applications, enabling seamless integration with databases, spreadsheets, and structured data formats beyond its native DBF files. This connectivity supports ODBC for relational databases, COM automation for interacting with Microsoft Office applications, and built-in functions for handling XML data, allowing developers to exchange information in heterogeneous environments.[88]
One primary method for external database connectivity is through ODBC passthrough, which allows direct execution of SQL statements against remote data sources without relying on remote views. The SQLSTRINGCONNECT() function establishes a connection using an ODBC connection string, returning a handle for subsequent operations. For example, to connect to a MySQL database:
foxpro
h = SQLSTRINGCONNECT("DSN=MySQL;UID=username;PWD=password;DATABASE=company")
h = SQLSTRINGCONNECT("DSN=MySQL;UID=username;PWD=password;DATABASE=company")
If the connection succeeds (handle h is positive), SQL commands can be executed using SQLEXEC(), which sends the statement to the server and optionally populates a local cursor with results. A SELECT query might look like this:
foxpro
SQLEXEC(h, "SELECT * FROM orders WHERE status = 'pending'", "pendingOrders")
SQLEXEC(h, "SELECT * FROM orders WHERE status = 'pending'", "pendingOrders")
For data modification, such as inserting records:
foxpro
SQLEXEC(h, "INSERT INTO orders (order_id, customer, amount) VALUES (1001, 'Acme Corp', 500.00)")
SQLEXEC(h, "INSERT INTO orders (order_id, customer, amount) VALUES (1001, 'Acme Corp', 500.00)")
The function returns 1 for success or -1 for failure, with error details accessible via SQLCANCEL(h) or AERROR(); connections are closed with SQLDISCONNECT(h). This approach bypasses Visual FoxPro's native SQL dialect, leveraging the full capabilities of the external database engine.[73]
COM automation enables Visual FoxPro to control and exchange data with external applications that expose OLE Automation interfaces, such as Microsoft Excel for reporting or data export. The CREATEOBJECT() function instantiates an object from a registered COM server, passing initialization parameters if needed. To automate Excel and insert data from a VFP cursor:
foxpro
oXL = CREATEOBJECT("Excel.Application")
oXL.Visible = .T. && Make Excel visible for development
oWS = oXL.Workbooks.Add()
oWS.Cells(1,1).Value = "Data from VFP"
* Assuming a cursor 'orders' exists, loop to populate:
GO TOP
FOR lnI = 1 TO RECCOUNT("orders")
oWS.Cells(lnI + 1, 1).Value = orders.order_id
oWS.Cells(lnI + 1, 2).Value = orders.customer
SKIP
ENDFOR
oXL.ActiveWorkbook.SaveAs("c:\output\orders.xlsx")
oXL.Quit()
RELEASE oXL
oXL = CREATEOBJECT("Excel.Application")
oXL.Visible = .T. && Make Excel visible for development
oWS = oXL.Workbooks.Add()
oWS.Cells(1,1).Value = "Data from VFP"
* Assuming a cursor 'orders' exists, loop to populate:
GO TOP
FOR lnI = 1 TO RECCOUNT("orders")
oWS.Cells(lnI + 1, 1).Value = orders.order_id
oWS.Cells(lnI + 1, 2).Value = orders.customer
SKIP
ENDFOR
oXL.ActiveWorkbook.SaveAs("c:\output\orders.xlsx")
oXL.Quit()
RELEASE oXL
This code creates an Excel instance, adds a workbook, writes header and data rows, saves the file, and releases the object to free resources. Error handling can be added using AERROR() to catch COM exceptions, ensuring robust integration with desktop productivity tools.[76]
For structured data interchange, Visual FoxPro includes native XML support via functions like XMLTOCURSOR(), introduced in version 7.0, which parses XML into a local cursor for manipulation as if it were a native table. The function accepts XML from a string or file and generates a cursor with fields inferred from the XML schema. An example using an external XML file:
foxpro
XMLTOCURSOR("orders.xml", "ordersCursor")
* Now manipulate as a standard cursor:
SELECT ordersCursor
REPLACE amount WITH amount * 1.1 FOR status = "pending" && Apply 10% markup
BROWSE && View or further process
XMLTOCURSOR("orders.xml", "ordersCursor")
* Now manipulate as a standard cursor:
SELECT ordersCursor
REPLACE amount WITH amount * 1.1 FOR status = "pending" && Apply 10% markup
BROWSE && View or further process
The XML must conform to a tabular structure (e.g., root element with repeating child elements for rows), and flags like 512 can suppress namespace processing if needed. Results are stored in the specified cursor (defaulting to "XMLRESULT"), allowing seamless blending of external XML data with VFP's data engine for reporting or further SQL operations. Conversion back to XML uses CURSORTOXML() for bidirectional exchange.[77]
Discontinuation and Legacy
End of support timeline
Visual FoxPro 9.0, released on December 22, 2004, received its final update with Service Pack 2 (SP2) in October 2007, after which Microsoft ceased all further development and enhancements.[1][6] This marked the end of active versioning for the product, with no additional service packs or major releases planned.[8]
Microsoft provided mainstream support for Visual FoxPro 9.0 until January 12, 2010, during which period new feature requests, non-security hotfixes, and design change requests were addressed.[6] Following this, extended support continued until January 13, 2015, limited to security updates and critical fixes, after which the product entered a fully unsupported state.[6] Exceptionally, Microsoft released a security update for Visual FoxPro 9.0 SP2 in March 2021 to address vulnerabilities in ActiveX controls.[89] Upon the conclusion of extended support, Microsoft designated Visual FoxPro as a legacy technology, indicating no ongoing official assistance or updates.[1]
The discontinuation stemmed from Microsoft's strategic pivot toward the .NET Framework and server-oriented database solutions like SQL Server, amid a broader industry decline in demand for xBase-style desktop database tools in favor of web and enterprise-scale technologies.[1] This shift narrowed Microsoft's database offerings to prioritize Access for lighter applications and SQL Server for robust, scalable environments, rendering Visual FoxPro non-strategic for future investment.[8]
Ongoing use and alternatives
Despite Microsoft's discontinuation of support for Visual FoxPro in 2007, with extended support ending in 2015, many enterprises continue to operate VFP-based applications for mission-critical tasks such as inventory management and accounting due to their proven reliability and low maintenance needs in stable environments.[90][91] Market data indicates that over 5,400 companies worldwide still rely on Visual FoxPro systems as of 2025, often in sectors where custom database-driven workflows remain effective.[10]
The Visual FoxPro community remains active through third-party tools and online resources that extend the platform's viability. West Wind Web Connection, a framework for integrating VFP applications with web technologies, continues to receive updates and support for enabling browser-based access to legacy systems.[92] Developer forums such as Tek-Tips and events like Virtual Fox Fest provide ongoing patches, troubleshooting, and knowledge sharing among users.[93][94]
For modernization, migration paths include automated conversion tools to .NET frameworks, such as FmPro Migrator, which handles code, forms, and data transfer to C# or VB.NET, or manual rewrites for complex logic.[95] Alternatives encompass low-code platforms like Lianja, which supports direct import of VFP files for app redevelopment, and Servoy, offering a visual development environment compatible with xBase syntax.[96][97] xBase successors like the open-source Harbour project allow recompilation of VFP code for cross-platform deployment without full rewrites.
Key challenges in sustaining VFP include heightened security vulnerabilities from unpatched code, exposing systems to exploits without official updates, and compatibility issues with modern operating systems.[10] A 2025 industry survey found that 84% of VFP users recognize risks from lack of maintenance, while 59% report operating system compatibility as a primary concern, particularly with Windows 11 requiring compatibility modes or virtual machines for runtime libraries.[98][99][100]