When you first begin using the new Visual FoxPro 8, you are sure to find useful new features that will make your development tasks easier.

Several members of the Visual FoxPro developer community who have already worked with VFP 8 tell us their opinions of the best and most useful new features. Perhaps their answers will help guide you to some cool ideas you can put to work right away.

3 Cool New Tools

Tamar E. Granor

Technical Editor, FoxPro Advisor

Author, What's New in Visual FoxPro 8

I'm really excited about the three new tools that VFP 8 offers: Code References, the Toolbox and the Task Pane Manager. Each makes it easier to get things done fast.

The Code References tool provides a project-oriented search-and-replace tool. It also provides the engine for the new View Definition item on the context menu of editing windows, which lets you quickly move to the definition of the highlighted item (variable, property, method, class, constant, etc.). I've already used this tool extensively to explore the code of all three tools, as well as for searching in a multi-developer client project. It makes understanding the structure of a project much easier.

The Toolbox strikes me as a marriage of the Form Controls toolbar and the Component Gallery. It's more capable than the toolbar and much easier to understand and use than the Gallery. It provides a home for all the controls you use, as well as for blocks of text (such as a standard header). The ability to add my own categories and items means that I can put everything I'll need for a given project in one easy-to-find place.

I'm most intrigued by the possibilities of the Task Pane Manager. This tool provides a portal for VFP development. The panes provided include a way to centralize access to all my regular development tools, offer quick access to sample code, let me organize paths and settings, and more. But the Task Pane Manager doesn't stop there. You can add third-party panes and create your own. I've already added a pane giving me quick access to my Hentzenwerke e-books, and another that displays my own website. I expect the VFP 8 versions of most VFP tools to include custom task panes, so you can switch between them easily.

CursorAdapter Gets My Vote

Mark McCasland

US Environmental Protection Agency

M & J Software

www.mctweedle.com

The most exciting new feature in VFP8 for me is the Cursor Adapter class. This class can be used to access native VFP data or remote data from SQL Server, Oracle and any other SQL database via ODBC or ADO provided there is a driver or provider for the DB. The companion to this is the ability to create a shared connection for any remote data (including remote views) using the SQLEXEC() or SQLSTRINGCONNECT() functions.

Even if you are not yet developing for a SQL database, the CursorAdapter will allow you to specify a NATIVE DataSourceType so you can handle your VFP data like a SQL database. Then, if you ever have to upsize the database to SQL Server or Oracle, all you have to do is change the *DataSource and *DataSourceType properties in each CursorAdapter.

Get used to seeing the *Property shorthand notation because there are three prefixes associated with each suffix preceded by an asterisk. They prefixes are always INSERT, UPDATE and DELETE. For example, *Cmd is short for the InsertCmd, UpdateCmd and DeleteCmd properties. Then there is the same trio set for *CmdDataSource and *CmdDataSourceType.

I can now create a "generic" subclass of this object which I will then use to create a subclass for each remote table in a database. In fact, developing a builder to do this for you is quite simple. Using my builder, I loop through an array of tables and get the column and data type meta data from the SQL database for each table, which I then use to populate the following properties for the Adapter:

Alias

ConversionFunc

KeyFieldList

SelectCmd

Tables

UpdatableFieldList

UpdateNameList

I cheat a little for the KeyFieldList property because ALL my tables use a surrogate integer field for the primary key, and it is always the same name, KEYID. However, I can also retrieve the PK column for any table from the SQL database to make this even more generic.

The ConversionFunc property lets you specify what conversion function to perform on a particular field. For example, for VARCHAR data types, VFP in the past would send data right padded with spaces. Well, that defeated the purpose of a VARCHAR column since all these spaces were not RTRIMmed before being sent to the database unless you handled all the INSERT or UPDATE SQL yourself. Now, you can list such fields and how to format the data before it goes to the database. For example:

loAdapter.ConversionFunc = ;
  [LastName RTRIM, FirstName RTRIM]

