其实做法很简单,就是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 
静静的想 阅读(2336) 
评论(1)  编辑 收藏 引用  所属分类: 
Windows/COM开发