其实做法很简单,就是ATL类中用一个 IDispatch* 来保存javascript函数,在调用时直接调用 IDispatch DSPID为0的method即可,简单的示例代码如下:
1 STDMETHODIMP CCallBackScript::put_cbMethod(IDispatch* newVal)
2 {
3 IDispatch *tmp = NULL;
4 if(m_callbackmethod)
5 {
6 IDispatch *tmp = m_callbackmethod;
7 m_callbackmethod = NULL;
8
9 tmp->Release();
10 }
11
12 tmp = newVal;
13 tmp->AddRef();
14 m_callbackmethod = tmp;
15
16 return S_OK;
17 }
18
这样m_callbackmethod中就保存了对应的javascript方法对象。
调用方式如下:
1 STDMETHODIMP CCallBackScript::Call(void)
2 {
3 if(m_callbackmethod)
4 {
5 return _com_dispatch_raw_method(m_callbackmethod,0,DISPATCH_METHOD,VT_EMPTY,NULL,
6 L"\x0003\x0008",300,::SysAllocString(L"测试中文"));
7 }
8 //其他对应的处理
9 return S_OK;
10 }
11
这样就实现了回调函数,至于_com_dispatch_raw_method嘛可以看我的另一篇日志 IDispatch 接口方法的调用 !
使用代码如下:
1 <html>
2 <head>
3 <title>测试</title>
4 <script language=javascript>
5 <!--
6 function cbmthod(i,str) {
7 alert("i\t= " +i+ "\nstr\t= " + str);
8 //尚不清楚这里抛出异常该如何捕获
9 }
10
11 var scrcb ;
12 try{
13 scrcb = new ActiveXObject("TestScriptCallBack.CallBackScript");
14 }
15 catch(e){
16 alert(e.message);
17 }
18
19 scrcb.cbMethod = cbmthod;
20
21 function abc(){
22 try{
23 scrcb.Call();
24 }
25 catch(e){
26 alert(e.message);
27 }
28 }
29
30
31 //-->
32 </script>
33 </head>
34 <body>
35 <input type=button value=点击测试 onclick="abc()" />
36 </body>
37 </html>
当然在多线程中不这么方便,需要 CoMarshalInterface CoUnmarshalInterface 来协助完成!
别处摘抄:
说明
该技术仅适用于脚本。不适合于VB、C++客户。
该技术和连接点、事件无关。
posted on 2009-11-19 13:49
静静的想 阅读(2271)
评论(1) 编辑 收藏 引用 所属分类:
Windows/COM开发