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.con trol');
test.connected := true;
test.characters.load('merl in');
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)
for example with msagent i call it like this
var
test : variant;
begin
test := createoleobject('agent.con
test.connected := true;
test.characters.load('merl
test.characters['merlin'].
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)
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!
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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
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