首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IDis补丁::调用_NewEnum在JScript阵列上不工作在IE9中

IDis补丁::调用_NewEnum在JScript阵列上不工作在IE9中
EN

Stack Overflow用户
提问于 2012-02-24 17:05:26
回答 1查看 1.4K关注 0票数 1

我有一个ActiveX组件,它从javascript接收字节数组并对其进行处理。我编写了以下代码,它适用于IE7 &8,但在IE9中,它在调用IDis修补程序时失败:请帮助我解决它

代码语言:javascript
复制
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脚本代码

代码语言:javascript
复制
<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>

此问题由下面的代码固定代码修复。

代码语言:javascript
复制
    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;


    }

Aprroach 2:

代码语言:javascript
复制
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;
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-02-25 04:53:17

我觉得你对你的问题做了错误的诊断。标题应该是: jscript9不支持数组对象的NewEnum。如果说有什么不同的话,我很惊讶它在以前的版本中适用于您--我没有尝试它,但是在IE9 (jscript9.dll) JavaScript数组上,既不能用SAFEARRAY,也不能用IEnumVeriant和任何其他数组构造来访问。Javascript数组只是普通的IDispatchEx对象。您可以以"0“、"1”和"2“的形式访问各个项目。

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

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

代码语言:javascript
复制
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,您可以准确地调查在pDisp上得到的信息,并使用ITypeInfo::GetTypeAttr获取有关类型的信息。TYPEATTR.cVars返回属性的数量,GetVarDesc返回关于每个变量的信息。验证没有‘长度’,‘计数’或_NewEnum变量,而有"0","1","2“变量,您可以提取。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9434930

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档