Académique Documents
Professionnel Documents
Culture Documents
Find
out how connection points work and digest a generous helping of code.
Component Object Model (COM) connection points are interfaces that handle event callback
functions. If you work with the Win32 API, you are probably familiar with callback functions. They
show up frequently as parameters to functions, such as EnumWindows().
COM connection points, although more complicated than standard callback functions, provide
greater flexibility because all parameters and calls are executed using the COM subsystem. The
COM subsystem allows calls to execute correctly across process boundaries, which is not
possible with simple callback functions.
For example, consider the C++ timer class in Listing A. The class includes the functions
SetExpiredProc(), SetTime(), Start(), and Stop(), as well as the constructor CExampleTimer() and
a protected member function RunTimer(). The timer also fires an event when it expires. A COM
interface describing this class would comprise only the public functions related to being a timer,
such as SetTime(), Start(), and Stop(). You could construct a COM connection point interface
containing a single method named TimerExpired().
So the main difference between normal programming with COM in a standard client-server
system and using connection points is that in the standard client-server case, the server exposes
a list of methods that the client employs, and in the connection point case, the client exposes a
set of methods that the server uses.
*· FindConnectionPoint() allows a sink to ask the source if it fires off a specific set of
events.
*· EnumConnectionPoints() allows a sink to ask the source for all of its event types.
To keep things simple, assume that the event sink knows which set of events it wants and that it
will ask for just that set of events. In this case, the event sink will take advantage of only the
IConnectionPointContainer::FindConnectionPoint() method, passing in a unique identifier for the
event type COM interface. If everything succeeds, and the source supports the requested event
type, the sink receives a pointer to an IConnectionPoint interface.
For this article, only the Advise() method and the Unadvise() methods are necessary. You
complete the attachment of the sink to the connection point source by employing the
IConnectionPoint::Advise() method of the interface returned from
IConnectionPointContainer::FindConnectionPoint(). The call to IConnectionPoint::Advise() needs
two parameters: the IUnknown interface pointer to the sink and a pointer to a DWORD datatype
(frequently used to store 4-byte values) for the source to initialize.
The last thing necessary for an event source to fire events to any listening sinks is a helper
method called Fire_EventX(), which is the name of a method in the COM event interface. This
method abstracts the EventX() calls on the sink objects that were stored during the execution of
the IConnectionPoint::Advise() method. After abstracting the objects, the event source fires off
events to all event sinks that care by calling Fire_EventX(), as shown in Listing C.
Conclusion
COM connection points offer a great deal of flexibility because the subsystem makes all function
calls so they will execute across processes. Once you get the hang of interfaces and event types,
you should be well on your way to taking advantage of this approach.