I got 2 events in my ActiveX/ATL library
dispinterface _IMyEvents
{
properties:
methods:
[id(1), helpstring("method OnReceiveData")] HRESULT OnReceiveData([in] long BytesReceived, [in, out] VARIANT_BOOL * Proceed);
[id(2), helpstring("method OnReceiveDataEx")] HRESULT OnReceiveDataEx([in] long BytesReceived, [in] BSTR DataChunk, [in, out] VARIANT_BOOL * Proceed);
};
They are called in the standard ATL's way:
template <class T>
class CProxy_IMyEvents : public IConnectionPointImpl<T, &DIID__IMyEvents, CComDynamicUnkArray>
{
//Warning this class may be recreated by the wizard.
public:
HRESULT Fire_OnReceiveData(LONG B开发者_C百科ytesReceived, VARIANT_BOOL * Proceed)
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[2];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
pvars[1] = BytesReceived;
pvars[0].vt = VT_BYREF|VT_BOOL;
pvars[0].pboolVal = Proceed;
DISPPARAMS disp = { pvars, NULL, 2, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
delete[] pvars;
return varResult.scode;
}
I need to know if application has subscribed particularly to OnReceiveDataEx event (which has extra parameter DataChunk which needs to be calculated). If the app only listens to OnReceiveData, I don't need to build DataChunk string as nobody will get it, and can optimize the performance.
ATL, however, only allows me to know if anybody has subscribed to any events at all, but not to which ones particularly (so I can only determine the number of objects (sinks) listening to my events, but not the number and names of particular events being listened to). Is there any way to overcome this?
In .net, for instance, you can check subscribers for an event independently of other events.
If you need to make this distinction, ATL or no, you will need two interfaces. One for OnReceiveData and one for OnReceiveDataEx. A given event sink has to implement all the methods of an event interface, even if it only cares about one.
精彩评论