如何实现IE中JS和VC之间的互相调用

转载 2013年12月03日 00:40:31

脚本语言和编译型语言之间进行通信是通过IDispatch接口来行的,这里我对双接口的理论就不进行讨论,直接看看如何用WTL代码来实现。

首先定义如下的一个IDispatch实现:

复制代码
 1 class CExternalDisp:
 2     public CComObjectRoot,
 3     public IDispatch
 4 {
 5 public:
 6     CExternalDisp(void);
 7     ~CExternalDisp(void);
 8 
 9     BEGIN_COM_MAP(CExternalDisp)
10         COM_INTERFACE_ENTRY(IDispatch)
11     END_COM_MAP()
12 
13      HRESULT STDMETHODCALLTYPE GetTypeInfoCount( 
14     /* [out] */ UINT *pctinfo) 
15     {
16         return E_NOTIMPL;
17     }
18 
19     HRESULT STDMETHODCALLTYPE GetTypeInfo( 
20         /* [in] */ UINT iTInfo,
21         /* [in] */ LCID lcid,
22         /* [out] */ ITypeInfo **ppTInfo)
23     {
24         return E_NOTIMPL;
25     }
26 
27     virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames( 
28         /* [in] */ REFIID riid,
29         /* [size_is][in] */ LPOLESTR *rgszNames,
30         /* [in] */ UINT cNames,
31         /* [in] */ LCID lcid,
32         /* [size_is][out] */ DISPID *rgDispId)
33     {
34         CComBSTR bsName(*rgszNames);
35         if (bsName == L"abc")
36         {
37             *rgDispId = 2535;
38             return S_OK;
39         }
40         return E_NOTIMPL;
41 
42     }
43 
44     virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( 
45         /* [in] */ DISPID dispIdMember,
46         /* [in] */ REFIID riid,
47         /* [in] */ LCID lcid,
48         /* [in] */ WORD wFlags,
49         /* [out][in] */ DISPPARAMS *pDispParams,
50         /* [out] */ VARIANT *pVarResult,
51         /* [out] */ EXCEPINFO *pExcepInfo,
52         /* [out] */ UINT *puArgErr) 
53     {
54         if (dispIdMember == 2535)
55         {
56             for (int i = 0; i < pDispParams->cArgs; ++i)
57             {
58                 if( pDispParams->rgvarg[i].vt == VT_INT)
59                     i = i;
60                 else
61 
62                     i = i;
63 
64             }
65 
66 
67             MessageBox(NULL, L"sdjlkf", L"sdl", MB_OK);
68             return S_OK;
69         }
70         return E_NOTIMPL;
71     }
72 
73 };
复制代码

以上代码中定义了一个CExternalDisp的组件,实现了IDispatch接口,当js脚本语言调用对象的某个方法时,会转成通过IDispatch的Invoke函数来调用,不同的函数对应不同的dispIdMember,而这个数字又是通过GetIDsOfNames来得到的。

有了CExternalDisp这个组件,还需要将其注册成为IE的exteranl对象。在IE控件的初始化部分进行设置,代码如下:

复制代码
1     CComPtr<IWebBrowser2> spWeb;
2     HRESULT hr = m_view.QueryControl(IID_IWebBrowser2, (void**)&spWeb );
3     CComObject<CExternalDisp> *obj;
4     CComObject<CExternalDisp>::CreateInstance(&obj);
5     CComPtr<IDispatch> spDisp;
6     obj->QueryInterface(IID_IDispatch, (void**)&spDisp);
7     m_view.SetExternalDispatch(spDisp);
复制代码

这样,JS脚本中的代码就可以访问window.external对象中得方法了。下面是html中js调用exteranl.abc的代码段:

复制代码
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 8.0">
<TITLE></TITLE>

<script type="text/javascript">
    window.external.abc(1, 'ljw', 2.3);
</script>

</HEAD>
<BODY>

</BODY>
</HTML>
复制代码

可以看到在页面加载时调用了window.external.abc(1'ljw'2.3);这个方法,还传递了参数。 当js的执行引擎解释这个语句时,会先去讲abc这个字符串送到GetIDsOfNames中去,获得对应的DISPID, 然后用这个DISPID在调用Invoke函数。我们在invoke函数对这个abc方法对应的dispid进行了处理,就能够给js进行结果反馈。通过实验,js函数中得参数是放在DISPPARAMS中传入Invoke的,而且好像是最右边的参数最先入栈。

相关文章推荐

VC与Delphi之间动态链接库互相调用

====================================================== 注:本文源代码点此下载 =============================...

js子窗口之间互相调用,top在捣乱

index.html  总体框架显示:                   无标题文档                 function ppp(){                    ...

两个JS之间的函数互相调用

这个问题是我在工作中用到的一个方法 因为要做封装 所以想到能不能在一个js中引用另一个js中的function 这样的话能大大的减少代码量话不多说 先上代码首先要在html页面引入两个js文件...
  • alokka
  • alokka
  • 2017年07月18日 17:07
  • 159

Android与JS之间的互相调用交互(二)

WebView默认是禁用JavaScript的,在启用后,就可以在两者间建立接口进行调用WebView myWebView = (WebView) findViewById(R.id.webview)...

Js代码和Java代码之间的互相调用了

很多复杂的UI界面,在Android中需要配合大量xml代码和Java代码实现,而使用HTML5可以非常轻松的实现出来,而且具有很好的跨平台特性,让我们不必为了多个平台而重写代码,H5学习成本也较低,...

JS调用IE实现分页打印

  • 2008年12月20日 00:48
  • 4KB
  • 下载

C++和C#之间互相调用

  • 2011年04月21日 16:16
  • 243KB
  • 下载

IE中js调用脚本实现打印预览(按钮本身不打印)

print demo .noprint { display: none; } function doPrintSetup() { //打印设置...

IE中js调用脚本实现打印预览(按钮本身不打印)

先上代码(声明大部分代码来自网络) print demo .noprint { display : none; } function doPrintSetup()...
  • crybird
  • crybird
  • 2012年05月10日 07:47
  • 13377

Delphi框架中怎样实现主程序与插件之间的互相调用以及参数传递

插件工程的dpr文件引出了三个函数,分别是CreatDllMDIForm,FreeDllMDIForm和GetDllPluginSign,主程序中通过调用动态库中的这三个函数实现dll中窗口的创建,具...
  • iivii
  • iivii
  • 2012年02月29日 09:31
  • 790
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何实现IE中JS和VC之间的互相调用
举报原因:
原因补充:

(最多只允许输入30个字)