Application scope gotcha

Visual FoxPro gives us the flexibility to embed files into the APP/EXE file. Other languages have the ability, but require the developer to use resource functions to access such files. In Visual FoxPro, on the other hand, accessing embedded files happens completely transparently. When you open a file that has the same file name as an embedded one, Visual FoxPro uses the internal one.
For instance, you can include a DBF file into an application. This application can open the DBF file without any problems. However, a second application might try to open the same table again using code like:


USE DBF("alias") AGAIN IN 0

This code line could suddenly fail, because the second application doesn't have access to the embedded DBF file. Why am I talking about this? Because Visual FoxPro 9 introduces application scope issues to applications that hadn't had a problem before. I'm talking about the new report engine that relies on three external APP files to perform its duty.

In versions prior to 9 we often used embedded FOXUSER files to control the preview toolbar, for example, to remove the print button from the toolbar. The report printing routine first changed the resource file, printed the report and restored the resource file. If you leave this code unchanged and just replace the REPORT FORM . PREVIEW line, you might receive an error in the OpenResourceFile method. The offending code actually looks pretty innocent:


select 0
use (set("RESOURCE",1)) again shared
set order to 1

When VFP loads a FOXUSER file it always creates a temporary index. The code works just fine. if it would be executed in the same application scope as your application. It's part of REPORTPREVIEW.APP, though. What in fact happens is this:

Your application loads the embedded resource and VFP creates a temporary index. The report preview attempts to save and restore the preview window position. The USE statement should open the current resource file. Since the preview code runs in a different application scope than your application, Visual FoxPro searches for an external file with the same name. Two things could happen now:

If there's no external file of this name, Visual FoxPro throws an error message that the file cannot be found. If the file exists externally, Visual FoxPro opens it. As far as VFP is concerned, this file is now a different one than the one that VFP opened as a resource file.

Visual FoxPro opens tables always only once. When you open a table in multiple work areas or data sessions, all these instances refer to actual table entry. That's one reason why you need USE.AGAIN when you open a table in more than one work area. The table entry keeps track of opened index files. That's the reason that when you open a table again, it kind of inherits all open index files.

When you open the resource file again using code like the one above, Visual FoxPro reuses the existing table entry with the index that VFP created internally. In our scenario of an embedded resource file, however, the USE statement creates a new table entry which doesn't have an index associated with it. Consequently, you get an error on the SET ORDER TO line. You can avoid this particular problem by turning resource OFF while you access the new print preview form.

However, it's not just about a bug in the preview application. It's about an issue that might become more and more important as we incorporate features in our application that are spread out across multiple APP files. Application scope issues can come in many flavors including in restoring settings like SET CLASSLIB, SET PROCEDURE, and the like, that all might refer to embedded files.