When you create the SQL for the UpdateCmd or InsertCmd properties and are going to trim your character fields, it does make a difference where the ? goes. For example:

UPDATE Customers SET LastName = RTRIM(?crsCustomers.LastName) WHERE...

UPDATE Customers SET LastName = ?RTRIM(crsCustomers.LastName) WHERE...

In the first UPDATE, RTRIM is included in the SQL passed to the server, so RTRIM must be a valid function on the server. For Oracle and SQL Server, this is valid. However if you just used TRIM() or ALLTRIM(), you would generate a server error. In the second UPDATE, the value of crsCustomers.LastName is evaluated at the client, and only the trimmed value is passed to the server. So the use of TRIM(), ALLTRIM() or any other valid VFP function will not matter.

As you can see, the CursorAdapter can be a very powerful object, and I did not even touch upon its numerous events and methods that let you have a little or as much control over the handling of the data as you want. I hope this gives you an idea of the excitement this new class has generated in the Visual FoxPro community. It has already become a very important component in my toolbox.

If you are interested in detailed examples of its use that you can use today [if you have VFP8], you can download them from my web site, http://www.mctweedle.com/downloads/CursorAdapter.zip. It also helps to have MSDE or SQL Server with the Northwind sample database or Oracle. VFP 8 now comes with a converted Northwind VFP database, and my examples show how the Adapter works with both databases.

You can also download my CursorAdapter builder at http://www.mctweedle.com/downloads/cabuilder.zip.

How I Will Use BINDEVENT()

Drew Speedie

Contributing Editor, FoxPro Advisor Magazine

Architect of the Visual MaxFrame Professional framework

The new BINDEVENT() function is what I'm most excited about of all the new VFP 8.0 features. Here are some of the ways I'm working on implementing it in the Visual MaxFrame Professional (VMP) framework.

Create a handler for _Screen: You can't subclass the _Screen object, but you can now BINDEVENT() its methods and properties to a custom screen handler.

BINDEVENT() the _Screen.Resize event to the screen handler object. Whenever the user resizes _Screen, the screen handler code fires to reposition a wallpaper graphic at the desired location in _Screen, along with anything else you want to happen when _Screen is resized either programmatically or interactively.

It's a snap to create a shortcut menu for the _Screen surface itself, by BINDEVENT()ing to _Screen.RightClick(). This and the previous item are what I call "runtime subclassing" ? adding behaviors to the method of an existing object at runtime.

If need be, you can even implement "runtime access and assign methods". Just BINDEVENT() the _Screen.Caption property to your custom screen handler. For assign-style functionality, BINDEVENT() to _Screen.Caption once without the optional nFlags parameter to save the Caption value before it is updated, and BINDEVENT() a second time, passing the nFlags parameter as 1, where you can take action based on the newly-assigned _Screen.Caption while having access to its original value saved in the first BINDEVENT().

BINDEVENT() _Screen.MouseMove() to take action when the mouse moves over a particular area of the screen. Use this idea to confuse the heck out of the users of your application, by firing random application events. Or try more useful (but less fun) things, like making a particular corner of _Screen "hot" when the mouse passes over it. I've setup the extreme upper-right corner of my _Screen during development to fire up the Toolbox, as a poor man's simulation of a flyout behavior.

Eliminate the need for tightly-coupled messages between objects: A long time ago I abstracted hard-coded calls in the VMP framework so that forms automatically message instances of a special container class whenever the user initiates basic actions - Add, Delete, Save, Cancel, etc. Then container class "registers" with the form on instantiation, so the form can message them without iterating through all the members of the form.

While I'm not planning to take the time to rip out that code just because I can, from now on I can have ANY control participate in those actions simply by having them BINDEVENT() to the desired form methods. The form doesn't have to know they exist.

Eliminate the need for column and header classes: The biggest reason I want to subclass columns and headers is to implement behaviors, not set properties. Now the grid can just iterate through its member columns and their headers, BINDEVENT()ing events to grid methods where all the actual work is done.

