FoxPro Home Page FoxPro Windows95 How To Converting FoxPro Printing Guide FoxPro Code Snippets FoxPro FTP Site

Creating ActiveX Components with the Visual FoxPro API/LCK

Page Contents
Introduction
Creating An ActiveX Control
Adding Features to the ActiveX Control
Integrating LCK Capability
The Windows API
Performance
AcitveX Controls versus FLLs
Summary


Introduction

Microsoft® Visual FoxPro™ 5.0 and its ancestors such as Microsoft® FoxPro™ for MS-DOS and Microsoft® FoxBASE+® have always included a way to extend programmability with extensions to other languages. Developers can take advantage of this extensibility to directly address machine hardware, call operating system functions, create exceptionally fast low-level routines, and so on.

The FoxBASE+ LOAD and CALL functions let developers create functions written in Assembly code (.COM or .BIN modules) to do specialized tasks such as take a string as a parameter and display it on the screen in a much larger font, no small feat in the pre-graphical user interface MS-DOS era. The LOAD and CALL functions had many drawbacks: the Assembly code had to be very carefully written, parameter passing was extremely limited, it was difficult to write in C, and it could not be used by products other than FoxBASE+.

FoxPro for MS-DOS later introduced the Library Construction Kit (LCK). The LCK consists of two key files; a header file included in a C program and a LIB file with which the C program is linked. The LCK allows functions to be written in C and C++; functions that can be called from a FoxPro program just as any user-defined function (UDF) is called. Argument passing is the same as a FoxPro UDF, allowing complex UDFs to be created. The FoxPro LCK is a vast improvement over the FoxBASE+ .COM modules that were LOADed and CALLed.

One of the most powerful features of the FoxPro LCK is the ability to create functions written in C and C++ that are callable from FoxPro. Another powerful feature is the ability of the same functions to also call back into FoxPro to manipulate records in a table, the editing environment, FoxPro variables, and so on. There are over 100 callback functions within FoxPro that the C and C++ programs can call. FOXTOOLS.FLL uses several of these callback functions.

Visual FoxPro Version 5.0 extends the capabilities of the LCK one step further. It enables C and C++ programmers to create ActiveX™ controls that can take advantage of the hundreds of Visual FoxPro callback functions. An ActiveX control can be written in several ways so that it:


Creating An ActiveX Control

It's easy to create an ActiveX control because Microsoft® Visual C® version 2.0 and greater provides the OLE Control Wizard now integrated into the Application Wizard.

To create an ActiveX control:

For the examples used in this white paper, the ActiveX control is named FOXOCX. Use the Hierarchical Tree View control in the Microsoft® Developer Studio™ Class view (a pane of the Project window) with the FOXOCX classes to see the various classes, methods, and properties that the wizard generated for the control.

It's easy to run your ActiveX control from within Visual FoxPro or any other ActiveX control host such as TSTCON32.EXE which is included with Visual C. In Visual C, press F5 or execute the project (if the project isn't built yet, Visual C prompts you to build it). Visual C then prompts for an executable file to run, and you can enter the path in two ways:

At this point the ActiveX control doesn't have many features, but you can create a new form in Visual FoxPro and insert the FOXOCX ActiveX control on it. If you place a breakpoint on CFoxocxCtrl::OnDraw, then the Visual C debugger is activated whenever this breakpoint is hit; it occurs whenever the ActiveX control needs to be drawn.
The following sample code shows how you can instantiate the ActiveX control in Visual FoxPro with a few lines of code in a program.


Adding Features to the ActiveX Control

Let's add some properties and methods to the sample ActiveX control. To do this:

Note that the wizard automatically prompts for the parameter types and return values.

Once you've added these, you can see them in the class view, and you can double-click them to see some of the code that was added by the wizard. You can also double-click them from within the Class wizard to see or modify the code.

Note that OLE uses UNICODE, so some of the strings you pass will appear as wide chars. You can convert them to MultiByte chars with the WideCharToMultiByte function which takes CP_ACP as the first parameter for conversion to ANSI chars. To convert in the opposite direction, use the MultiByteToWideChar function.


Integrating LCK Capability

You can change the build settings for the ActiveX control to give it the ability to use the Visual FoxPro LCK. Let's add a method called Data to our sample ActiveX control that takes a single string parameter (LPCSTR dbfname: long pointer to a constant string). The function is passed a parameter that is the full path to the Tastrade Customer table, CUSTOMER.DBF, and it returns a value based on a calculation on numeric data in the table.

First you need to make the compile options of the ActiveX control compatible with the LCK.

Next, add OCXAPI.LIB, included with Visual FoxPro 5.0, to the Object/Library modules on the link page. Be sure that the paths to these files are listed in the Directories dialog, displayed by choosing Options from the Tools menu so Visual C can locate them.

Now add the following line to your CPP file (included with Visual FoxPro 5.0).

Add the following lines to the constructor of your control. This call initializes the LCK.

