The template class IDispEventImpl can be used to provide support for connection points in your ATL COM object. A connection point allows your COM object to handle events fired from external COM objects. These connection points are mapped with an event sink map, provided by your COM object.
To properly implement a connection point or points for your COM object, the following steps must be completed:
In this procedure, you will be modifying only the header file (.h) of your COM class.
For each external object whose events you wish to handle, you must import the type library. This step defines the events that can be handled and provides information that is used when declaring the event sink map. The #import directive can be used to accomplish this. Add the necessary #import directive lines for each dispatch interface you will support to the header file (.h) of your COM class.
The following example imports the type library of an external COM server (MyServer
):
#import "D:\MyServer.dll" raw_interfaces_only, no_namespace, named_guids
Note You must have a separate #import statement for each external dispatch interface you will support.
Now that you have imported the type libraries of each dispatch interface, you need to declare separate IDispEventImpl interfaces for each external dispatch interface. Modify the declaration of your COM class by adding an IDispEventImpl interface declaration for each external object. For more information on the parameters, see IDispEventImpl.
The following lines of code declare two connection points, for the custom IExtEvents1
and IExtEvents2
interfaces, for the COM object implemented by class CMyObj
:
public IDispEventImpl<0, CMyObj, &DIID__IExtEvents1,
&LIBID_EXTEVENTS1Lib, 1, 0>,
public IDispEventImpl<1, CMyObj, &DIID__IExtEvents2,
&LIBID_EXTEVENTS2Lib, 1, 0>
In order for the event notifications to be handled by the proper function, your COM object must route each event to its correct handler. This is achieved by declaring an event sink map.
ATL provides several macros, BEGIN_SINK_MAP, END_SINK_MAP, and SINK_ENTRY, that make this mapping easier. The standard format is as follows:
BEGIN_SINK_MAP(comClass)
SINK_ENTRY(id, dispid, func)
. . . //additional external event entries
END_SINK_MAP()
The following example declares an event sink map with two event handlers:
BEGIN_SINK_MAP(CMyObj)
SINK_ENTRY(0, Events1, OnClick1)
SINK_ENTRY(0, Events2, OnClick2)
END_SINK_MAP()
The implementation is nearly complete. The last step concerns the advising and unadvising of the external interfaces.
The final step is to implement a method that will advise (or unadvise) all connection points at the proper times. This advising must be done before communication between the external clients and your object can take place. Before your object becomes visible, each external dispatch interface supported by your object is queried for outgoing interfaces. A connection is established and a reference to the outgoing interface is used to handle events from the control. This procedure is referred to as "advising."
After your object is finished with the external interfaces, the outgoing interfaces should be notified that they are no longer used by your COM object. This process is referred to as "unadvising."
Because of the unique nature of COM objects, this procedure varies, in detail and execution, between implementations. These details are beyond the scope of this topic and are not addressed.