(转)如何在JavaScript与ActiveX之间传递数据3

时间:2022-09-18 11:21:43

本文研究如何在JS等脚本语言与ActiveX控件之间通信,如何传递各种类型的参数,以及COM的IDispatch接口。使用类似的方法,可以推广到其他所有脚本型语言,如LUA,AutoCad等。
本文将研究以下几个方面:

1.         整形数组传参

2.         字符串参数,字符串返回值

3.         修改传入字符串内容

4.         数组参数

5.         IDispatch接口介绍

6.         修改输入数组内容

7.         增加数组内容

8.         以数组传参方式,JS调用S4Execute( )

由于本文篇幅较长,所以将以连载方式进行发表,连载一主要讨论1-3点,连载二主要讨论4-6点,连载三主要讨论7-8点.

(七)增加数组内容

1.      在COM中无法向JS中一样,直接增加数组元素。只能使用属性、方法的方式访问数组对象,并以此产生增加数组元素的效果。

2.       JS的Array中包含push( )、 pop( )两个方法,用于在数组尾部增减元素。在COM中需要增减元素时,可通过IDispatch:: Invoke( )接口调用 "push"、"pop"方法来实现。

3.       COM中C++定义

STDMETHODIMP CJsAtl::AddNewElement(VARIANT vArray)

{

AddArrayElement(vArray.pdispVal, 123);   // 增加元素,值为 123

return S_OK;

}

// ****************************************************

// 向js数组中增加元素

// ****************************************************

HRESULT AddArrayElement(IDispatch* pDisp, int value)

