gpt4 book ai didi

javascript - IDispatch::Invoke _NewEnum 在 JScript 数组上无法在 IE9 中工作

转载 作者:行者123 更新时间:2023-11-30 18:31:50 27 4
gpt4 key购买 nike

我有一个 ActiveX 组件,它从 javascript 接收字节数组并处理它。我编写了以下代码,它适用于 IE7 和 8,但在 IE 9 中,当我调用 IDispatch::Invoke 时它失败了,请帮助我解决它

if(pszBufData->vt == VT_DISPATCH)
{
BYTE * pData = new BYTE[dwSize];

IDispatch *pDisp = pszBufData->pdispVal;
pDisp->AddRef();

DISPPARAMS dispparamsNoArgs = { NULL, NULL, 0, 0 };

VARIANT var;
VariantInit(&var);

HRESULT hr = pDisp->Invoke(DISPID_NEWENUM, IID_NULL, GetUserDefaultLCID(), DISPATCH_PROPERTYGET, &dispparamsNoArgs, &var, NULL, NULL);


int i=0;
if (SUCCEEDED(hr))
{

if (var.vt == VT_UNKNOWN)
{
IEnumVARIANT *pEnum = NULL;
if SUCCEEDED(var.punkVal->QueryInterface(IID_IEnumVARIANT, (void**) &pEnum))
{
VARIANT item;
VariantInit(&item);

pEnum->Reset();
while ( (pEnum->Next(1, &item, NULL) && S_FALSE) != S_FALSE)
{
if (item.vt == VT_I4)
{
//AfxMessageBox(_T("SendData"));
pData[i] = item.cVal;
i++;
}
VariantClear(&item);
}
pEnum->Release();
}
var.punkVal->Release();
}
}

/*VariantClear(&var);*/
pDisp->Release();


}

java脚本代码

<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript" FOR="window" EVENT="onLoad()">
<!--

var arr = new Array(0x1, 0xA,0x20)

//CSDS_Communication1.ConfigCon("COM1",9600)

CSDS_Communication1.SendData("COM1",arr,3)


-->
</SCRIPT>
<TITLE>New Page</TITLE>
</HEAD>
<BODY>
<OBJECT ID="CSDS_Communication1" WIDTH=100 HEIGHT=51
CLASSID="CLSID:73D79990-090E-48CB-8857-E6BF50F42E63">
<PARAM NAME="_Version" VALUE="65536">
<PARAM NAME="_ExtentX" VALUE="2646">
<PARAM NAME="_ExtentY" VALUE="1323">
<PARAM NAME="_StockProps" VALUE="0">
</OBJECT>
</BODY>
</HTML>

问题已通过以下代码修复固定代码

    BYTE * pData = new BYTE[dwSize];

/* retrieving IDispatch */
IDispatch *disp = pszBufData->pdispVal;
if (pszBufData->vt & VT_BYREF)
disp = *(pszBufData->ppdispVal);

/* getting array's length */
DISPPARAMS params;
FillMemory(&params, sizeof(DISPPARAMS), 0);
VARIANT res;

DISPID dl = 0;
LPOLESTR ln = L"length";
HRESULT hr = disp->GetIDsOfNames(IID_NULL, &ln, 1, LOCALE_USER_DEFAULT, &dl);
if (FAILED(hr))
return false;

// get the number of elements using the DISPID of length parameter

hr =disp->Invoke(dl, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,&params, &res, NULL, NULL);
if (FAILED(hr))
return false;


VARIANT len1;
VariantInit(&len1);

VariantChangeType(&len1, &res, 0, VT_I4);

LONG len = len1.lVal;

/* summing elements */

