调用JS函数

转载 2015年11月18日 09:01:38

这一章,我们来动手实践VC调用JS函数。


我们动手写一个HTML,其中包含这样一段JS代码:

  1. <script type="text/javascript">  
  2.     function Add(value1, value2) {  
  3.         return value1 + value2;  
  4.     }  
  5. </script>  

然后我们用WebBrowser加载这个HTML后,在VC中这样来调用这个函数名为Add的JS函数:

  1. //别忘了#include <MsHTML.h>  
  2. //m_WebBrowser是一个WebBrowser的Activex控件对象。  
  3. CComQIPtr<IHTMLDocument2> spDoc = m_WebBrowser.get_Document();  
  4. CComDispatchDriver spScript;  
  5. spDoc->get_Script(&spScript);  
  6.   
  7. CComVariant var1 = 10, var2 = 20, varRet;  
  8. spScript.Invoke2(L"Add", &var1, &var2, &varRet);  



spScript.Invoke2的作用是调用JS函数中名为Add的函数,传入两个参数,用varRet接收返回值。

可以看到,Invoke2调用成功后,varRet得到了返回值30。

 

但这样的话一次只能接受一个返回值。

如果要一次接受多个返回值的话,怎么办呢?

我们可以让JS返回一个JS中的Array数组或Object对象。

当JS函数return一个Array或一个Object对象时,VC这边的varRet将接受到一个代表该对象的IDispatch接口。我们仍然用CComDispatchDriver来管理这个IDispatch。用上一篇文章介绍的CComDispatchDriver的四个方法:

GetProperty

GetPropertyByName

PutProperty

PutPropertyByName

来从这个Array或Object对象中取出我们要的数据。

实践是检验真理的唯一标准,让我们再来写一个JS函数:

  1. <script type="text/javascript">  
  2.     function Add(value1, value2) {  
  3.         var array = new Array();  
  4.         array[0] = value1;  
  5.         array[1] = value2;  
  6.         array[2] = value1 + value2;  
  7.         return array;  
  8.     }  
  9. </script>  

然后在VC中这样写:
  1. CComQIPtr<IHTMLDocument2> spDoc = m_WebBrowser.get_Document();  
  2. CComDispatchDriver spScript;  
  3. spDoc->get_Script(&spScript);  
  4.   
  5. CComVariant var1 = 10, var2 = 20, varRet;  
  6. spScript.Invoke2(L"Add", &var1, &var2, &varRet);  
  7.       
  8. CComDispatchDriver spArray = varRet.pdispVal;  
  9. //获取数组中元素个数,这个length在JS中是Array对象的属性,相信大家很熟悉  
  10. CComVariant varArrayLen;  
  11. spArray.GetPropertyByName(L"length", &varArrayLen);  
  12. //获取数组中第0,1,2个元素的值:  
  13. CComVariant varValue[3];  
  14. spArray.GetPropertyByName(L"0", &varValue[0]);  
  15. spArray.GetPropertyByName(L"1", &varValue[1]);  
  16. spArray.GetPropertyByName(L"2", &varValue[2]);  



可以看到,10,20,30,这三个JS函数返回的值已经躺在我们的varValue[3]里了。

当然,如果不知道JS返回的Array对象里面有几个元素,我们可以在VC这边获取它的length属性,然后在一个循环中取出数组中的每个值。

 

如果我们的JS函数返回一个包含有多个属性值的Object对象,VC这边该如何接收呢?

让我们再来写一个JS函数:

  1. <script type="text/javascript">  
  2.     function Add(value1, value2) {  
  3.         var data = new Object();  
  4.         data.result = value1 + value2;  
  5.         data.str = "Hello,我是小明!";  
  6.         return data;  
  7.     }  
  8. </script>  

然后在VC中我们这样接收:

  1. CComQIPtr<IHTMLDocument2> spDoc = m_WebBrowser.get_Document();  
  2.     CComDispatchDriver spScript;  
  3.     spDoc->get_Script(&spScript);  
  4.   
  5.     CComVariant var1 = 10, var2 = 20, varRet;  
  6.     spScript.Invoke2(L"Add", &var1, &var2, &varRet);  
  7.       
  8.     CComDispatchDriver spData = varRet.pdispVal;  
  9.     CComVariant varValue1, varValue2;  
  10.     spData.GetPropertyByName(L"result", &varValue1);  
  11.     spData.GetPropertyByName(L"str", &varValue2);  



