This topic is for further elaboration on the Visual FoxExpress application object. Here is what the VFE help says about the application object:
- The application object is the starting point of a
Visual FoxExpress application. It creates the environment
the application will run in, provides global services and
provides access to other objects that are used throughout
the application. The superclass for the application
object is cApplication in the cApp.VCX class library.
When you create a new Visual FoxExpress application, the
application object for your application is created as a
subclass of the iApplication class in iApp.VCX from the
If you open up a VFE project in the plain vanilla VFP project manager, you will see that the application object class (in aapp.vcx) is SET MAIN, which you might expect given the statement in the first line of help. It's a worthwhile exercise to read through the init() of the application object (capplication in capp.vcx) to see what happens at instantiation. If you want something to happen during application startup, a good place to put it is in init_post() or beforereadevents(). Note that if you put code in iapplication.init or aapplication.init in the following manner, the code will not run until the application is shutting down.
*-- iapplication.init (don't do this!)
*--custom code here
The reason is that READ EVENTS is called in the application.do() method. The do() method is called near the end of the application.init(). So this explains why any custom code inserted as above will not run until shutdown (ie, after CLEAR EVENTS). Note that in the init() that the init_post() hook is called right before do() is called. On the subject of READ EVENTS, be sure to check out the help topic "Accessing a Visual FoxExpress Application through COM" for a situation where it is not executed at all.
The application.do() method itself is a good method to go through. Note that it contains a few last minute items, including the beforereadevents() hook. Based on what was said in this and the last paragraph, you know that the beforereadevents() is called after the init_post().
If you want some code to run prior to login, you need to put it long before init_post() or beforereadevents(). Perhaps aapplication.init_pre() would be a good choice (it executes prior to anything else) or maybe put your custom code in aapplication.login() followed by a DODEFAULT(tcuserid,tcpassword). Actually, F1 has already thought of this and provided a
login_pre() hook, so this would be preferred place to put your custom code in this instance. Insert your custom code in the i-layer (iapplication in iapp.vcx) if it is for all your applications or insert it in the a-layer (aapplication in aapp.vcx) if it is application specific.
I like to use methods of the sfutility class that comes with SDT. I created a custom property in iapplication called outility, and I populate it at runtime by putting this code in the iapplication.init_post().
this.outility = NEWOBJECT("sdtutility", "SDT")
And I put the following in the iapplication.destroy() method to clean up.
this.outility = .NULL.
The above is not necessary. The SDTUtility object can be accessed this way if you have a ref to the application object... -- Del Lee
Here is the exported code from the class browser on the Sample Application object. This shows some (not all) framework properties of the application object.
cappname = "VisualFoxExpress 6.0 Sample Application"
ccompany = "F1 Technologies"
cversion = ("1.0")
cdatapath = "DATA\"
cprogspath = "PROGS\"
clibspath = "LIBS\"
coutputpath = "OUTPUT\"
cmiscpath = "MISC\"
cmetapath = "METADATA\"
cadditionalpath = ""
cframeworkpath = ..\VFEFRAME\
cilibspath = ..\ILIBS\
cproject = "SAMPLE.PJX"
luselocaldata = .T.
caboutimage = "MISC\F1.ICO"
cformicon = "MISC\F1.ICO"
chomepageurl = "www.f1tech.com"
csplashimage = "C:\VFE6\SAMPLE\MISC\F1LOGOPURPLE.BMP"
cwallpaperbmp = "C:\VFE6\SAMPLE\MISC\F1LOGOPURPLE.BMP"
lfillwallpaper = .F.
cdefaultformtoolbar = "SAMPLETOOLBAR"
lenableerrorhandling = .T.
chelpfile = "help\help.chm"
cstartform = "SwitchBoardForm"
lusesecurity = .T.
csplashclass = "SampleSplashForm"
name = "sampleapplicationobject"
Some of these are set by the wizard when you create a new application. Note that chelpfile is the property to set for the application's help file. To set pathing for your application, you would put this in the cadditionalpath property. According to a
conference message, you shouldn't put anything in the cpath property, as this is populated at runtime based on what's in the other pathing properties (I assume cdatapath and cadditionalpath).
Note the above is not a complete listing of all the properties of the application object. For example, the osecurity property is populated at runtime if you use security. A common use of the security object would be to find out the currently logged in user. This is contained in the cuserid property of the Security object. So to access the current user, you simply get a reference to the application object and drill down to the cuserid thusly:
lcuserid = oapplication.osecurity.cuserid
Maybe the hard part of the above is finding a reference to the application object. Many framework objects have a reference to the application object (oapplication property) which is populated at runtime in their respective oapplication.access() methods.
Otherwise you can get a reference to it by calling the findapplication function (the code for this is located in utility.prg off VFEFRAME\PROGS).
One method of the application worth special mentioning here is the addbizobj() method. With it, you can instantiate a biz obj via COM (for instance, in an ASP or a Excel macro) to make it available for use. There is a ldisplayinterface property of the application object which should be set to .F. when you do this. I haven't done this yet, but I think I understand the idea. Here is some VBA/VBScript code I saw on one of Mike's posts...
Set oapp = CREATEOBJECT("Sample.SampleApplicationObject")
Set oCustomer = AddBizObj("CustomerBizObj")
' Yada, Yada, Yada
The help topic "Accessing a Visual FoxExpress Application through COM" is very good and contains very helpful sample code. Be sure to check it out. If you've ever done any work with VBA in Office97, you've seen how Excel has an application object and it has a Workbooks collection. Similarly, you've seen how Word has an application object and a Documents collection. A VFE application has an obizobjs Collection, which is analagous to these Office counterparts. In Excel, you do do the following...
Set loExcel = CREATEOBJECT("Excel.Application")
In a VFE application (compiled as a public COM server) you could do the following, which is similar to the above. The differences are that in VFE you need to supply the name of the bizobj to add plus the bizobj is not necessarily new and empty like the Workbook above would be.
Set loApp = CREATEOBJECT("Sample.SampleApplicationObject")
Set loCustomer = loApp.oBizObjs.Add("CustomerBizObj")
A lot more could be added to this. Please do so.
Contributors Del Lee
Category Visual FoxExpress