Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations sizbut on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Unable to use eventhandler() in VFP9 SP2 1

Status
Not open for further replies.

markftwain

Technical User
Jul 12, 2006
108
In trying to replicate previous examples, my use of eventhandler() always returns .f. I am using VFP 9 SP2 on Windows XP with service pack 3.

To be explicit, the below code was compiled as multi-threaded dlls, each in their own project. Windows Component Services was then manually used to add the dlls to the com+ interfaces. Activation of 'wife' is seen with the ball turning.

I receive no errors in the compilation or running. But, eventhandler() ALWAYS FAILS to complete, returning .f. Is there another way to do this?

Thank you.

* testing eventhandler
public owife,x
owife = createobject('wife.Garbage')
x=NEWOBJECT("myclass")

? eventhandler(m.owife,m.x)
return

DEFINE CLASS myclass AS session OLEPUBLIC
IMPLEMENTS Igarbage IN "wife.Garbage"
PROCEDURE Igarbage_TakeOutGarbage(what AS STRING) AS VOID
ENDPROC

ENDDEFINE

* wife code compiled into wife.dll and added to com+
define class Garbage as session olepublic
procedure TakeOutGarbage (what as string) as void
endproc
enddefine
 
What happens when you just do all this in VFP without involving COM+? Does it work there?

Tamar
 
There is nothing in the code that takes advantage of COM+, so I don't know why you're hosting the DLL there. I agree with Tamar, try running it outside of COM+.

Craig Berntson
MCSD, Visual FoxPro MVP,
 
Eventhandler() fails at runtime with: "Function argument value, type, or count is invalid".

public owife,ohusband
m.owife = newobject('wife')
m.ohusband = newobject('husband')

? eventhandler(m.owife,m.ohusband)
return

define class Wife as session
procedure TakeOutGarbage (what as string) as void
endproc
enddefine

define class Husband as session
procedure TakeOutGarbage(what as string) as VOID
messagebox( what )
endproc
enddefine

I am open to ideas...I am using a vfp form that runs in a private datasession with its own instance of vfp in the background. It starts with windows as a service to monitor the status of certain private tables excluded from the desktop forms. The com+ system of event notification seemed like a good way to inform whatever visible forms were currently runing on the desktop (in their own instance of vfp ) of a change in status. The COM+ Event System also failed with the vfp code. Hence, eventhandler(). I have been using winsock for this, but was looking for a better way. Thanks.
 
In the new example, you're missing the IMPLEMENTS command. Also, EVENTHANDLER() is only for linking VFP code to event behavior of COM code. If you want to link VFP code to an event of another VFP object, use BindEvent().

Tamar
 
Thank you.

Bindevent() works well within the same instance of vfp. (Probably another thread--how can one instance of vfp use an object created in another vfp instance? )

The mentioned articles are excellent. This is the situation. A stock program synchronizes files between the desktop machine and a mobile unit. The first instance of vfp is a windows service that manages input/output with these files. These files are forced to be isolated in their own private datasession. The desktop application (not the vfp service), may or may not be running at all, and will not have direct contact to these files.

I believe these are 'transient','asynchronous', 'Loosely Coupled Events'. My intent is for the desktop forms to manage the published events, (e.g., "here is a record"), triggered by the seperate vfp service. (i.e., the vfp service will publish the event on the Com Event System which then triggers the forms in the second vfp instantiation).

For vfp to manage the event, do not the desktop forms need to use eventhandler()?
 
Hi mark,

if you talk about a COM service and a desktop app consuming it's events it could work. What you'll need is a VFP class implementing the/an interface of your COM class.

So in vfps objectbrowser, choose open dialog, tab "COM Libraries" Browse, choose the COM dll or Exe you created with VFP (exeordllname.wife and exeordllname.husband) expand the tree, expand the interfaces node, create a new empty prg. Drag the interface node within the interfaces to the empty prg editor window.

Now you have your implementation of the interface. Rename the class from myclass to eg wifehandler, also the olepublic definition of this class is not necessary for foxpro, eventhandler() will need a vfp object to handle the events of a COM object, so this eventhandler class is sufficiently working, if not olepublic.


To make use of this you create

Code:
oWife = CreateObject("exeordllname.wife")

(not only Wife, then you'd not create a COM object but a native VFP object, which you can't use with eventhandler)

Code:
oWifeHandler = Createobject("wifehandler")

And then you'd bind these both with Eventhandler:

Code:
EventHandler(oWife,oWifehandler,.t.)

Pay attention to the intellisense about the Eventhandler function. You need to input a COM object (event source) and a VFP object (event handler/sink).

