Link to home
Start Free TrialLog in
Avatar of joyrider
joyrider

asked on

How to use an objects event created using createoleobject ???

How do get to use an objects events when u call it using createoleobject ?

for example with msagent i call it like this
var
test : variant;
begin
test := createoleobject('agent.control');
test.connected := true;
test.characters.load('merlin');
test.characters['merlin'].show  ;
end;

but how can i for example make it respond to an onclick event ? (i know i can import it as a activex control but like to know for future revence and when i don't want to use the control)
Avatar of Dumani
Dumani

listenning...
This might interest you:

  https://www.experts-exchange.com/questions/10237322/Word-close-event-with-OLE-and-dp3-0.html

Or this (a bit long to read but quite complete):

  http://www.undu.com/Articles/990120b.html

Hope it helps a bit!
ASKER CERTIFIED SOLUTION
Avatar of Russell Libby
Russell Libby
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of joyrider

ASKER

But can u explain me how u created that comobjevents unit ? i mean did delphi create it automaticly by some way ?

don't like copy / pasting without really knowing what happens & how it was made & stuff

To answer your questions:

1.) It is not auto generated code. I wrote it; borrowing from MSDN, Delphi sources, personal experience, previous projects, etc. Pretty much the same way everyone else writes code :-)

For example: The param array transfer routine used in Invoke() is from oleserver.pas. (Easiest, most generic way to call the OnEvent function with an open array of variant parameters). MSDN examples were used for walking ITypeInfo, etc. Personal experience in regards to using IProvideClassInfo, vs walking connection points. Previous project where I wrote a type library browser. etc...

2.) As to how it works. Well, the concept is actually pretty simple:

- Given a dispatch interface, determine if there is a connection point container. If not, then no events

- Using the interface, check to see if IProvideClassInfo is exposed. (Easiest way of ascertaining the desired IConnectionPoint). If not, enumerate the connection points in the container.

- Once we determine the correct IConnectionPoint interface (There is ONLY ONE interface that can be marked as both SOURCE and DEFAULT.) we save the interface (FCP), and load the Name-ID pairs from the ITypeInfo. We also save the guid for later comparison in QI.

- At this point we are not connected. To tell the object we wish to receive events, we must call Advise() on the connection point. This is done by using the object's Sinked property. (Which then calls Advise/Unadvise based on current state).

- During Advise() we pass our interface (IUnknown). The object will then QI our interface for either IDispatch or the actual event IID. This is where the guid comes into play. Without it, we could only resolve IUnknown and IDispatch. This would work for some objects, but not all. So we use the guid to check the IID, and if the same, act like the IID was IDispatch. (This is also the reason why the event interface must be IDispatch based). At this point we are "connected" and ready to receive events.

- When an event gets fired, our object's Invoke() get's called. We lookup the event name using the dispatch id and reverse the params into an array of variant. Then all this info:

sender - variant (IDispatch of source object)
event  - event name string
id     - dispatch id
params - array of variant

is passed to the assigned OnEvent method.

-----

So in essence, what you have is a generic IDispatch based object, which, through the use of late bound methods, can emulate an event sink for pretty much any automation object. (As long as the object exposes type information).

-----

If some of the code looks foreign, it's because the Delphi wrappers hide this level of COM from you.

Hope this clears things up (some?). If not, then let me know.

Russell