VC与JavaScript交互(二) ———— 调用JS函数

页面导航:首页 > 网络编程 > JavaScript > VC与JavaScript交互(二) ———— 调用JS函数

VC与JavaScript交互(二) ———— 调用JS函数

来源: 作者: 时间:2016-02-20 09:49 【

这一章,我们来动手实践VC调用JS函数。我们动手写一个HTML,其中包含这样一段JS代码:[html] function Add(value1, value2) { return value1 43; value2;

这一章,我们来动手实践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函数:

     

     

    [cpp 
    1. //别忘了#include
    2. //m_WebBrowser是一个WebBrowser的Activex控件对象。
    3. CComQIPtr spDoc = m_WebBrowser.get_Document();
    4. CComDispatchDriver spScript;
    5. spDoc->get_Script(&spScript);
    6.  
    7. CComVariant var1 = 10, var2 = 20, varRet;
    8. spScript.Invoke2(LAdd, &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函数:

       

      [html] 
      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中这样写:

         

         

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

           

          \

           

           

           

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

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

           

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

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

           

          [html] 
          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中我们这样接收:

             

             

            [cpp] 
            1. CComQIPtr spDoc = m_WebBrowser.get_Document();
            2. CComDispatchDriver spScript;
            3. spDoc->get_Script(&spScript);
            4.  
            5. CComVariant var1 = 10, var2 = 20, varRet;
            6. spScript.Invoke2(LAdd, &var1, &var2, &varRet);
            7.  
            8. CComDispatchDriver spData = varRet.pdispVal;
            9. CComVariant varValue1, varValue2;
            10. spData.GetPropertyByName(Lresult, &varValue1);
            11. spData.GetPropertyByName(Lstr, &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。

               

              VC调用JS函数没问题了。那么JS函数如何调用VC呢?我们将在下一篇文章中慢慢道来。

Tags:

文章评论

最 近 更 新
热 点 排 行
Js与CSS工具
代码转换工具

<