If you get the message "LINK : warning LNK4098: defaultlib "MSVCRT" conflicts with use of other libs; use /NODEFAULTLIB:library," change the Ignore libraries textbox to msvcrt in the Category Input dialog, displayed by choosing Build from the Settings menu, and then choosing Link Page.

Now you can run the ActiveX control in TSTCON32.EXE and the MessageBox is displayed.

The Data method looks like this:


The Windows API

Visual FoxPro allows you to call many of the thousands of functions available from the Win32 API directly with the DECLARE DLL command. You can also call third-party 32-bit DLLs with DECLARE DLL. To call 16-bit or 32-bit DLLs, use RegFN( ) and CallFN( ) in FOXTOOLS.FLL. Calls to these functions are limited to Visual FoxPro data types such as string and integer. Many of the Win32 API functions require more complex data types such as structures and pointers. Structures can be simulated using a string of bytes of the proper length. However, this is awkward, and there are many functions in the Win32 API that can't be called at all from Visual FoxPro. Use Visual C or Visual C++ to easily access all of these Win32 API functions.


Performance

It's important to note that performance gains from using the LCK can be tremendous, but your performance improvements depend on the nature of your code.

The following sample programs are written in Visual C and Visual FoxPro. They open the Customer table and total the Max_Ord_Amt field 100 times, and then return the total. The Visual C program is just a modification of the Data method described above. There are easier ways to get the total of a numeric field (for example, with the SUM command), but these samples illustrate the differences in execution time between Visual C and Visual FoxPro code when a task is file intensive.

The following examples are computationally intensive, do not perform file I/O operations, and demonstrate that Visual C code is much faster than Visual FoxPro code. These examples calculate the number of prime numbers below a certain value. The two parameters passed to the examples are the value and the number of iterations to perform.

Note that the Visual FoxPro code and the Visual C code are identical except for syntax. You can make the Visual C code even faster if you create a non-debug version with full optimization.


ActiveX Controls versus FLLs

There are several advantages when using ActiveX controls rather than the traditional Visual FoxPro FLLs. (An FLL is a DLL with a few extra Visual FoxPro specific characteristics). For example, the FOXTLIB ActiveX control used by the Visual FoxPro 5.0 Class Browser can be hosted by applications other than Visual FoxPro. FLLs can only be hosted by Visual FoxPro which means the third-party market for ActiveX controls is much greater. There are many more third-party books, development tools, and developers for ActiveX controls than for FLLs.

To use an FLL, use the SET LIBRARY TO command. This loads the FLL and makes all the functions that are exported by the FLL available to a running Visual FoxPro program. Note that there is potential for name conflicts when more than one FLL is loaded.

Many applications that are written in Fox are modeless such as the Visual FoxPro 5.0 Class Browser. You can run multiple instances of the Class Browser and you can switch between it and the Form Designer, Database Designer, or another Visual FoxPro application. When the Class Browser is the active application, it needs access to some Visual C functions to read OLE type library information from ActiveX controls, VFP.EXE, and so on. When another window is brought to the foreground, the Class Browser is inactive, and the Visual C functions should not be in scope. Thus, the SET LIBRARY TO and RELEASE LIBRARY commands would need to be placed in the Activate, Deactivate events of the Class Browser. This is cumbersome and slow.

Instead, the Class Browser uses an ActiveX control, called FOXTLIB, which enables the Class Browser to read and write OLE type library information. The source code to FOXTLIB is distributed with Visual FoxPro 5.0. By using the FOXTLIB ActiveX control, the Visual C functions are automatically encapsulated and scoped to the Class Browser, making it a more encapsulated object, thus increasing efficiency.

Note that you can use the return value of _OCXAPI to determine if Visual FoxPro or another application is the ActiveX control host. The ActiveX control can behave differently depending on its host.

You can test to verify that an ActiveX control is valid by determining what functions the control exports. Use the Visual C LINK and DUMP options to display the functions the ActiveX control exports:

The DllRegisterServer and DllUnregisterServer are exported by all OLE In Process servers that are self-registering. Thus, you can tell an ActiveX control to register itself from within any Visual FoxPro program:

The @DispatchAPI@4 export is the entry point into the ActiveX control that the Visual FoxPro ActiveX control uses to make function callbacks. If your ActiveX control is Visual FoxPro enabled, you should see this export.


Summary

Visual FoxPro and its ancestors have always had ways of utilizing other languages such as Assembly and C. With the evolution of OLE and ActiveX controls comes an architecture that allows the development of code modules that can be accessed uniformly by any host. Using the Visual FoxPro LCK and creating Visual FoxPro enabled ActiveX controls is a great way to take advantage of OLE architecture and extend the power of Visual FoxPro.


Stars.com
The Virtual Library of WWW Development

Copyright ? 1996-97 Pro WEBDesign / Gustavo - webfox@cyberservices.com
All Rights Reserved

This Page was Launched on Friday, March 28, 1997


FoxPro Home Page FoxPro Windows95 How To Converting FoxPro Printing Guide FoxPro Code Snippets FoxPro FTP Site