(急)ATL ActiveX 怎样传出自定义结构体数组给 js调用?顶也有分!

qinweima 2009-11-05 11:03:32

各位大哥大姐,问大家一个问题 :我在js 调用ATL的 ActiveX 里面的函数 ,希望获得 ActiveX 里面定义的一个结构体数组的数据。。现在有几个问题向大家求教:
1. 上述功能能不能实现?
2. ActiveX 里面代码要怎么样写,js里面要怎么样写?

先给100分,问题解决后再追加100分!谢谢大家!!!请知道的大哥大姐告诉小弟!谢谢。。
...全文
1643 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
duyinxia123 2012-08-11
  • 打赏
  • 举报
回复
从js向COM组件传递结构数组时,如果如果传递的数组中的值是用户在页面输入的,而不是像你说给出的列子在代码中直接赋值,该如何做呢?[Quote=引用 3 楼 的回复:]
这是从页面javascript向Com组件传递结构数组的代码
从COM组件向javascript组件传递数据也基本类似.是这个代码的逆过程


JScript code
// 页面脚本
var o = new ActiveXObject("TestATL.TestCom");
o.onstaTe=onState;
o.Put("array", {0: 123, 1: "abc"})……
[/Quote]
visualassist4680 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 tttyd 的回复:]

这是从页面javascript向Com组件传递结构数组的代码
从COM组件向javascript组件传递数据也基本类似.是这个代码的逆过程

JScript code
// 页面脚本
var o = new ActiveXObject("TestATL.TestCom");
o.onstaTe=onState;
o.Put("array", {0: 123, 1: "abc"});
o.……
[/Quote]
代码很完整,就是这样实现
ralphzmr 2010-05-05
  • 打赏
  • 举报
回复
function fillColorChange()
{

var data= AXSample.PutData();
var InCount = data.getItem(0);
alert(InCount);
var OutCount= data.getItem(1);
alert(OutCount);
var Name= data.getItem(2);
alert(Name);
}
请问我设了断点跟踪,程序可以进入 ActiveX中的 PutData,但就是再js中不能解析出:
alert(InCount);
alert(OutCount);
alert(Name);

谁帮我改改代码啊 !!
ralphzmr 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 qinweima 的回复:]

STDMETHODIMP CAXSampleCtl::PutData(VARIANT *val)
{

HRESULT hr;
SAFEARRAY *psaData = NULL;
SAFEARRAYBOUND saBound = {4,0};
MyData *pMyData = NULL;
psaData = Saf……
[/Quote]
wshcdr 2009-11-06
  • 打赏
  • 举报
回复
IDL中

interface ITest : IDispatch
{

[id(1), helpstring("method VBVars2")] HRESULT foo([in,out] SAFEARRAY(BYTE) *pSA);
};


声明
STDMETHOD(foo)(SAFEARRAY** pSA);

实现
STDMETHODIMP CWzd:: foo(SAFEARRAY** pSA)
{
// get input array
LPBYTE lpByte=NULL;
::SafeArrayAccessData(
*pSA,
(LPVOID*)&lpByte);
lpByte[0]=12;
lpByte[1]=34;
::SafeArrayUnaccessData(
*pSA);

return S_OK;
}

雪影 2009-11-05
  • 打赏
  • 举报
回复
例:假设你在COM组件中封装的数据是int InCount; int OutCount; char *Name;
data = AXSample.Data();
var InCount = data.getItem(0);
var OutCount= data.getItem(1);
var Name= data.getItem(2);
qinweima 2009-11-05
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 oyljerry 的回复:]
引用 8 楼 qinweima 的回复:
引用 6 楼 tr0j4n 的回复:
如楼上所说,讲结构体弄成一个数组传递

请问 typedef  struct 
  { 
  int  InCount; 
  int  OutCount; 
  char  *Name; 
  }MyData; 
的定义要再  .idl文件里吧?还要您能说说  HRESULT  PutData 怎么定义吗?


接口参数就用VARIANT等类型,只不过你在ActiveX中处理的时候,给VARIANT参数用CComSafeArray等来包装你的数组,然后JS中再讲VARIANT类型转换回VBArray等方式处理对应的数组》。。
[/Quote]

