Com组件调用JS代码并传递多个参数个JS函数
项目中经常碰到JS与Com组件交互的问题,通过查找网络资料和项目实际需要,总结如下:一、Com组件简单回调JS代码JS中定义函数[javascript]function printMsg(msg1, msg2, msg3, msg4, msg5) {alert(msg1);alert(msg2);alert(msg3);alert(msg4);alert(msg5);}Com组件中定义函数接口,以便将JS中定义的函数作为参数传递给Com组件头文件中定义IDispatch接口:[cpp]static CComPtr<IDispatch> m_spCallback;[cpp]STDMETHODIMP CJSCallBack::SetJsCallbackFunc(VARIANT scriptCallback){AFX_MANAGE_STATE(AfxGetStaticModuleState());// TODO: 在此添加实现代码if (scriptCallback.vt == VT_DISPATCH){m_spCallback = scriptCallback.pdispVal;}return S_OK;}在JS中调用SetJsCallbackFunc接口注册回调函数[javascript]var obj = new ActiveXObject("ComForJS.JSCallBack.1");[javascript] view plaincopyresult = obj.SetJsCallbackFunc(printMsg);Com组件中调用JS函数:[cpp]void CJSCallBack::CallJsFunction(){CComVariant avarParams[5];avarParams[0] = “AAA”; //指定回调函数的参数avarParams[1] = "BBB";avarParams[2] = "CCC";avarParams[3] = "DDD";avarParams[4] = "EEE";DISPPARAMS params = { avarParams, NULL, 5, 0 };if(m_spCallback){HRESULT hr = m_spCallback->Invoke(0,IID_NULL,LOCALE_USER_DEFAULT,DISPATCH_METHOD,¶ms, NULL, NULL, NULL);}}几点注意的地方:1,DISPPARAMS params = { avarParams, NULL, 5, 0 },中的第三个参数将决定要传递到JS函数中的参数的个数2,在JS函数中参数的顺序与Com组件中赋值的顺序是反的,根据本例代码,参数数组中第一个是"AAA",最后一个是"EEE",但是实际在JS代码中,msg1的值是"EEE",msg5的值是"AAA"调用过程:[javascript]obj.Print("AAA",0);[cpp] view plaincopySTDMETHODIMP CJSCallBack::Print(BSTR bstrToPrint, LONG lWait){AFX_MANAGE_STATE(AfxGetStaticModuleState());CallJsFunction();return S_OK;}可以发现,以上调用是单线程调用,那么,如果在Com组件中,需要多线程操作,并且要在别的线程完成一定任务之后才需要调用JS函数,而在子线程是没有办法直接调用在主线程中注册的JS函数的,又该如何处理呢?二、Com组件中,多线程调用JS函数针对这个问题,查阅了大量资料,基本上都是关于IDispatch接口在多线程中使用需要列集散集等概念,可能理解能力较差,最终也没能够通过这样的方式来解决实际项目中的问题,后来联想到以前项目中曾经用到过的消息窗口,于是决定尝试一番:定义MsgWnd类:[cpp]class CJSCallBack;//接口类class MsgWnd : public CWnd{public:MsgWnd() {}MsgWnd( CJSCallBack* p );~MsgWnd() {}protected:afx_msg LRESULT OnRecvMsg(WPARAM wParam, LPARAM lParam);DECLARE_MESSAGE_MAP()private:MsgWnd(const MsgWnd&);MsgWnd& operator=(const MsgWnd&);CJSCallBack* m_pParent;};为MsgWnd类实现构造函数以及消息处理函数,并设置MessageMap[cpp]#define WM_COMM WM_USER+200BEGIN_MESSAGE_MAP(MsgWnd, CWnd)ON_MESSAGE(WM_COMM, OnRecvMsg)END_MESSAGE_MAP()LRESULT MsgWnd::OnRecvMsg(WPARAM wPar, LPARAM lPar){if ( NULL != m_pParent ){m_pParent->CallJsFunction();//调用Parent,也就是接口类中的函数}return 1;}MsgWnd::MsgWnd( CJSCallBack* p ){if ( NULL != p ){m_pParent = p;}}在接口类中声明消息窗口:[cpp]MsgWnd* m_pMsgWnd;[cpp]声明线程函数:[cpp]<pre class="cpp" name="code">static UINT CallJspFunctionThread(LPVOID param);</pre>定义线程函数:[cpp]UINT CJSCallBack::CallJspFunctionThread(LPVOID param){CJSCallBack* pCallBack = (CJSCallBack*)param;while(m_bRunThread){while(m_bPrint){MsgWnd* pMsgWnd = pCallBack->GetMsgWnd();if ( NULL != pMsgWnd ){pMsgWnd->PostMessage( WM_COMM );}}sleep(20000);}return 0;}创建消息窗口并启动线程函数:补充:web前端 , JavaScript ,
上一个:js控制文本框自动适应文本长度
下一个:javaScript中的正则表达式
- 更多JS疑问解答:
- 几个验证11位手机号码格式的js代码
- js把图片转换成 base64代码
- js把base代码转换成图片
- JS 将 base64编码的图片转化为图片文件
- js中的定时器
- js如何获得FCKeditor控件的值
- 用js限制投票的cookie .目前设置的为:<input type="" class="" onclick="'window.location...
- JS验证,这块“牛皮”反复修改都不能实现
- 在JS中使用DOM模型
- 如何用JS 获取本地文件夹的文件列表
- js中new 了两个Object数组。怎么样将数组内容合并,重复的内容?
- 求实现自动生成图片缩略图的JS代码
- JS脚本网页问题
- js,代码中"object"和"Object"区别?
- js+flash实现网页图片切换效果,出现边框,单击激活此控件。