0
我有2个事件在我的ActiveX/ATL库如何知道是否有人订阅了我要开火的特定活动?
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);
};
他们被称为标准ATL的方式:
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 BytesReceived, 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;
}
我需要知道,如果应用程序已经订阅特别OnReceiveDataEx事件(其中有需要计算的额外参数DataChunk)。如果应用程序仅侦听OnReceiveData,则不需要构建DataChunk字符串,因为没有人会获取它,并且可以优化性能。
然而,ATL只允许我知道是否有人订阅了任何事件,但不是特别针对哪些事件(所以我只能确定收听我的事件的对象(接收器)的数量,而不是被监听的特定事件的号码和名称)。有什么办法可以解决这个问题吗?
例如,在.net中,您可以检查订户是否独立于其他事件。
不适用于您不需要的调度接口。在ATL中,您只需将您感兴趣的DISPID映射到处理函数。没有ATL或其他框架,你可以打开DISPID。其他客户端(VB,.NET)将DISPID连接到代理。对于事件有多个调度接口几乎没有意义。 – 2011-05-18 20:03:59
我必须承认我不是ATL和事件接收器方面的大专家,也不能说我完全理解了你的评论。这是否意味着可以得到我需要或不需要的东西?谢谢你的帮助。 – Alex 2011-05-18 20:57:35
其实我误解了Logans的答案。在你的问题的背景下,你会需要两个界面,正如他指出的那样。 – 2011-05-18 21:08:01