请问再 js里面怎么去解析 返回的数据
vae data = AXSample.PutData();//AXSample为ActiveX 对象。
怎么解析 data呢?
_JeffreyWu 2009-11-05
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 tr0j4n 的回复:]
不是啊,结构体干嘛定义idl里面,随你定义哪里,能用就好了,idl里面放个方法,访问一个结构体实例就好啦。
idl里面写一个返回VARIANT指针的方法就好了。putdata随便放,在你需要为结构体赋值的时候用

有了方法,返回VARIANT,Js就可以通过那个接口方法访问那个结构体实例了
[/Quote]

UP.
wshcdr 2009-11-05
  • 打赏
  • 举报
回复
UP
qinweima 2009-11-05
  • 打赏
  • 举报
回复
这样行吗 ??
HRESULT sendinf([out]VARIANT *datainf);
qinweima 2009-11-05
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 tr0j4n 的回复:]
不是啊,结构体干嘛定义idl里面,随你定义哪里,能用就好了,idl里面放个方法,访问一个结构体实例就好啦。
idl里面写一个返回VARIANT指针的方法就好了。putdata随便放,在你需要为结构体赋值的时候用

有了方法,返回VARIANT,Js就可以通过那个接口方法访问那个结构体实例了
[/Quote]

您能给我写个 idl里面写一个返回VARIANT指针的方法的 例子吗?就这写个函数的声明。。谢谢了
qinweima 2009-11-05
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 oyljerry 的回复:]
引用 8 楼 qinweima 的回复:


接口参数就用VARIANT等类型,只不过你在ActiveX中处理的时候,给VARIANT参数用CComSafeArray等来包装你的数组,然后JS中再讲VARIANT类型转换回VBArray等方式处理对应的数组》。。
[/Quote]

您在CSDN里面就这个问题回答了好多次!我看了好多回复。。。。有些地方还是不很明白。。谢谢大家的回复!!我好好分析分析大家的回答!!呵呵。。。
MoXiaoRab 2009-11-05
  • 打赏
  • 举报
回复
不是啊,结构体干嘛定义idl里面,随你定义哪里,能用就好了,idl里面放个方法,访问一个结构体实例就好啦。
idl里面写一个返回VARIANT指针的方法就好了。putdata随便放,在你需要为结构体赋值的时候用

有了方法,返回VARIANT,Js就可以通过那个接口方法访问那个结构体实例了
oyljerry 2009-11-05
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 qinweima 的回复:]
引用 6 楼 tr0j4n 的回复:
如楼上所说,讲结构体弄成一个数组传递

请问 typedef  struct 
  { 
  int  InCount; 
  int  OutCount; 
  char  *Name; 
  }MyData; 
的定义要再  .idl文件里吧?还要您能说说  HRESULT  PutData 怎么定义吗?

[/Quote]
接口参数就用VARIANT等类型,只不过你在ActiveX中处理的时候,给VARIANT参数用CComSafeArray等来包装你的数组,然后JS中再讲VARIANT类型转换回VBArray等方式处理对应的数组》。。
qinweima 2009-11-05
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 tr0j4n 的回复:]
如楼上所说,讲结构体弄成一个数组传递
[/Quote]
请问 typedef struct
{
int InCount;
int OutCount;
char *Name;
}MyData;
的定义要再 .idl文件里吧?还要您能说说 HRESULT PutData 怎么定义吗?
MoXiaoRab 2009-11-05
  • 打赏
  • 举报
回复
typedef   struct   
{
int InCount;
int OutCount;
char *Name;
}MyData;

//结构体包成variant
PutData(VARIANT *val)
{
HRESULT hr;
SAFEARRAY *psaData = NULL;
SAFEARRAYBOUND saBound = {4,0};
MyData *pMyData = NULL;

psaData = SafeArrayCreate(VT_VARIANT,1,&saBound);

hr = SafeArrayAccessData(psaData,reinterpret_cast<void **>(&pMyData));

pMyData[0].InCount = 8;
pMyData[0].OutCount = 2;
pMyData[0].Name = "LZY1";
pMyData[1].InCount = 11;
pMyData[1].OutCount = 5;
pMyData[1].Name = "LZY2";
pMyData[2].InCount = 13;
pMyData[2].OutCount = 4;
pMyData[2].Name = "LZY3";
pMyData[3].InCount = 15;
pMyData[3].OutCount = 1;
pMyData[3].Name = "LZY4";

hr = SafeArrayUnaccessData(psaData);

(*val).vt = VT_ARRAY;
(*val).parray = psaData;
}


