vc++调用msscript.ocx解析实现C++与JavaScript脚本交互

ScriptControl接口

属性名称

类型

备注

AllowUI

BOOL

检测是否允许运行用户的接口元素。如果为False,则诸如消息框之类的界面元素不可见。

CodeObject

Object

脚本暴露给宿主调用的对象。只读。

Modules

Modules

宿主提供给脚本的组件库模块。只读。(COM组件通常都是以对象收集的形式向用户提供可以留给用户二次开发的对象集合,每一个收集即一个Modules)

Language

String

设置或获取脚本引擎解释的语言,例如:VBScript、JScript。

Name

String

脚本引擎的名称。只读。

Procedures

Procedures

返回模块中定义的过程的集合

SitehWnd

HWND

在脚本中显示UI的父窗口句柄

State

Enum

设置或返回控件的状态,如果为0,控件只执行语句但不转发事件,为1则为加入的本控件接受的对象转发事件。

Timeout

Long

控件的执行脚本的超时值,-1表示不超时

UseSafeSubset

BOOL

设置或返回宿主程序是否关心安全。宿主程序的安全级别可以从此属性设置

Error

Error

错误对象,发生错误时,此属性返回一个错误对象

方法名称

参数

功能

AddCode

Code As String

往脚本引擎中加入要执行的脚本

AddObject

Name As String, Object As Object, [AddMembers As Boolean = False]

往脚本引擎加入一个对象,以便在脚本中可以使用该对象提供的方法等。

Eval

Expression As String

表达式求值

ExecuteStatement

Statement As String

解释并执行脚本语句

Reset

丢弃所有的对象和代码,将State属性置0。

Run

ProcedureName As String, ParamArray Parameters() As Variant

运行一个指定的过程

事件名称

功能

Error

有错误发生时激发该事件

TimeOut

执行过程超时时发生

一般使用方法

1、在程序中加入ScriptControl

2、定义一个ScriptControl的实例

3、调用AddCode等方法向脚本引擎中加入要执行的脚本。

4、调用Run执行要执行的脚本函数。

1.导入msscript.ocx

1 #import "C:\\Windows\\syswow64\\msscript.ocx" no_namespace

这一步步能忘记否则无法生成com接口文件

