VC与JavaScript交互(二) --- 调用JS函数
这一章,我们来动手实践VC调用JS函数。
我们动手写一个HTML,其中包含这样一段JS代码:
//[html]
<script type="text/javascript">
function Add(value1, value2)
{
return value1 + value2;
}
</script>
然后我们用WebBrowser加载这个HTML后,在VC中这样来调用这个函数名为Add的JS函数:
//[Cpp]
//别忘了#include <MsHTML.h> void CTestCallJsDlg::OnBnClickedOk()
{
//m_WebBrowser是一个WebBrowser的Activex控件对象。
CComQIPtr<IHTMLDocument2> spDoc = m_WebBrowser.get_Document();
CComDispatchDriver spScript;
spDoc->get_Script(&spScript); CComVariant var1 = , var2 = , varRet;
spScript.Invoke2(L"Add", &var1, &var2, &varRet);
}
调试(Debug):
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] view plaincopy在CODE上查看代码片派生到我的代码片
<script type="text/javascript">
function Add(value1, value2) {
var array = new Array();
array[0] = value1;
array[1] = value2;
array[2] = value1 + value2;
return array;
}
</script>
然后在VC中这样写:
//[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
void CTestCallJsOnBnClickedOk()
{
CComQIPtr<IHTMLDocument2> spDoc = m_WebBrowser.get_Document();
CComDispatchDriver spScript;
spDoc->get_Script(&spScript); CComVariant var1 = , var2 = , varRet;
spScript.Invoke2(L"Add", &var1, &var2, &varRet); CComDispatchDriver spArray = varRet.pdispVal;
//获取数组中元素个数,这个length在JS中是Array对象的属性,相信大家很熟悉
CComVariant varArrayLen;
spArray.GetPropertyByName(L"length", &varArrayLen);
//获取数组中第0,1,2个元素的值:
CComVariant varValue[];
spArray.GetPropertyByName(L"", &varValue[]);
spArray.GetPropertyByName(L"", &varValue[]);
spArray.GetPropertyByName(L"", &varValue[]);
}
调试(Debug):
可以看到,10,20,30,这三个JS函数返回的值已经躺在我们的varValue[3]里了。
当然,如果不知道JS返回的Array对象里面有几个元素,我们可以在VC这边获取它的length属性,然后在一个循环中取出数组中的每个值。
如果我们的JS函数返回一个包含有多个属性值的Object对象,VC这边该如何接收呢?
让我们再来写一个JS函数:
//[html] view plaincopy在CODE上查看代码片派生到我的代码片
<script type="text/javascript">
function Add(value1, value2) {
var data = new Object();
data.result = value1 + value2;
data.str = "Hello,我是小明!";
return data;
}
</script>
然后在VC中我们这样接收:
//[cpp]
void CTestCallJsOnBnClickedOk()
{
CComQIPtr<IHTMLDocument2> spDoc = m_WebBrowser.get_Document();
CComDispatchDriver spScript;
spDoc->get_Script(&spScript); CComVariant var1 = 10, var2 = 20, varRet;
spScript.Invoke2(L"Add", &var1, &var2, &varRet); CComDispatchDriver spData = varRet.pdispVal;
CComVariant varValue1, varValue2;
spData.GetPropertyByName(L"result", &varValue1);
spData.GetPropertyByName(L"str", &varValue2);
}
调试(Debug):
我们从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呢?我们将在下一篇文章中慢慢道来。
VC与JavaScript交互(二) --- 调用JS函数的更多相关文章
- c++与js脚本交互,C++调用JS函数/JS调用C++函数
<!DOCTYPE html> <html> <body> <h1>我的第一段 JavaScript</h1> <p> Java ...
- c++与js脚本交互,C++调用JS函数JS调用C++函数
一.javascript调用c++,方法有两种 方案1: 1.html编写 <html><head></head><body><h1>TES ...
- [AS3]as3与JS的交互(AS3调用JS)实例说明
一,AS3 vs JavaScript (1)AS3调用JS 函数: ExternalInterface.(functionName:, arguments): //AS3 Code 属性: 同上,通 ...
- js,JavaScript,a标签onclick传递参数不对,A标签调用js函数写法总结
错误示例: <a href="javascript:waterLineEdit(${goods.goods_id})" >修改 </a> <!-- 浏 ...
- VC与JavaScript交互(一) --- 如何实现
为什么要让VC与JavaScript交互? 1.有时候我们需要让自己的软件打开一个网页,来获取页面上的一些数据.这时,可以用mshtml解析HTML提取出数据,也可以向HTML文档动态写入我们准备好的 ...
- VC与JavaScript交互(一) ———— 怎样实现
为什么要让VC与JavaScript交互? 1.有时候我们须要让自己的软件打开一个网页.来获取页面上的一些数据. 这时,能够用mshtml解析HTML提取出数据.也能够向HTML文档动态写入我们准备好 ...
- 初探JavaScript(二)——JS如何动态操控HTML
除去五一三天,我已经和<JavaScript Dom编程艺术>磨合了六天,第一印象很好.慢慢的,我发现这是一块排骨,除了肉还有骨头.遇到不解的地方就会多看几遍,实在不懂的先跳过,毕竟,初次 ...
- Java中通过脚本引擎调用js函数
import java.io.*; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.scri ...
- [模拟回调] demo1模拟用字符串调用js函数 demo2模拟springmvc controller回调页面js函数
demo1. 模拟用字符串调用js 函数 function dataQuery() { var strFun = "testCallBack"; var strParam = &q ...
随机推荐
- 将网站部署到windows2003 iis6之后,出现asp.net程序页面无法访问情况
idc的技术说是没有装.net framework 2.0的缘故. 可是我已经装了4.0. 后来把一个伪静态的组件卸载了,就可以了.
- OAF_架构MVC系列1 - MVC的概述(概念)
2015-04-03 Created By BaoXinjian
- CF109 C. Lucky Tree 并查集
Petya loves lucky numbers. We all know that lucky numbers are the positive integers whose decimal re ...
- python--输入一组无序的数,排序
N=int(raw_input('input the number N=')) number=[] while(N): m=int(raw_input('input..\n')) number.app ...
- js中如何操作json数据
一.要想熟练的操作json数据,就先要了解json数据的结构,json有两种结构:对象和数组. 1.对象 一个对象以“{”开始,“}”结束.每个“名称”后跟一个“:”:“‘名称/值’ 对”之间使用“, ...
- java获取数据库的列名,类型等信息
当你使用和学习JDK的时候,可以查看并学习它所提供给你的两个ResultSetMetaData 和DataBaseMetaData类的源码并很好的了解它们的实现原理和思路,JDBC中提供有两种源数据, ...
- 解决dedev5.7更新出现include\userlogin.class.php on line 21的办法
第一种情况解决办法: 在dede\templets文件夹 找到 index_body.htm 文件 把这些注释掉. $(function() { $.get("index_tes ...
- DELPHI SOKET 编程(使用TServerSocket和TClientSocket) 转
http://www.cnblogs.com/findumars/p/5272658.html 本文采用delphi7+TServerSocket+TClientSocket; 笔者在工作中遇到对 ...
- [SQL] cast 与 convert 都在什么情况下使用
CONVERT(data_type,expression[,style]) 说明: 此样式一般在时间类型(datetime,smalldatetime)与字符串类型(nchar,nvarchar,ch ...
- [ZOJ 1010] Area (计算几何)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1010 题目大意:给你n个点,问你顺次连线能否连成多边形?如果能, ...