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();