下面的就是代码了

  1 fstream m_fs;
  2     long Error_code=NULL;
  3     long Error_Line = NULL;
  4     BSTR Error_content;
  5     HRESULT hr = ::CoInitialize(NULL);        //初始化com库
  6     IScriptControlPtr  m_IScritp(__uuidof(ScriptControl));
  7     IScriptErrorPtr m_IScript_Error = m_IScritp->Error;
  8     //hr = m_IScritp->get_Error(&m_IScript_Error);
  9     m_IScritp->Language = "javascript";        //设置语言的格式
 10     m_fs.open("QQ.js", ios::in | ios::_Nocreate);
 11     if (!m_fs.is_open()) {
 12         m_fs.close();
 13         return ;
 14     }
 15     //得到文件的大小
 16     m_fs.seekg(0, ios::end);
 17     streamoff  length;
 18      DWORD i = 0;
 19     string m_str;
 20     length = m_fs.tellg();
 21     i = (DWORD)length;
 22     char* strTemp = new char[i];
 23     if (!strTemp)return;
 24     memset(strTemp, 0, i);
 25     m_fs.seekg(0, ios::beg);
 26     m_fs.read(strTemp, length);
 27     m_str.append(strTemp);
 28     m_fs.close();    //关闭文件流
 29     //size_t max_size =m_str.max_size();
 30     /*hr = m_IScritp->AddCode(m_str.c_str());        //把代码加载到解释器里
 31     if (FAILED(hr)) {
 32         hr = m_IScript_Error->get_Number(&Error_code);
 33         hr = m_IScript_Error->get_Line(&Error_Line);
 34         hr = m_IScript_Error->get_Description(&Error_content);
 35     };*/
 36     hr=m_IScritp->ExecuteStatement(m_str.c_str());    //ExecuteStatement 和AddCode 一样都是将代码加入解释器 使用任意一个都可以
 37     if (FAILED(hr)) {
 38         hr = m_IScript_Error->get_Number(&Error_code);    //获取错误的代码
 39         hr = m_IScript_Error->get_Line(&Error_Line);    //获取错误的行号
 40         hr = m_IScript_Error->get_Description(&Error_content);    //获取具体错误的文本描述
 41     };
 42     _bstr_t eval = "getEncryption(\"123456\",\"\",\"!VVZ\",0);";
 43     _variant_t r_st;
 44     LPSAFEARRAY pSafearray;            //安全数组指针
 45     SAFEARRAYBOUND rgsabound[1];
 46     /*
 47     SAFEARRAYBOUND是一个结构体,里面有两个变量,ULONG cElements表示的是元素的数目(更准确的说是在本维中的数目);
 48     LONG lLbound表示的是一个逻辑起点序号,实际访问内存的时候,安全数组会将程序指定的序号减去lLbound,
 49     比如你将其设置为10000,a[10000]这相当于A[0],a[999]数组越界,所以在没有特殊要求的情况下,lLbound一般为0。
 50     还有一点,定义的时候是SAFEARRAYBOUND rgsaBound[1], 这点要解释一下,rgsaBound[1]表示的是一位数组,
 51     二维数组要定义为rgsaBound[2],这里主要讲解一位数组,更高维数大家可以去搜一下,和一维的相似。
 52     */
 53     rgsabound[0].cElements = 4;
 54     rgsabound[0].lLbound = 0;
 55     pSafearray = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
 56     /*
 57     第一个参数VT_VARIANT表示数组的类型,第二个参数表示创建数组的维数,本例中是一维,第三个参数是对这个数组各个维度的描述。
 58     SafeArrayCreate()就是创建SAFEARRAY的函数,准确的说是在堆中创建了一个SAFEARRAY,也就是说在这个函数里面,
 59     调用了new或者malloc()之类的申请了一个空间 最后使用SafeArrayDestroy() 释放内部申请的空间
 60     */
 61     if (!pSafearray)
 62     {
 63         return;
 64     }
 65     VARIANT vFlavors[4];
 66     
 67     for (LONG i = 0;i<4;i++)
 68     {
 69         VariantInit(&vFlavors[i]);
 70         V_VT(&vFlavors[i]) = VT_BSTR;
 71         if (i==3)
 72         {
 73             vFlavors[i].vt = VT_INT;    //最后一个参数是整数
 74         }
 75     }
 76     vFlavors[0].bstrVal = SysAllocString(OLESTR("123456"));
 77     vFlavors[1].bstrVal = SysAllocString(OLESTR(""));
 78     vFlavors[2].bstrVal = SysAllocString(OLESTR("!VVZ"));
 79     vFlavors[3].intVal = 0;
 80     
 81     for (LONG l=0;l<4;l++)
 82     {
 83         SafeArrayPutElement(pSafearray, &l, &vFlavors[l]);
 84         /*
 85         第一个参数是指向SAFEARRAY的指针;
 86         第二个参数是long型数组元素下标的指针,
 87         第三个参数就是要放置的那个值得指针了。
 88         */
 89         if (l<3)
 90         {
 91             SysFreeString(vFlavors[l].bstrVal);
 92         }
 93 
 94     }
 95     r_st = m_IScritp->Run("getEncryption",&pSafearray);
 96     if (r_st.vt==VT_NULL || r_st.vt ==VT_EMPTY) {
 97         hr = m_IScript_Error->get_Number(&Error_code);
 98         hr = m_IScript_Error->get_Line(&Error_Line);
 99         hr = m_IScript_Error->get_Description(&Error_content);
100     };
101         /*
102         m_IScript_Error->get_Column();
103         m_IScript_Error->get_HelpContext();
104         m_IScript_Error->get_Source();
105         m_IScript_Error->get_Text();
106         */
107     SafeArrayDestroy(pSafearray);//释放数组空间
108     delete [] strTemp;
109     ::CoUninitialize();