It doesn't matter what column/header classes are instantiated, and even the VFP base classes work fine. For example, the RightClick of a header can delegate to a custom HeaderRightClick method of the grid, which can handle something like toggling the sort order ascending/descending.

The grid can determine which header called via AEVENTS(), passing the 2nd parameter as zero. But since you will most likely create column and header classes now that VFP 8.0 makes that much easier, the BINDEVENT() can be done by the columns and headers as they instantiate, rather than the grid having to iterate through them when it instantiates.

Handle object reference cleanup in forms: When form members store object references to custom properties, it's critically important that those object references be released no later than the Form.Destroy(). This has always been problematic because the Form.Destroy() fires BEFORE the Destroy() of each of its members, making it impossible for the members to handle object reference cleanup in their Destroy().

In VFP 8.0, just BINDEVENT() a custom ObjectRefCleanup() method to the Form.Destroy(), passing the 5th nFlags parameter as 0 to ensure the member.ObjectRefCleanup() code fires before the Form.Destroy() finishes.

Member Classes Are Great!

Barbara Peisch

Peisch Custom Software, Inc.

www.peisch.com

My favorite new feature in VFP 8 is Member Classes. It isn't a feature that's receiving a lot of press, but I think it's one that most developers really want. The best examples I can think of that makes Member Classes so great are ones using PageFrames. Up until now, if you wanted to use your own page subclass on your pageframes, you had to define that page class in code, and couldn't use it in the class designer.

You then had to have code in your PageFrame's Init to add the pages at runtime. Bleh! Now you can visually design a page subclass, and by specifying that page subclass as the member object in your PageFrame base class, all your PageFrames will use your subclass instead of the native page class.

Using PageFrames, there are two common examples I can think of that make this very useful. The first is if you want the characteristics of the selected page to change. Previously, we had to do this using the UIEnable method of a custom class dropped onto each page. Now, you can just put that code into the page itself. For example, you can change the ForeColor and BackColor of a page in its Activate method, and change it back in the Deactivate method.

Another example is putting a This.Refresh() in the page's Activate method. I don't know about you, but most of the time, that's the behavior I want, except I forget to add it to the page until I have a problem. Now, I'll never have to worry about that again!

The Task Pane and the Environment Manager

Paul Maskens

pmaskens@mvps.org

Well, everyone seems to be talking about the new OO features and new Data handling classes. I'm different, my favorite (and it's cool) is the Environment Manager in the Task Pane. I often end up working on several different projects at once, and this helps organize them, and me! It's so simple to use, too. Open the Task Pane (Tools|Task Pane on the menu) and click on the Environment Manager button. Then click on the Manage Environments link. That's it! It really is so simple to use. So simple that there's no help for it.

In fact, the whole Task Pane is a neat VFP8 feature, extensible and of awesome flexibility. The combination of VFP, Explorer, JavaScript, XML, XSL, and HTML is amazingly powerful.

If you want to dip into it, click on the Options button in the Task Pane. Then click on Task Pane Manager in the treeview on the left. Click on Customize under that. Finally click on the Customize Panes button. Just take a look at how it's put together and what you can do with it.

Click on Environment Manager in the list on the left. The General tab isn't very interesting, but click on the Data tab. Here you find what makes it work:

<?xml version='1.0' encoding='utf-8' standalone='no'?><?xml:stylesheet type="text/xsl" href="envmgr.xsl"?><VFPData> <!-- CONTENT --></VFPData>

How? Well the key is in the stylesheet applied to this very simple XML, in the envmgr.xsl file. Click on the View Files option button at the top of the screen (yes, I missed seeing that for a few minutes, too!). Then open the xsl file just by clicking on it in the list.

This is the magic line in the .XSL file:

<A href="vfps:doapplication?filename=(HOME() + [envmgr.app])&amp;refresh">Manage Environments</A>

