2011-07-03 1 views
1

suite à une similar question je lui ai répondu il y a quelque temps, je l'ai trouvé que lorsque vous essayez d'énumérer l'objet, en utilisant IDispatch::Invoke(DISPID_NEWENUM,...) échoue avec DISP_E_EXCEPTION sur IE9.
Cela se produit avec IDispatch et IDispatchEx, sur n'importe quel tableau javascript.javascript Récupérer objet tableau avec C++ en utilisant DISPID_NEWENUM échoue sur IE9

inutile de dire que le code fonctionne très bien sur IE6-IE8, et échoue uniquement sur IE9.

La même question apparaît également dans le MSDN dev forums sans aucune chance jusqu'à présent.

Voici un extrait de code pour illustrer ce que j'ai essayé de faire. Notez que pDispatch est la variante de tableau de javascript.

// invoke the object to retrieve the enumerator containing object 
CComVariant varResult; 

DISPPARAMS dispparamsNoArgs = {0}; 
EXCEPINFO excepInfo = {0}; 
UINT uiArgErr = (UINT)-1; // initialize to invalid arg 
HRESULT hr = pDispatch->Invoke(DISPID_NEWENUM, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD | DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, &excepInfo, &uiArgErr); 

// if failed - retry with IDispatchEX 
if (FAILED(hr)) 
{ 
    CComPtr<IDispatchEx> pDispatchEx; 
    pDispatchEx = pDispatch; // Implied query interface 

    hr = pDispatchEx->InvokeEx(DISPID_NEWENUM, LOCALE_USER_DEFAULT, DISPATCH_METHOD | DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, &excepInfo, NULL); 

    if (FAILED(hr)) 
     return false; 
} 

Est-ce que quelqu'un a une idée pourquoi ce code échoue toujours (IDispatch et IDispatchEx) avec HRESULT de DISP_E_EXCEPTION spécifiquement sur IE9?

Merci.

Répondre

1

IEnumVARIANT peut fonctionner. Bien que quand je l'ai essayé IEnumVARIANT :: Next retournait toujours E_FAIL, l'élément a été récupéré correctement. Je n'ai pas eu le temps ou le besoin d'aller au fond des choses. Cela a fonctionné pour moi, mais si ce n'était pas je devais utiliser IDispatchEx: lorsque les membres énumérés des objets de tableau passés par IE ils avaient tous "0", "1" etc., pas "longueur" méthode cependant, doit être dans son typeinfo, n'ont pas vérifié. Je pense que vous avez l'idée.

Désolé ne peut pas afficher le code pseudo ce site ne me permet pas sans suivre certaines règles de formatage spéciales

HTH

+0

voulez-vous dire que vous avez un objet IDispatch (comme un tableau javascript IE objet) et lorsque vous essayez de récupérer son interface IEnumVARIANT - vous avez réussi? parce que si vous utilisez IE9 - il devrait échouer. jetez un oeil sur le code dans mon message - avez-vous essayé la même méthode? merci –

+0

oui, QueryInterface sur IEnumVARIANT travaillé. Mon IE est 9.0.8112.16421 – edp

+0

Mon IE probablement expiré. Ne sera pas surpris s'il échoue dans les mises à jour ultérieures IE. IEnumVARIANT :: Next ou QueryInterface pour IEnumVARIANT doivent être corrigés. Pour le code de version, j'essayerais probablement d'utiliser pDipstacheEx-> GetDispID de "0", "1", etc., puis InvokeEx. – edp

3
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; 
} 
Questions connexes