3,248
社区成员




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;
}
// 页面脚本
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;
}