Any URL with a vfps: prefix is passed back to the handler in the Task Pane application. So when you click on the Manage Environments link, the application is run with the parameter "refresh". You'll need to take a look at home(7)+"taskpane.dbf" and home(7)+"panecontent.dbf" to see the data that drives the TaskPane application.

Unfortunately, the source code for envmgr.app isn't in the XSource.ZIP file that ships with VFP8, so there's a piece of the puzzle missing. But the code for the Task Pane application itself is there.

The Code References Search Tool

Cindy Winegarden

MCSD, Microsoft Visual FoxPro MVP

cindy.winegarden@mvps.org

The Visual FoxPro Code References Window is one of the great developer productivity tools the Fox team added in Version 8. Use it when you need to spelunk through unfamiliar code or when you're making changes and need to evaluate every place a particular text string is used.

I found this tool invaluable when I was working with the new VFP Toolbox source code. The code for the _Root class, which is the Foundation of the Toolbox, is at least 30 pages. The code references tool made it easy for me to trace references to various objects through that mountain of code.

The Code References tool allows you to specify a search string, choose a project or directory to search, and choose any of several groups of file types to search in. Once you've got your results, you can double-click to open the item containing the text string; when the window comes up the string will be highlighted. Also, you can choose to replace the text with some other string, and the Code References Window can be configured to verify and log each change and create a backup of any file that is changed.

The details of past searches and replacements are stored in the RefAddIn.dbf, RefDef.dbf, and RefFile.dbf tables in the HOME(7) or user application data directory, and until you "Clean Up Source Tables" you will have access to past searches each time you open this tool. Alternatively, you can save search results to any of a number of file formats including DBF, XML, TXT, or the clipboard.

Backward CompatibilityIs A Great Feature

Doug Dodge

ddodge@utah-inter.net

What has become my perennial favorite feature about Visual FoxPro (or even FoxPro for that matter) is that when migrating between different versions there has been relatively little that has changed. Oh, sure, there have been changes and even sometimes core VFP engine behavior has changed, but it has always seemed to be on the margins for me.

In our particular case we have an amalgam of code that dates at times back almost twelve (12) years. Included is code that dates from the early FoxPro 2.0 DOS days. It's mixed in with code that uses classes but is anything but object oriented. IOW, the code was malformed at inception but it worked.

The absolutely amazing thing in my mind is that, with one small exception I'll mention in a moment, all of that code worked absolutely without a hitch in VFP 8!

I never worry about whether or not FoxPro will be able to do something. If it can't, it can be extended or I can connect with some program, DLL or object that can. I suppose in today's world, where consistency is thought to be dull and somehow of lesser value, that this is the bane of a product that just continues to deliver.

Now, there is a new feature in the Visual FoxPro language set that I have had to deal with as a result of some changes to the VFP 8 engine.

The VFP engine has been 'tweaked' to be more compliant with the ANSI-92 SQL standard. This immediately affects all SQL code that is not compliant. However, if you're not yet ready to migrate or don't have time to line up your GROUP BY and HAVING command with the fields you've chosen (part of the engine change) all you need to do is "SET ENGINEBEHAVIOR 70" and you're immediately VFP 7.0 compliant.

No harm, no foul but you now can be much more confident that when you use the new "SET ENGINEBEHAVIOR 80" command that your data result set will have less ambiguity. Oh, "SYS(3099,70)" and "SYS(3099,80)" are new but they are exactly the same as the SET ENGINEBEHAVIOR commands. So, one command in your startup program and that's about it.

So, you'll need to look at GROUP BY stuff and how you manage it with the SYS(3099) (or SET ENGINEBEHAVIOR) command. I guess I just like the notion that my current code doesn't need a whole lot of attention or effort. However, in VFP 8 the default behavior is the new setting, so if you start getting SQL-related error messages you should check this first.

This way you can take the time you need to learn this new behavior and, if you're like me, in 4-5 years you can change and incorporate this new feature.

Having said all of that, my "Favorite Feature" is the consistency of the product (while it continues to embrace the future)." I think peace of mind as a developer one of the nicest features to have. VFP 8 delivers.