{

HRESULT hr = 0;

DISPID      dispid[2] = {0};

CComBSTR funcName(L"push");

hr = pDisp->GetIDsOfNames(IID_NULL, &funcName, 1, LOCALE_USER_DEFAULT, dispid);

if (FAILED(hr))

return hr;

DISPID dispidNamed = DISPID_UNKNOWN;

DISPPARAMS params;

params.rgdispidNamedArgs = NULL;

params.cArgs = 1;

params.cNamedArgs = 0;

params.rgvarg = new VARIANTARG[1];

params.rgvarg[0].vt = VT_I4;

params.rgvarg[0].intVal = value;

hr = pDisp->Invoke(dispid[0], IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

return hr;

}

4.         JS调用

function test_add_element()

{

var array = new Array(0, 1, 2, 3);

try {

var obj = document.getElementByIdx_xx_x("obj");

obj.AddNewElement(array);

alert("length: [" + array.length + "] " + array[array.length - 1]);

} catch (e) {

alert("JS ERROR: " + e.message);

}

}

5.         测试执行

原数组:{0,1,2,3}

增加后:{0,1,2,3,123}

(八)以数组传参方式,JS调用S4Execute( )

1.         本例展示如何在JS中执行精锐4锁内程序,且以数组方式处理参数。

2.         本例在Execute传参时,直接以整形数组表示字节数组,而不再需要Hex字符串形式,使得JS端接口更加直观。

3.         JS代码

var obj = document.getElementByIdx_xx_x("obj");

var deviceID = "123";

var userPin = "12345678";

var fileID  = "0001";

var inBuff      = new Array(1, 2, 3, 4);

var outBuff = new Array(0, 0, 0, 0);

var ret = 0;

try {

ret = obj.OpenLock(deviceID);

ret = obj.ChangeDir("\\");

ret = obj.VerifyPin(userPin);

ret = obj.Execute(fileID, inBuff, outBuff);

ret = obj.Close();

} catch (e) {

alert("JS Exception: " + e.message);

}

// JS数组操作,打印结果

var str = "";

for (var i = 0; i < outBuff.length; i++)

str += " " + outBuff[i];

alert(str);

4.          ActiveX代码

SENSE4_CONTEXT  g_ctx = {0}; //全局变量保存当前打开的ctx

// 打开设备,以设备ID作为筛选条件,若设备ID指定为空串,则打开第一把锁

STDMETHODIMP CS4ActiveX::OpenLock(BSTR deviceID, LONG* retVal)

{

SENSE4_CONTEXT *         pctx  =       NULL;

unsigned long                ret              =       0;

unsigned long                size   =       0;

unsigned long                devCount= 0;

unsigned long                i                  =       0;

char                               bDeviceID[9]      = {0};

char                               bUserPin[9]                  = {0};

S4Enum(NULL, &size);

if (size == 0)

{

*retVal = S4_NO_LIST;

goto cleanup;

}

pctx = (SENSE4_CONTEXT*) malloc(size);

ret = S4Enum(pctx, &size);

if (ret != S4_SUCCESS)

{

*retVal = ret;

goto cleanup;

}

// 获取ascii格式的设备ID

WideCharToMultiByte(CP_ACP, 0, deviceID, SysStringLen(deviceID), bDeviceID, 9, NULL, NULL);

// 遍历,寻找deviceID为指定值的设备

devCount = size / sizeof(SENSE4_CONTEXT);

for (i = 0; i < devCount; i++)

{

if (strlen(bDeviceID) == 0) // 未指定设备ID,返回第一把锁

{

break;

}

if (0 == memcmp(bDeviceID, pctx[i].bID, 8))

{

break;

}

}

// 没有找到

if (i == devCount)

{

*retVal = S4_NO_LIST;

goto cleanup;

}

memcpy(&g_ctx, &pctx[i], sizeof(SENSE4_CONTEXT));

ret = S4Open(&g_ctx);

if (ret != S4_SUCCESS)

{

*retVal = ret;

goto cleanup;

}

*retVal = S4_SUCCESS;

cleanup:

if (pctx)

{

free(pctx);

pctx = NULL;

}

return S_OK;

}

STDMETHODIMP CS4ActiveX::ChangeDir(BSTR dir, LONG* retVal)

{

char            bDir[20]     = {0};

WideCharToMultiByte(CP_ACP, 0, dir, SysStringLen(dir), bDir, 20, NULL, NULL);

*retVal = S4ChangeDir(&g_ctx, bDir);

return S_OK;

}

STDMETHODIMP CS4ActiveX::Execute(BSTR fileID, VARIANT inBuff, VARIANT outBuf, LONG* retVal)

{

char            bFileID[5]  =       {0};

BYTE *               bInBuff               =       NULL;

BYTE *               bOutBuff   =       NULL;

int                        inBuffSize  =       0;

int                        outBuffSize =     0;

unsigned long size                  =       0;

unsigned long ret          =       0;

int                        i                           =       0;

int                        tmp                     =       0;

GetArrayLength(inBuff.pdispVal, &inBuffSize);

GetArrayLength(outBuf.pdispVal, &outBuffSize);

if (inBuffSize > 0)

bInBuff = (BYTE*) malloc(inBuffSize);

if (outBuffSize > 0)

bOutBuff = (BYTE*) malloc(outBuffSize);

for (i = 0; i < inBuffSize; i++)

{

GetArrayNumberOfIndex(inBuff.pdispVal, i, &tmp);

bInBuff[i] = (BYTE)tmp;

}

WideCharToMultiByte(CP_ACP, 0, fileID, SysStringLen(fileID), bFileID, 5, NULL, NULL);

ret = S4Execute(&g_ctx, bFileID, bInBuff, inBuffSize, bOutBuff, outBuffSize, &size);

if (ret != S4_SUCCESS)

{

*retVal = ret;

return S_FALSE;

}

for (i = 0; i < size; i++)

{

SetArrayNumberOfIndex(outBuf.pdispVal, i, bOutBuff[i]);

}

return S_OK;

}

STDMETHODIMP CS4ActiveX::VerifyPin(BSTR userPin, LONG* retVal)

{

unsigned char      bUserPin[9] = {0};

WideCharToMultiByte(CP_ACP, 0, userPin, SysStringLen(userPin), (char*)bUserPin, 9, NULL, NULL);

*retVal = S4VerifyPin(&g_ctx, bUserPin, 8, S4_USER_PIN);

return S_OK;

}

STDMETHODIMP CS4ActiveX::Close(LONG* retVal)

{

*retVal = S4Close(&g_ctx);

return S_OK;

}

至此,本篇博文连载完成,希望您通过阅读此系列博文后,可以了解如何在JavaScript以及Acticex之间相互传递数据的问题,当然,也希望您与我们进行互动,能够在此基础之上,再发掘出更好的方法!!!

(转)如何在JavaScript与ActiveX之间传递数据3的更多相关文章

  1. (转)如何在JavaScript与ActiveX之间传递数据2

    本文研究如何在JS等脚本语言与ActiveX控件之间通信,如何传递各种类型的参数,以及COM的IDispatch接口.使用类似的方法,可以推广到其他所有脚本型语言,如LUA,AutoCad等.本文将研 ...

  2. (转) 如何在JavaScript与ActiveX之间传递数据1

    本文研究如何在JS等脚本语言与ActiveX控件之间通信,如何传递各种类型的参数,以及COM的IDispatch接口.使用类似的方法,可以推广到其他所有脚本型语言,如LUA,AutoCad等.本文将研 ...

  3. 【MVC架构】——怎样利用Json在View和Controller之间传递数据

    在MVC架构中,尽管非常多东西和三层非常相似,可是也有非常大的差别.就比方传递数据.在三层架构中,传递数据就仅仅要一层返回,另外一层用同样类型的变量来接收即可了.在MVC中,事实上原理是一样的,Con ...

  4. Activity之间传递数据的方式及常见问题总结

    Activity之间传递数据一般通过以下几种方式实现: 1. 通过intent传递数据 2. 通过Application 3. 使用单例 4. 静态成员变量.(可以考虑 WeakReferences) ...

  5. Controller之间传递数据:属性传值

    在项目中,Controller之间传递数据非常之多,这里简单介绍一下属性传值.例如有FirstController 和 SecondController,数据从First传递到Second中,我们如何 ...

  6. Activity之间传递数据或数据包Bundle,传递对象,对象序列化,对象实现Parcelable接口

    package com.gaojinhua.android.activitymsg; import android.content.Intent; import android.os.Bundle; ...

  7. 28、activity之间传递数据&amp&semi;批量传递数据

    import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android ...

  8. 【Android 复习】 &colon; Activity之间传递数据的几种方式

    在Android开发中,我们通常需要在不同的Activity之间传递数据,下面我们就来总结一下在Activity之间数据传递的几种方式. 1. 使用Intent来传递数据 Intent表示意图,很多时 ...

  9. Android基础知识04—Activity活动之间传递数据

    ------活动之间传递数据------ 向下一个活动传递数据: Intent中提供了一系列的putExtra()方法,可以把数据暂存到Intent中,启动另一个活动的时候就可以取出来. 代码: (存 ...

随机推荐

  1. Underscore&period;js

    概述 Underscore.js是一个很精干的库,压缩后只有4KB.它提供了几十种函数式编程的方法,弥补了标准库的不足,大大方便了JavaScript的编程.MVC框架Backbone.js就将这个库 ...

  2. Bit-Coin收入的一分钱

    好吧,这是我在Slush's pool上对Bit-coin收入的第一分钱. 回想起来,2013年平安夜开始到今天,将近3个月没日没夜窝在这个矿里挖矿 从最开始的集成显卡挖,买了显卡挖,加了显卡挖,使用 ...

  3. Java-集合类汇总

    结构图: Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map ├Hashtable ├HashMap └WeakH ...

  4. &ast;&ast;&ast;mysql中经度纬度字段用什么存储&lpar;关于mysql的float和decimal区别&rpar;

    float,decimal精确度比较   float,double容易产生误差,对精确度要求比较高时,建议使用decimal来存,decimal在mysql内存是以字符串存储的, 用于定义货币要求精确 ...

  5. canvas实现钟表

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Leveldb Advanced

    [Slice] The return value of the it->key() and it->value() is a simple structure that contains ...

  7. samba服务简介

    1.1 Samba 概述Samba主要用于Windows和Linux之间的文件共享,也一样用于Linux和Linux之间的共享文件:不过对于Linux和Linux之间共享文件有更好的网络文件系统NFS ...

  8. selenium 学习笔记 ---新手学习记录(10) 问题总结(java)--poi--excel 操作

    1.当我使用poi想要操作xlsx时,报错,解决方法下载xmlbeans-2.6.0.jar架包,引入即可.点我下载 https://yunpan.cn/cSdVqp6e4v6Jk  访问密码 2c5 ...

  9. spring mvc接收JSON格式的参数

    1.配置spring解析json的库   <dependency>         <groupId>org.codehaus.jackson</groupId> ...

  10. ffmpeg架构和解码流程分析

    转 一,ffmpeg架构 1. 简介 FFmpeg是一个集录制.转换.音/视频编码解码功能为一体的完整的开源解决方案.FFmpeg的 开发是基于Linux操作系统,但是可以在大多数操作系统中编译和使用 ...