I received a question from a reader:
I decided to extend my VPF9SP1 application to support OLE Automation like MS Office. I'd like to enable user (through code, i.e. VBA macro in Excel) to instantiate my app, create a new form, fill-in some data and display the form on screen and let the user decide what to do next.
Unfortunately, after releasing reference variable in client code, a form disappeared and my application ended.
I understand, that I should increment RefCount to keep my app running, but how can I do that in VFP code?
Is there any way in VFP to access IDispatch interface of COM server itself?
Try the code below. It creates a runtime VFP COM server (like “Excel.Application”, but a little simpler) that displays a form.
It then offers 2 MessageBoxes in a row. Try answering No to each the first time running the code. That shows the default behavior. When the server is released from the client, the refcount is decremented to none, the object is released and the form disappears.
Answering Yes to either MessageBox demonstrates how the refcount can be modified in two ways: one from the client and one from the server.
Both use SYS(3097) - Add Reference to Object. The one from the client is quite simple. From the server itself, we pass in the same Server reference variable oSrv and bump the refcount on that.
Managing Object Lifetimes Through Reference Counting
To make the runtime VFP screen invisible at runtime, see Special Terms for Configuration Files
More about VFP COM servers: Blogs get 300 hits per hour: Visual FoxPro can count.
TEXT TO myprog noshow
DEFINE CLASS c1 as session olepublic
proc MyDoCmd(cCmd as string,p2 as Variant,p3 as Variant,p4 as Variant,p5 as Variant) helpstring 'Execute a command'
proc MyEval(cExpr as string,p2 as Variant,p3 as Variant,p4 as Variant,p5 as Variant) helpstring 'Evaluate an expression'
BUILD PROJECT testxx FROM testxx
BUILD EXE testxx FROM testxx
oSrv.MyDoCmd("_screen.Height = 400")
oSrv.MyDoCmd("_screen.Width = 400")
oSrv.MyDoCmd("oForm = CREATEOBJECT('form')")
IF MESSAGEBOX("AddRef the server from the client?",4) = 6 && IDYES from foxpro.h
?"The client is making an additional AddRef on the server"
?SYS(3097,oSrv) && AddRef the server ref count
IF MESSAGEBOX("AddRef the server?",4) = 6 && IDYES from foxpro.h
?"The server is making an additional AddRef on itself"
oSrv.MyDoCmd("PUBLIC oMe") && create a var to store a self ref
oSrv.MyDoCmd("oMe = p2",oSrv) && set that var to self
?oSrv.MyEval("SYS(3097,oMe)") && AddRef the server ref count
oSrv=0 && release the server