2012-02-24 3 views
1

javascriptからバイト配列を受け取って処理するActiveXコンポーネントがあります。私は、次のコードを書き、それがIE7 & 8のために働いていたが、IE 9で、それは私がのIDispatchを呼び出しながら::呼び出しは私が解決するのに助けてください失敗していることIDispatch :: IE9で動作しないJScript配列の_NewEnum

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; 


    } 

APと固定されています。うろこ2:

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; 
    } 
+0

どのラインに障害が発生しますか? 'HRESULT hr = pDisp-> Invoke'がエラーHRESULTを返す場合、渡されたオブジェクトが' For Each'構文をサポートしていないことを意味します。実際には、そのオブジェクト上で何が変わったのかを知ることです。**オブジェクトはどこから来ましたか?**あなたはjavascriptコードを投稿できますか? – Ben

+0

はいpDisp-> Invokeで失敗します。私はJavaScriptコード – Jeeva

+1

で質問を更新しました。試したIDispatchEx :: Invoke? –

答えて

2

あなたの問題について間違った診断があると思います。タイトルは次のとおりです。jscript9は配列オブジェクトのNewEnumをサポートしていません。私はそれを試していないが、IE9(jscript9.dll)ではJavaScript配列にSAFEARRAYもIEnumVeriantも他の配列構造も使用できません。 Javascript配列は、通常のIDispatchExオブジェクトです。個々の項目には、「0」、「1」、「2」としてアクセスできます。

エリックリペットから、次のポストは、JavaScriptの配列を説明していますあなたのC++コードでhttp://blogs.msdn.com/b/ericlippert/archive/2003/09/22/53061.aspx

、のIDispatchへのごpDispポインタは、以下の(最初の要素のための擬似コード)を行うと:

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

これは、非常にJavaScript'yものです。 VBScriptは完全に異なる構成(おそらくSAFEARRAY)をパスします。 pDisp-> GetTypeInfoの場合、pDispで取得しているものを正確に調べ、ITypeInfo :: GetTypeAttrを使用してそのタイプに関する情報を取得できます。 TYPEATTR.cVarsはプロパティの数を返し、GetVarDescは各変数に関する情報を返します。抽出できる「0」、「1」、「2」の変数がある間に、 'Length'または 'Count'または_NewEnum変数がないことを確認します。

+1

この質問に似ています(質問は異なりますが、回答は同じです)http://stackoverflow.com/questions/6562368/retrieve-javascript-array-object-with-c-using -dispid-newenum-fails-on-ie9 – Ben

関連する問題