Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.
CREATEOBJECTEX()
Distributed computing arrives at last! This function lets you create objects external to the machine you’re working on.
oHandle = CreateObjectEx( cCLSID | cProgID
[ , cComputer ] [, cInterfaceID ] )
Parameter |
Value |
Meaning |
cCLSID |
Character |
The class identifier of the object you're trying to create, typically in the form returned by the CLSID property ({HhHhHhHh-HhHh-HhHh-HhHh-HhHhHhHhHhHh}, where each "Hh" is a hexadecimal representation of one byte. This format is also known as a GUID). |
cProgID |
Character |
The programmatic identifier for the class. This is the "friendly name" of the COM server, as stored in the Registry. For example, "Word.Application". |
cComputer |
Character |
The name of the computer on which this object is created. The name can be in Universal Naming Convention (UNC) format, as in "\\ServerName," or in another format that can be resolved to an individual machine name, such as a TCP/IP address or domain name. Services to resolve the addresses must be available to the machine. |
Omitted |
Create the object on the local machine. |
|
cInterfaceID |
Character |
The GUID of the interface identifier of the object you're creating. Creates an early bound instance of the object. |
Omitted or empty string |
Attempts to instantiate the default interface. Creates an early bound instance of the object, if possible. |
|
Omitted |
Creates a late bound instance of the object. |
|
oHandle |
Object |
Returns a handle to the object if created successfully. In our experience, failure to create the object typically brings up the error handler. |
If you’ve been following the adventures of Microsoft and the idea of running portions of your application on other machines, you know they introduced the idea of Remote Automation in the VFP 3 timeframe. Remote Automation required that a separate Automation Manager run on the server machine to support communications between the two machines. It was awkward to set up, and it wasn’t terribly stable. Not long after that came the similar idea of Distributed COM, where the COM model itself works with remote components by presenting a proxy object on the local machine that imitates the interface of the remote object, and DCOM itself handles the communication between machines. (Microsoft refers to this as “remoting an object.” We’ve learned that in English every noun verbs, but this is the first time we’ve seen an adjective verb.) CREATEOBJECTEX()
is another step along the way.
With CREATEOBJECTEX()
, there are two ways to work with a remote object. First, if the class ID of the object itself is known, it can be called directly from any client machine, without the need to pre-install any software on those clients. This is ideal for those situations where you don’t have control over the configuration of the client machines such as over the Web or a WAN. This lets you invoke a remote object without messing with the client’s Registry. The second calling format, using the ProgID (the English language version of the COM object’s name, such as “MyServer.MyObject”) has the advantage of much more readable code, but the disadvantage of having to be pre-registered on each client machine.
So what’s the advantage of this over the earlier versions of DCOM? The real payoff comes in the second parameter, where the name of the computer on which to create the object is specified. Since this is a string parameter, it can be programmatically assigned at runtime. This gives you the option of creating load-balancing schemes or strategies of pooling computers to perform intensive tasks, and then finding the most available machine at runtime.
VFP 7 adds early binding and interface support to this command. With early binding, VFP resolves the references to the object at compile time. Without early binding, each call to the object must be resolved, adding additional overhead to each call. Early binding can bring substantial performance gains, especially if there are many calls that each requires little processing. Pass an empty string to get the default interface, or pass the GUID for another interface. This last point is a boon to those wanting to use objects that don’t have a default interface, for now you can specify which interface you want. Where do you find these GUIDs? A bit of detective work is necessary, as they’re stored by GUID in the Registry, under HKEY_CLASSES_ROOT\Interface. For COM objects you create in VFP, look for a <YourComObjName>.VBR file, which has the Registry keys and GUIDs in it.
oProj = _vfp.ActiveProject && Get a handle to the project
cCLSID = oProj.Servers[1].CLSID && Get 1st server's class ID
oWow = CreateObjectEx(cCLSID,"","") && Create the object