for (int i = 0; i < len; i++)
{
std::wstring strIndex;// = StringUtils::IntToString(i);

wchar_t buf[8];
_itow(i,buf,10);
strIndex.append(buf);

DISPID dispid;

LPOLESTR pIndex = reinterpret_cast<LPOLESTR>(const_cast<WCHAR *>(strIndex.data()));


hr = disp->GetIDsOfNames( IID_NULL, &pIndex, 1, LOCALE_USER_DEFAULT, &dispid );
if (FAILED(hr))
continue;


/*std::stringstream ss;
ss << ind =" CComBSTR(ss.str().c_str());">GetIDsOfNames(IID_NULL, &ind, 1, LOCALE_USER_DEFAULT, &dispid));*/
hr = disp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &params, &res, NULL, NULL);
if (FAILED(hr))
continue;

VARIANT val1;
VariantInit(&val1);

VariantChangeType(&val1, &res, 0, VT_I4);

pData[i] = val1.lVal;


}

方法二:

IDispatch *disp = pszBufData->pdispVal;
if (pszBufData->vt & VT_BYREF)
disp = *(pszBufData->ppdispVal);

// Get IDispatchEx on input IDispatch
CComQIPtr<IDispatchEx> pdispexArray(disp);
if ( ! pdispexArray )
return E_NOINTERFACE;

// Get array length DISPID
DISPID dispidLength;
CComBSTR bstrLength(L"length");
HRESULT hr = pdispexArray->GetDispID(bstrLength, fdexNameCaseSensitive, &dispidLength);
if (FAILED(hr))
return false;

// Get length value using InvokeEx()
CComVariant varLength;
DISPPARAMS dispParamsNoArgs = {0};
hr = pdispexArray->InvokeEx(dispidLength, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParamsNoArgs, &varLength,
NULL, NULL);
if (FAILED(hr))
return hr;

ATLASSERT(varLength.vt == VT_I4);
const int count = varLength.intVal;

BYTE * pData = new BYTE[count];

// For each element in source array:
for (int i = 0; i < count; i++)
{
CString strIndex;
strIndex.Format(L"%d", i);

// Convert to BSTR, as GetDispID() wants BSTR's
CComBSTR bstrIndex(strIndex);
DISPID dispidIndex;
hr = pdispexArray->GetDispID(bstrIndex, fdexNameCaseSensitive, &dispidIndex);
if (FAILED(hr))
break;

// Get array item value using InvokeEx()
CComVariant varItem;
hr = pdispexArray->InvokeEx(dispidIndex, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParamsNoArgs, &varItem,
NULL, NULL);
if (FAILED(hr))
break;

ATLASSERT(varItem.vt == VT_I4);

pData[i] = varItem.intVal;
}

最佳答案

我认为您对问题的诊断有误。标题应该是:jscript9 不支持数组对象的 NewEnum。如果有的话,我很惊讶它在以前的版本上对你有用——我没有尝试过,但是在 IE9 (jscript9.dll) 上,既不能使用 SAFEARRAY 也不能使用 IEnumVeriant 和任何其他数组构造访问 JavaScript 数组。 Javascript 数组只不过是常规的 IDispatchEx 对象。您可以访问单个项目作为“0”、“1”和“2”。

Eric Lippert 的以下帖子解释了 JavaScript 数组:http://blogs.msdn.com/b/ericlippert/archive/2003/09/22/53061.aspx

在您的 C++ 代码中,使用指向 IDispatch 的 pDisp 指针执行以下操作(第一个元素的伪代码):

DISPID dispid;
wchar_t name[] = L"0";
pDisp->GetIDsOfNames( IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid );
pDisp->Invoke( dispid, ... );

这是非常 JavaScript 的东西。 VBScript 将传递一个完全不同的构造(可能是 SAFEARRAY)。如果您使用 pDisp->GetTypeInfo 并使用 ITypeInfo::GetTypeAttr 来获取有关类型的信息,您可以准确地调查您在 pDisp 中获得的内容。 TYPEATTR.cVars 返回属性的数量,GetVarDesc 返回关于每个变量的信息。验证没有“长度”或“计数”或 _NewEnum 变量,同时有“0”、“1”、“2”变量可以提取。

关于javascript - IDispatch::Invoke _NewEnum 在 JScript 数组上无法在 IE9 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9434930/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com