JS调用的时候,变通下就可以了吧
MoXiaoRab 2009-11-05
  • 打赏
  • 举报
回复
如楼上所说,讲结构体弄成一个数组传递
qinweima 2009-11-05
  • 打赏
  • 举报
回复
谢谢楼上的哥哥。。。。。我好好看看!!希望其他的大哥也积极发言啊 !呵呵。。大家都有分的!不够我追加!!关键是小弟太菜了。。这块才开始搞,能直接提供个 js获取 ActiveX 自定义对象的数据的例子就更好了!呵呵。。再次感谢楼上的大侠!
雪影 2009-11-05
  • 打赏
  • 举报
回复
这里有详细的代码
http://topic.csdn.net/t/20021024/16/1122084.html

基本思想就是将数字封装成VARIANT数组,然后传递给Javascript
雪影 2009-11-05
  • 打赏
  • 举报
回复
这是从页面javascript向Com组件传递结构数组的代码
从COM组件向javascript组件传递数据也基本类似.是这个代码的逆过程

// 页面脚本
var o = new ActiveXObject("TestATL.TestCom");
o.onstaTe=onState;
o.Put("array", {0: 123, 1: "abc"});
o.Put("array", [456, "def"]);
o.Put("array", [{name: "tom", age: 8}, {name: "jack", age: 10}]);
var a = new Array(789, "ghi"); // has "length" property
o.Put("array", a);


// Com组件VC7.1 ATL代码
STDMETHODIMP CTestCom::Put(BSTR key, VARIANT value)
{
WCHAR output[4096] = L"";
if(0 == wcsicmp(key, L"array") && VT_DISPATCH == value.vt)
{
IDispatchPtr spDisp = value.pdispVal;
DISPID dispID = 0;
DISPPARAMS dispParams = {NULL, NULL, 0, 0};
CComVariant result;
EXCEPINFO excepInfo;
memset(&excepInfo, 0, sizeof excepInfo);
UINT nArgErr = (UINT)-1; // initialize to invalid arg
unsigned int length = 0; // 数组长度 或 属性 个数

LPOLESTR func = L"length";
HRESULT hr = spDisp->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
if(S_OK == hr){ // 如果有"length"属性
hr = spDisp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
if(S_OK == hr && VT_I4 == result.vt)
length = result.intVal; // 直接读取数组长度
}else{
unsigned int nTypeInfo = 0;
hr = spDisp->GetTypeInfoCount(&nTypeInfo);
ATLASSERT(1 == nTypeInfo);
ITypeInfoPtr spTypeInfo;
hr = spDisp->GetTypeInfo(0, 0, &spTypeInfo);
TYPEATTR *pTypeAttr = NULL;
hr = spTypeInfo->GetTypeAttr(&pTypeAttr);
//ATLASSERT("{C59C6B12-F6C1-11CF-8835-00A0C911E8B2}" == pTypeAttr->guid); // JScript:
length = pTypeAttr->cVars; // 从类型信息读取数组长度
spTypeInfo->ReleaseTypeAttr(pTypeAttr);
}
for(unsigned int i=0; i<length; i++)
{
WCHAR buf[32];
_itow(i, buf, 10);
func = buf;
hr = spDisp->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
hr = spDisp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
if(S_OK != hr)
continue;
if(VT_DISPATCH == result.vt){
IDispatchPtr spItem = result.pdispVal;
func = L"name";
hr = spItem->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
hr = spItem->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
if(S_OK == hr && VT_BSTR == result.vt)
swprintf(output + wcslen(output), L"name=%s", result.bstrVal);
func = L"age";
hr = spItem->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
hr = spItem->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
if(S_OK == hr && VT_I4 == result.vt)
swprintf(output + wcslen(output), L" age=%d\n", result.intVal);
}else if(VT_BSTR == result.vt)
swprintf(output + wcslen(output), L"BSTR:%s\n", result.bstrVal);
else if(VT_I4 == result.vt)
swprintf(output + wcslen(output), L"I4:%d\n", result.intVal);
else
swprintf(output + wcslen(output), L"item.vt=%d\n", result.vt);
}
}
FireStateEvent(output);
return S_OK;
}
加载更多回复(17)

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