This is surely a valid way to bind to events of a seperate process.

Bye, Olaf.
 
Thanks. I thought/hoped so too....no luck. eventhandler() returns .f. (Am I doing something wrong?)

To replicate, this is the exact procedure I followed:
1. Created an empty vfp project with one program: c:\wife.prg
2. wife.prg is:

define class Garbage as session olepublic
procedure TakeOutGarbage ( what as string) as void
endproc
enddefine

3. 'Build project'-->'Multi-threaded COM server (dll) with Regenerate Component ID's checked. Save as type 'dll' ---> c:\com\wife.dll
4. Went to windows xp -->Component Services-->Computers-->My Computer-->COM+ Applications
Right click on Com+ Applications-->New Application-->Create An Empty Application
Checked on 'Server Application' , Name: 'HouseHold'-->Interactive User-the current logged on user-->Finish

5. Then, COM+ Applications--> HouseHold-->Right click on Components-->New Component-->Install New Event
select: c:\com\wife.dll

This resulted in component called: "Wife.Garbage"

6. Returned to vfp. Created empty program file. Opened Object Browser. Right clicked on 'Classes and Members' Pane. Open-->Com Libraries
7. Scrolled down list to find: wife Type Library.
8. Opened wife Type Library-->Interfaces (1) --> Igarbage
Draged Igarbage to empty program file.

9. Changed 'Myclass' to 'wifehandler'. Removed OLEPUBLIC.
10. the resulting program (below) was compiled and run with lUnbind = .t. and .f. :

owife = createobject("wife.garbage")
owifehandler = NEWOBJECT("wifehandler")
? eventhandler(oWife,owifehandler,.f.)

DEFINE CLASS wifehandler AS session
IMPLEMENTS Igarbage IN "wife.Garbage"
PROCEDURE Igarbage_TakeOutGarbage(what AS STRING) AS VOID
* add user code here
ENDPROC
ENDDEFINE

The good news is the component services displays 'Wife.Garbage' turning.
The bad news is eventhandler() fails with .f.

Thank you
 
Okay, it seems you need to do a little more in case of VFP COM or even COM+ servers. Take a look at Samples/Com+/Events, in the Foxbook_client.pjx you'll find a tce_events form. In it you can activate events and subscribe to them. Helperclasses "EventSystem.EventSystem" and "EventSystem.EventPublisher" are used.

One more easy way is to use a simple COM server, change it to Multiple Use and then create an instance and bind to it in a second process by Getobject(). Because of multiple use you'll get the running instance and have access to the exact same object. This does not make an event happaing in the COM object trigger some code in the "subscriber" process, but at least you're already directly connected from one side. You might give that COM server a property holding a reference to a subscriber object and in the methods of the COM server call a corresponding method in this subscriber object and have something very equal.

Bye, Olaf.
 
Good examples. Tried...getobject() returns: OLE error code 0x800401e3: Operation unavailable
 
Well, old examples. But you compiled the three projects?

Regarding getobject():
a) look under project info (CTRL+J), in the servers tab, if Instanciating is "Multiple use", only then one instance can be used multiple times. Default is Single use, which means even getobject() will create a new object.

b) getobject() only works after an initial normal createobject("the.class") or newobject("the.class"), there has got to be an instance created before you can get it.

c) the syntax is getobject(,"the.class")

Bye, Olaf.
 
Yes. A 'Star' ! and a very sincere thank you.

To conclude the initial thread:
It is my belief that Eventhandler() fails when vfp classes are made into com objects. (sad)

After some playing, it seems that on my system, getobject(,"the.class") always fails. But, getobject("","the.class") seems to work within the same vfp session.

For our community, I will post sharing between sessions as a seperate thread.. Thanks again.

 
I wonder why getobject("","the.class"), this is odd. But thanks. And I wonder what you mean by "when vfp classes are made into com objects". Because having a COM object and a native vfp interface implementation are the main ingredients. What's true is, that vfp COM classes don't seem to offer the right interface that works by itself, whwn you implement it, and you need helper classes. So perhaps you better implement the COM class part of it all with something else. I don't know yet what's the main factor, I know the interface implemntation works for example for the Microsft Agent (
And inspecting agentctl.dll with the object browser, it's _AgentEvents interface also is based on IDispatch, I see no major difference to th COM classes vfp creates.

It's a bit mysterious why dragging the interface to a prg the object browser creates a "myclass" as olepublic, as for the internal use with eventhandler you need this as a vfp native object, but that may be to make use of this outside vfp via OLE too.

In short, what you posted inintally should work, but vfp COM classes seem insufficient in some way to use them with eventhandler.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top