我们从JS返回的Object对象里取出了它的两个属性,result和str,分别是一个整形数据和一个字符串。

这里JS代码是我们自己写的,在VC这边当然事先知道这个JS函数返回的对象有result和str这两个属性。

如果JS代码不是我们写的,或者它的属性是事先不能确定的,该怎么办呢?答案是使用IDispatchEx接口来枚举这个对象的相关信息(方法名、属性名)。

这个现在暂时不讲,在后续的文章中会讲。


当然,JS不只可以返回Object对象,返回什么对象都可以,当返回一个对象而非基本数据类型(整形、浮点、字符串)时,VC这边收到的返回值是一个IDispatch,然后我们需要调用GetPropertyByName方法从这个IDispatch代表的对象中取出它的属性来。


这样一来,VC调用JS函数,传递参数给JS和JS返回返回值给VC,大致就都会了。

对于CComVariant包装的VARIANT这种智能型变量,不了解的可以到网上看下相关资料。《深入解析ATL》之类的书上均有介绍。

 

值得注意的是ATL提供的这些CCom开头的智能包装类,并不依赖于ATL的动态库。因为我在VC项目中并没有选择链接ATL,程序调试运行时进程加载的模块中也有没有ATL100.dll之类的模块载入。大家可以放心使用而不用担心依赖上ATL。

6- js 函数的四种调用方式

6. 函数的四种调用方式函数有下列调用模式 函数调用模式 方法调用模式 构造器模式 上下文模式 1. 函数调用 模式要调用,就肯定要先定义,函数的定义方式: 声明式: function fuc...
  • qq_16415157
  • qq_16415157
  • 2016年11月04日 13:41
  • 2641

javascript调用flash函数示例javascript调用flash函数示例

转发自:http://outofmemory.cn/code-snippet/1537/javascript-call-flash-function-example 关于Flash和...
  • lxd860105
  • lxd860105
  • 2015年01月09日 13:09
  • 716

深入理解JavaScript系列(一): 函数的四种调用模式

1.四种调用模式 1.方法调用模式 当一个函数被保存为对象的一个属性时,我们称之为一个方法。当一个方法被调用时,this被绑定到该对象。 function A() { this.x = ...
  • u012422829
  • u012422829
  • 2016年03月24日 22:27
  • 1441

Asp.Net 如何调用js中的函数function ?

http://bbs.csdn.net/topics/330215458 1、直接在前台调用 javascript 函数  很简单,在 head 元素之间加入 script 元素,将 ty...
  • DJ2008
  • DJ2008
  • 2013年09月28日 17:34
  • 5425

JS中的函数-内部函数,子调用函数和返回值为函数的函数

自调用函数(Self-invoking Functions) 自调用函数也是匿名函数的一种表现形式,这个函数在定义之后,直接调用。如下 (  function(){      alert(...
  • u012220365
  • u012220365
  • 2013年12月24日 16:23
  • 5326

[iOS]在WebApp中如何使用JS调用iOS的函数

实现功能:点击HTML标签,通过JS调用iOS的函数 iOS中,先拖拽WebView,访问localhost,然后通过WebView的委托事件监听url跳转操作,并且把跳转截取下来。 也就是说,在on...
  • wxg694175346
  • wxg694175346
  • 2014年06月04日 11:26
  • 2601

Js new一个函数和直接调用函数的区别

个人对js函数的理解
  • zchdjb
  • zchdjb
  • 2016年11月04日 20:09
  • 840

js函数中声明和调用、有参函数和无参函数、返回值

js函数中声明和调用、有参函数和无参函数、返回值
  • dzahao
  • dzahao
  • 2016年10月11日 20:09
  • 2048

iOS在WebApp中如何使用JS调用iOS的函数

实现功能:点击HTML的标签,通过JS调用iOS内部的原生函数 基本流程: 先看一下Web中,我们给h3标签添加一个onclick事件,让它在被点击之后,修改当前的url。 W...
  • wenzfcsdn
  • wenzfcsdn
  • 2015年01月04日 16:52
  • 1474

js调用其他js文件的函数,以及js加载过程

我们在编写js时,通常会需要在一个js文件中调用另一个js文件的函数,那么如何调用呢? 例如我有一个a.js文件,功能是弹出一个窗口的函数,我在b.js文件中需要调用这个函数,写法如下(函数开头弹窗...
  • sinat_32290679
  • sinat_32290679
  • 2016年08月24日 15:57
  • 3683
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:调用JS函数
举报原因:
原因补充:

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