In a recent article, we talked about how to create ActiveX, this time we respond to events. This time, we will create a class: Cgeneraleventsink, which can respond to any dispatch event (the interface inheritance and IDispatch of the event).
First, let's review the concept of ConnectionPoint. Any object that supports the event (for example, an ActiveX control) supports the IConnectionPointContainer interface, which, as its name implies, is a iconnectionpoint container that contains all the events supported by this object. IConnectionPoint represents a set of events, calls IConnectionPoint::Advise, and passes in the object pointer to the event we want to receive. The IID returned by IConnectionPoint::GetConnectionInterface is the interface that the object that receives the event must implement or advise will fail. Take a look at Axadviseall's code:
Enumerates each iconnectionpoint in the IConnectionPointContainer,
For each IConnectionPoint, create a new Cgeneraleventsink object that supports the IID interface and advise.
Punk is a pointer to a control
HRESULT Axadviseall (IUnknown * pUnk)
{
HRESULT hr;
IConnectionPointContainer * Pcontainer = NULL;
IConnectionPoint * PCONNECTIONPOINT=NULL;
ienumconnectionpoints * Penum = NULL;
hr = Punk->queryinterface (IID_IConnectionPointContainer, (void**) &pcontainer);
if (FAILED (HR)) goto Error1;
hr = Pcontainer->enumconnectionpoints (&penum);
if (FAILED (HR)) goto Error1;
ULONG ufetched;
while (S_OK = = (Penum->next (1,&pconnectionpoint,&ufetched)) && ufetched>=1)
{
DWORD Dwcookie;
IID IID;
hr = Pconnectionpoint->getconnectioninterface (&IID);
if (FAILED (hr)) IID = Iid_null;
The afferent punk here is to obtain the ITypeInfo of the IID through the punk, and then to determine whether the IID is a dispatch interface
IUnknown * Psink = new Cgeneraleventsink (iid,punk);
hr = Pconnectionpoint->advise (Psink,&dwcookie);
Psink->release ();
Pconnectionpoint->release ();
Pconnectionpoint = NULL;
Psink = NULL;
}
hr = S_OK;
Error1:
if (penum) penum->release ();
if (Pcontainer) pcontainer->release ();
if (pconnectionpoint) pconnectionpoint->release ();
return HR;
}
Then, for the Dispath event. This event is a Dispath event if the IConnectionPoint::GetConnectionInterface returned by the IID represents an interface that inherits from IDispatch. When an event occurs, the object that produces the event does not call Pobj->onevent () directly, and the Pobj->invoke (...) is invoked. For example, the event object for the Flash Control: (generated by the #import instruction of VC)
struct __declspec(uuid("d27cdb6d-ae6d-11cf-96b8- 444553540000"))
_IShockwaveFlashEvents : IDispatch
{
//
// Wrapper methods for error-handling
//
// Methods:
HRESULT OnReadyStateChange (
long newState );
HRESULT OnProgress (
long percentDone );
HRESULT FSCommand (
_bstr_t command,
_bstr_t args );
HRESULT FlashCall (
_bstr_t request );
};