FoxSpoken Volume 3
Most Recent Volume, Fox Stuff
Other Retired Fox Volumes
articles on this page retired Apr.98
Before you use this material, please be sure you have read and understand
the various provisos *3 with which
I provide it for your use.
Contents of this page:
- The Future of FoxPro: a few more thoughts, and a plea
- GetNextVersion(), another futuristic epic
- Tales from the Framework: Edit options feature not continued
- So You Wanna Learn about the Active Messaging API...
- The Whipped Tip Dept: Unknown datasessions won't bite you
- CLASSDOC update
Special DevCon Non-Issue Issue
This volume of FoxSpoken is somewhat short on technical content, and
it's appearing bit later than I expected to write it. This is mostly because
been exhausting myself trotting around to Fox conferences, presenting Fox
information in-the-flesh rather than over-the-net, for a change.
At conferences, one has a chance to think about the product with a business
perspective. Talking to peers, clients, and the MS staff, is a different
ballgame from the technical focus one maintains when one is coding,
back-to-the-wall, fingers-to-the-grindstone, nose-to-the-screen, at the home.
Consequently my thoughts at this time are about why we use the product
VFP, and perhaps how it uses us, more than about how we use
DevCon attendees: the special DevCon page is now available to you. Check
out the additional technical details there. It's not like I've been doing
The Future of FoxPro again
The most earthshaking revelation at the San Diego International VFP DevCon, for
me, came in the opening session.
Yes, I know it was stultifyingly boring. Let's ignore the tepid
presentation for a moment.
If you were there, do you
remember being asked how many people were new to Fox, and new to DevCon, at this
year's meeting? The people who stood up to be counted for that question had to be
about 25% of the group. This is truly astounding.
No less remarkable was the tiny fraction that was still left standing when the roll
was called for people who'd attended the first and second DevCons in Toledo. Many of
the developers, both inside the developer team and on the front lines using the product,
who helped make this product great with their creativity, their humour,
their intelligence, their independence, and their fearless exploration... are no
longer with us.
Some of our brightest stars -- Tom Kemm, Glenn Hart, Tom Rettig --
have sadly passed away. Others have burned out. Still others seem to blaze in and
out of our lives (if you read this, Dr. X, say hi! Chuck Werner, are you still doing
Fox? Ham Ahlo, what are you writing in these days?)...
The product continues. It's amazing that we're still debating about it. For
heaven's sake, the first article I published with the words "The Future of Fox" in the title was by Jordon Powell,
in FoxTalk -- I believe this was early 1992! Apparently FoxPro has progressed
more than we have, in that time!
Let's just get on with it, shall we?
No crystal balls here, no matter what logo they use at DevCon
One final word, or perhaps a plea: Folks, please stop e-mailing me your CVs and
descriptions of your applications, with requests for advice on how to manage
your careers or which development environment you should use next year. Only
you can answer these questions.
I have no inside information, and if I did it wouldn't help you here. I've said
all I can say on this subject in the last
If you choose to write applications in FoxPro, any version, it is my professional
responsibility to help you write the best FoxPro applications you can possibly
write. If your applications should not be written in FoxPro, or if you shouldn't
be writing in FoxPro, and you are my client, I will not shirk from my professional
responsibility to advise you of these facts as I see them.
But I have to make these judgements on technical grounds, as a developers'
consultant, okay? Clearly, technical issues are only a part of the picture you
have to face. You need to take responsibility for the whole picture.
GetNextVersion(), a whole 'nuther ballgame from Service Packs
If you weren't at DevCon, and somehow missed Fox making front page news (!) in InfoWorld
for a change, Tahoe, the next version of VFP, looks like a winner.
What sexy is
InfoWorld and presumably MS likes Tahoe because of its cozy relationship to Transaction
Server. If you have no idea what that means, or are not sure whether it's relevant
to your development work, or your life, or even your galaxy, here's a list of
some of the other new features MS divulged at DevCon:
- COM components use apartment model threading
- Transaction Server will manage multiple instances of VFP COM components
- Active Document support lets you run a VFP form in Internet Explorer
- True OLE Drag and Drop, so you can drag and drop text from Word onto a VFP form
- Scrollbar property (None, Horizontal, Vertical, Both) allows for scrolling forms
- INDEXSEEK function allows you to find a key value within an index without
moving the record pointer
- AGETCLASS and AVCXCLASSES to obtain class info without having to open the class
- Some file functions in FOXTOOLS.FLL are now native to the VFP language, for example
JUSTEXT( ) and JUSTFNAME( )
- NEWOBJECT( ) function lets you specify the classlibrary from which to instantiate an object,
without messing with SET CLASSLIB, aliasing, etc
- _INCLUDE system variable, so you can set a global #INCLUDE file to be used
by default in your classes
- GIF and JPG file support with preview capability
- VARTYPE( ) function, faster and neater than TYPE() (no checking for ISNULL() of an object-type variable)
- Capability to compare two object references directly, to see if they reference the same object
- AddProperty( ) method for all base classes, which lets you add properties dynamically at runtime
- TRANSFORM function greatly enhanced to turn data type to a string, without worrying about its original data type
- STRTOFILE( ) (with additive option) and FILETOSTR( ), should come in right handy for HTML work!
- HTML Help
MS marketing wouldn't let them tell us everything, so we can figure this
isn't a complete list. On the other hand, they were fairly clear that we weren't
getting a new Report Writer. (Anybody else up for study sessions on Crystal Reports?)
RIP, VFP for Macintosh
MS also told us that there will not be a new Mac version of VFP. Although it's hard to see
how this could be considered a feature, we can respect them for letting us know... my personal
opinion is that this was probably a painful decision to make, but a reasonable one.
Apparently nobody is out there
Last time I gave you some tips on using menu functions
when the menu is not available.
I then said that there are some more pieces of the puzzle you have to think about if
you're using top forms with this functionality. I was prepared to continue this discussion,
if anybody was interested.
Well, apparently nobody is. I got no feedback on that section, even though you guys
usually give me feedback on everything! Either you haven't encountered the problems
yet (hint: they only show up in runtime), you've all solved these problems or you
just plain don't care. Any of these reasons is possible...
I admit I am obsessed with top forms, because they present so many obstacles on the
path to Fox application development nirvana, but you don't have to be!
So, OK, end of subject. This time I'm gonna ask before I write:
Is there anybody interested in finding out
how to use listboxes with a rowsourcetype of 6 (fields) and a rowsource that includes
fields from multiple related tables in the list?
You can, and you don't need a view. Perhaps everybody
already knows the answer to this one -- or perhaps this is another subject you don't
need an answer to. Either way, drop me an e-mail. If there's curiosity, I'll
discuss this topic in the next FoxSpoken issue; if not, let me know what else you'd
like solved and you think would make a reasonable topic here...
Where oh where is the documentation on Active Messaging?
Here's something that apparently half the Fox programmers on the planet are struggling with:
how do you address the Active Messaging API? And how do you find out more about it?
The first thing you have to realize: this is a moving target. When I first started to
write about this subject, gee, all the way back in September 1996, it was called "OLE
Messaging". This was later changed to "Active Messaging", and now is about to be called
"Collaboration Data Objects" (CDO). I think this is actually Version 1.2 of the
same library, no matter what it is called.
I doubt you'll find very much documentation under the last name, at this writing.
However, in this guise, (CDO), the Messaging API is about to become very useful
with Active Server Pages on the web.
Your best bet for finding up-to-date information on this subject is to search the MSDN OnLine
section of the Microsoft site using this string
"Active Messaging" OR "Collaboration Data Objects"
If you were fortunate enough to get your hands on the May TechNet CD, it was
an "Exchange Special Edition" which contained the first published version I saw
for the OLE Messaging API. This was later released on the Exchange DK (Technical
If you have the October 97 MSDN Library, take a look in the Platform SDK section under
"Database and Messaging". You'll probably find the CDO Library Guide and Reference
is exactly what you are looking for, at least assuming you can write to the latest
version of the API. (If not, either the Library Archive or one of the older editions
listed above will have what you need.)
The challenge, of course, is to translate this
idealized object model into working VFP code!
Check out the HowTo articles in the KnowledgeBase for help. For example, Q171425 is
"HOWTO: Writing an Active Messaging Inbox Agent in Visual Basic" -- it's not great,
but at least it's sample code. Q169031 is "HOWTO: Embedding a Document in a Message using
Active Messaging", ditto. Whether you're looking in the HowTo or Info sections of the
KB, the area you want is called (at least right now) "Messaging Application Programmers
And, yes, all the useful examples I've seen are written from a VB programmer's perspective.
Stay away from the C and C++ examples, unless you plan to add C components to your
VFP applications that you'll write yourself. The C/C++ syntax will only confuse you
with syntax that you won't actually be able to implement, in fact whole APIs that you
won't be able to get your hot little VFP hands on, mirages in the desert.
With these examples in hand, it's time to boogie. Start trying out the syntax from Fox!
Just as important, create the kinds of messages you have in mind, interactively, in
your messaging client application (Exchange Server client, Outlook, Windows Messaging).
Get a reference to these messages from VFP and examine their properties. This will
give you a good idea of the items you have to fill out programmatically, to achieve
the same results.
Think cross-platform and least-common-denominator while working on
this task . Yeah, all the "platforms" we're talking about are "Windows",
and all the messaging clients we're talking to are MAPI-compliant... so how
different can they get? The answer is: plenty different.
Although the Outlook object
model, for example, can look entrancing, and is certainly more full-featured than the
bare-bones Messaging API, resist the temptation to write to that object model unless you
are certain that all your users are willing to make Outlook their preferred
messaging client. Otherwise, considering how much work it takes to learn the syntax and twists
of Messaging, you're going to waste your time learning two idiosyncratic interfaces --
and the Outlook object model may not be very long for this world, whereas it looks like
the Messaging/CDO API is going to stick around, presumably improved. What's more,
various people have been telling me that Automating Outlook is not going to give you
The Whipped Tip Dept:
Unknown Datasessions are not your enemy
This particular heading covers information I've seen published or available
to Fox developers that either needs amplification to be useful or is Just
Plain Wrong. Warning: I will not always be good tempered in this section, or
perhaps not even on the rest of the page. Sometimes I wonder why I gave up
carrying a whip <g>.
This one really ticks me off, because it's basically an issue manufactured by the FoxPro
press looking for something to write about, IMHO.
Here's a quote from "Ask Advisor", in the May 1997 issue of FoxPro Advisor --
Tamar and Ted have introduced the idea of a modal form or a report form sharing
a datasession with an existing form:
The problem with this approach is subtle. It's best seen by opening the Data Session
window (know as the View window in VFP 3.0) while testing. The private data session
of the original form is known by the name of that form. After calling and returning
from the modal form, that data session now indicates that it's "Unknown". It appears
to work correctly and closes when it should, but the change in identify to "Unknown"
is a cause for concern.
I don't wish to pick on Tamar and Ted here -- I've just chosen this excerpt because,
together with the additional sections I'm about to quote, it represents a very complete
example of the issue, but in fact I've seen this alarmist attitude countless times in
the FoxPro press.
Why, exactly, is this "cause for concern"? The datasession operates correctly because,
in fact, nothing is wrong. The View/Datasession window, like the status bar, is not
perfect in its understanding of the environment and does not always refresh dynamically
exactly when we would like. But the Datasession window is a programmer's tool, not
a reflection of any "higher reality".
Having a form or REPORT FORM share a datasession with an existing form is a standard
technique (this is exactly why it is a choice on the Reports menu popup). It allows
a form or a report to see current/buffered/dirty data, which is sometimes the appropriate
thing for that second form or report to see. (Not always -- that's why we get the other
During the run of the report, and in absence of an explicit SET DATASESSION statement
or the creation of a new DE object, the Datasession window can't use its usual cue
(WONTOP()) to figure out a name for the current session. All this means is that
the Datasession window is confused; FoxPro isn't. The same thing sometimes happens
during a modal window brought up into a current session (it depends on when you
invoke the Datasession window).
The story thus far: we're talking about a datasession that is behaving completely normally,
except that the Datasession window has a problem figuring out what to name it.
The problem can actually get more important, and more complex, than the above example.
In fact it is possible to create datasessions that live beyond their appointed life
span. We'll get to those in a moment. But first it's vital
that you realize this: sharing datasessions
between forms (or between forms and reports) is necessary, and good, and perfectly okay.
It is actually quite a bit safer than using the explicit SET DATASESSION TO statement
that Tamar and Ted appear to be recommending as an alternative. (I'll get to that in
a moment, too.)
The DED reference
Sometimes, you can get a Diabolical Everlasting Datasession -- this one won't release
when you think it should, which is when the form that "owned" it releases.
Here's an easy way to see one in the flesh (I promise you, I'll hold your hand if you get scared!):
- Open the Datasession window. This isn't required to get a DED reference,
but otherwise you won't be able to see it.
- Create a form or form class with a private session, and open a table in the session.
Nothing fancy is required.
- Use the Datasession window or the SET DATASESSION command in the Command window to
move into the private datasession of your form. Issue a BROWSE statement, or use the
Browse button in the Datasession window.
- Close the form.
- DED at twenty paces. Your datasession is Unknown, and It's Alive.
What's happened? Your datasession object can't disappear, even though you think it should,
because you have a table open in that session, which the form didn't know enough to close when it
it disappeared. The datasession is called "Unknown" because it no longer has an "owner form"
from the Datasession window's point of view (duh!), and it still exists because it is
still needed as an "owner" of that open table.
Guess how you get rid of it? Close the BROWSE, and watch the Datasession window revert
to the Default session. The DED will be completely gone.
This simple trick is not the only way you can get DEDs. For example, use the SCATTER...
NAME syntax to get an object reference to the fields in a table in a private datasession.
Hand a reference to that object to an application property or a variable scoped outside
the form or formset that owns the session. Now, if you close the form or formset,
the datasession remains because there's an outstanding reference to the tables in it
(which, when you think about it, is all the BROWSE really was!). Similarly, a reference
to a cursor or relation object stored in a property or variable scoped outside the form
or formset can stop a datasession from disappearing.
How do you get rid of it? The same way you'd get rid of any object that refused to die:
you'd look for the outstanding object reference, and get rid of that. It's purely a matter
of being responsible about your garbage collection.
Tamar and Ted went on to say that "Contributing Editor Drew Speedie ran into memory
problems when testing this technique [sharing data sessions] (although several
other people indicate they're sharing data sessions this way in their applications without
problems". Well, sure. If you don't get rid of unknown data sessions properly, eventually
they will pile up and eat memory. But it's perfectly legitimate to keep a datasession around
longer than a form because you actually need that reference, briefly, perhaps
because you've passed information back to your app object using the SCATTER'd object
reference I postulated above.
FoxPro isn't Voodoo
Scare tactics have no place in VFP education. The product is complicated enough without
adding mystery where it doesn't belong. With this in mind, let's return to the rest of
Ask Advisor's comments on this subject:
The alternative approach is to use the SET DATASESSION command to change the data session
of the modal form. The problem here is that you can only do so safely if none of the
controls on the modal form are bound. Watch for a future article for details on making this
This is rubbish. You can certainly bind controls safely on a modal form that changes
datasession (should you really feel it necessary to use this technique, which takes
far more work than simply sharing a datasession the way God and Fox intended!). All
you have to do is bind the controls after you switch datasessions to the one
containing the data you want, and un-bind them before switching out of that
datasession again. If you pay attention to how Fox is thinking about these things,
it's perfectly clear, and there's no need for superstitious mumbling or sacrifices on the
GPF altar; the behavior is quite predictable.
There may be a design problem here (does switching datasessions violate
encapsulation? is switching datasessions ever justified -- I think it is, but not
here --?). But all the design problems in the world should only prove that Fox
writers should never have to stoop to made-up issues for their material.
plus a few development principles you can live by
Pertinent files: CLASSDOC.ZIP updated Nov.97, ~13k.
A text file from this .ZIP, CLASSDOC.TXT ~11k, is
also available for viewing before download if you wish. In this update,
I've fixed a small bug in the treeview control DblClick handling (this would affect
the VisualDocForm subclass of ClassDoc and its descendent VisualClassMemberDocForm).
If you haven't learned about this utility earlier, please check out the
information in the relevant past FoxSpoken article.
Uploading an updated version of this utility gives
me an excuse to bring it to your attention. Although the Class Browser has been much
improved in 5.0 and undoubtedly will be further improved in future versions of VFP,
there is still no "natural" way to document descending classes, rather than ancestor
classes, provided in the product. CLASSDOC fills this need. When you're spelunking
around in your class hierarchy, making an architectural design change mid-stream, you'd
be wise to consider its repercussions on all possible descendent classes in your toolkit
-- and those of your fellow team members -- before proceeding.
CLASSDOC also demonstrates another important principle, one that you can't always
live by in VFP but which you should take into consideration whenever possible: Don't
use ActiveX controls without giving yourself a "back door" in Fox code to serve when
the ActiveX control is not available, unregistered, the wrong version, et cetera.
Although I've used a Treeview control in two of the classes in the CLASSDOC hierarchy,
you're not required to use those particular subclasses to get CLASSDOC's main purpose
CLASSDOC also uses the common file dialog control, and this one is
required in the entire class tree. However, you'll notice that if an OCX error occurs,
CLASSDOC switches smoothly over to using GETFILE() instead. If you know that you are
running VFP on a minimal installation, such as a laptop, or if you've been having troubles
with the common file dialog control version on your machine, you may want to switch
the #DEFINE DOC_OMIT_TRYING_OCXS and recompile -- if this #DEFINE is .F.,
CLASSDOC won't even wait for an OCX error before using GETFILE() instead.
Lisa Slater Nicholls