首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

VC6 COM控件增多事件支持

2013-02-19 
VC6 COM控件增加事件支持template class Tclass CProxy_IMyCtrlEvents : public IConnectionPointImplT

VC6 COM控件增加事件支持

template <class T>
class CProxy_IMyCtrlEvents : public IConnectionPointImpl<T, &DIID__IMyCtrlEvents, CComDynamicUnkArray>
{
??? //Warning this class may be recreated by the wizard.
public:
??? HRESULT __stdcall Fire_OnOK()
??? {
??? ??? CComVariant varResult;
??? ??? T* pT = static_cast<T*>(this);
??? ??? int nConnectionIndex;
??? ??? 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);
??? ??? ??? ??? DISPPARAMS disp = { NULL, NULL, 0, 0 };
??? ??? ??? ??? pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
??? ??? ??? }
??? ??? }
??? ??? return varResult.scode;
???
??? }


??? HRESULT __stdcall Fire_OnError(LONG err,BSTR msg)
??? {
??? ??? CComVariant varResult;
??? ??? T* pT = static_cast<T*>(this);
??? ??? int nConnectionIndex;
??? ??? 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);
??? ??? ??? ??? //DISPPARAMS disp = { NULL, NULL, 0, 0 };
??? ??? ??? ??? DISPPARAMS dispparams;
??? ??? ??? ?? memset(&dispparams, 0, sizeof(dispparams));
??? ??? ??? ?? dispparams.cArgs=2;?? // 设置参数个数
??? ??? ??? ?? dispparams.rgvarg=new VARIANTARG[1]; // 初始化参数数组
??? ??? ??? ?? dispparams.rgvarg[0].vt=VT_UI4; // 第一个参数的类型
??? ??? ??? ?? dispparams.rgvarg[0].uintVal=(UINT)err;
??? ??? ??? ?? dispparams.rgvarg[1].vt=VT_BSTR; // 第一个参数的类型
??? ??? ??? ?? dispparams.rgvarg[1].bstrVal=(BSTR)msg;??? ??? ??? ??

??? ??? ??? ??? pDispatch->Invoke(0x2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &varResult, NULL, NULL);
??? ??? ??? }
??? ??? }
??? ??? return varResult.scode;
???
??? }
};

?

?

?

我们可以看到,触发事件的FireEvent实现中,特殊之处在于,要把参数进行赋值,再调用定义的事件,0x1、0x2就是定义的事件。

?

?

实现之后,还需要在控件类定义处加入代理类,如(1)中需继承的其他类。

?

(4)有了这些之后,就可以在需要的地方触发事件,例如,在出现某种错误或情况时触发onError事件

?

(5)请注意,不要在控件所起的线程中触发事件,如果需要的话,请在线程中需要触发事件的地方给控件窗口(仅限控件有窗口的情况)发送自定义的消息,由控件窗口接收到消息后触发事件。要使用线程消息,需要在控件类定义时,在BEGIN_MSG_MAP和END_MSG_MAP中定义消息处理函数。

?

?

?

(6)一个题外话,控件类还应该继承 IObjectSafetyImpl,并在COM_MAP中声明宏,这样在浏览器中使用时,就不会弹出“在此页上的ActiveX控件和本页上的其它部分交互可能不安全”这样的提示。当然,要更好的解决安全问题,还需要考虑对控件数字签名等等方式。

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

热点排行