javascript代码实例教程-Com组件调用JS代码并传递多个参数个JS函数

发布时间:2019-02-23 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了javascript代码实例教程-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 plaincopy

result = 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,   

            &params, 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 plaincopy

STDMETHODIMP 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+200  

  

BEgin_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;  

}  

 

创建消息窗口并启动线程函数:

 

[cpp]  

STDMETHODIMP CJSCallBack::Initialize(void)  

{  

    AFX_MANAGE_STATE(AfxGetStaticModuleState());  

  

    // TODO: 在此添加实现代码  

    if ( NULL == m_pMsgWnd )  

    {  

        m_pMsgWnd = new MsgWnd( this );  

        m_pMsgWnd->CreateEx(WS_EX_CLIENTEdge,_T(";message"),  

            _T("Message"),WS_OVERLAPPED,0,0,0,0,HWND_MESSAGE,NULL);  

    }  

  

    if ( 0 == m_hThreadHandle )  

    {  

        m_hThreadHandle = CreateThread(NULL, 0, (Lpthread_START_ROUTINE)CallJspFunctionThread, this, 0, &m_dThreadId);  

    }  

  

    return S_OK;  

}  

 

 

线程函数启动后,将会通过pMsgWnd->PostMessage( WM_COMM ),在MsgWnd类的消息处理函数中将会调用接口类的CallJsFunction函数。

 

由于pMsgWnd是在主线程中创建的,因此这样一来也就相当于是在主线程中调用JS函数了,虽然不是很完美,但是也成功的解决了项目中的实际问题。

 

 

 

 三、调用JS函数并返回值

[javascript] 

  function printMsg(msg1, msg2, msg3, msg4, msg5) {  

  

      alert(msg1);  

alert(msg2);  

alert(msg3);  

alert(msg4);  

alert(msg5);  

              return "abcDEFG";  

  }   

 

定义CComVariant变量,Invoke时用来接收来自JS函数的返回值

 

[cpp]  

CComVariant vaResult;   

    HRESULT hr = m_spCallback->Invoke(0,   

        IID_NULL,   

        LOCALE_USER_DEFAULT,   

        DISPATCH_METHOD,   

        &params, &vaResult, NULL, NULL);  

    AfXMessageBox(vaResult.bstrVal);  

执行完毕将会弹出带有字符串"ABCDEFG"的对话

 

 

 

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的javascript代码实例教程-Com组件调用JS代码并传递多个参数个JS函数全部内容,希望文章能够帮你解决javascript代码实例教程-Com组件调用JS代码并传递多个参数个JS函数所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。