locked
Crash with IE9 when trying to call IHTMLElementCollection->Item() RRS feed

  • Question

  • I have code similar to following code in my MFC application:

     

    CComQIPtr<MSHTML::IHTMLDocument2,         &MSHTML::IID_IHTMLDocument2>     pHtmlDocument2 (GetHtmlDocument ());
       CComQIPtr<MSHTML::IHTMLElementCollection, &MSHTML::IID_IHTMLElementCollection> pHtmlDocElements;
       CComQIPtr<MSHTML::IHTMLElementCollection, &MSHTML::IID_IHTMLElementCollection> pHtmlObjElements;
       //- check for empty document.
       if (pHtmlDocument2 == NULL)
    	   return;
       pHtmlDocument2->get_all (&pHtmlDocElements);
       pHtmlDocElements->tags (CComVariant ("object"), (IDispatch**) &pHtmlObjElements);
       if (pHtmlObjElements != NULL)
       {
          int ItemID    = 0;
          while (1)
          {
             CComQIPtr<IDispatch, &IID_IDispatch> pDispHtmlElement;
             pHtmlObjElements->item (CComVariant (ItemID), CComVariant (ItemID), &pDispHtmlElement); //THE APP CRASHES HERE
             if (pDispHtmlElement == NULL)
                break;
             //do something with the objects
          }
       }

    This code works fine with the HTML templates we use in the applicaton when having IE8.

    If we have IE9 installed on the system, then following statement in the above code causes exception (crash)

     pHtmlObjElements->item (CComVariant (ItemID), CComVariant (ItemID), &pDispHtmlElement); //THE APP CRASHES HERE

    The exception is

    Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

    Any help is appreciated.

    Thanks,

    Krushna Jhala

    Thursday, March 1, 2012 12:40 PM

Answers

  • Krushna Jhala wrote:

      CComQIPtr<MSHTML::IHTMLElementCollection,  &MSHTML::IID_IHTMLElementCollection> pHtmlObjElements;
      pHtmlDocElements->tags (CComVariant ("object"), (IDispatch**)  &pHtmlObjElements);

    You can't do it like this. You are effectively down-casting from  IDispatch to IHTMLElementCollection. Make it

    CComPtr<IDispatch> pTagsDisp;
    pHtmlDocElements->tags (CComVariant ("object"), &pTagsDisp);
    pHtmlObjElements = pTagsDisp;  // calls QueryInterface.


    Igor Tandetnik

    • Proposed as answer by Jesse Jiang Friday, March 2, 2012 2:43 AM
    • Marked as answer by Krushna Jhala Friday, March 2, 2012 10:12 AM
    Thursday, March 1, 2012 1:30 PM

All replies

  • Krushna Jhala wrote:

      CComQIPtr<MSHTML::IHTMLElementCollection,  &MSHTML::IID_IHTMLElementCollection> pHtmlObjElements;
      pHtmlDocElements->tags (CComVariant ("object"), (IDispatch**)  &pHtmlObjElements);

    You can't do it like this. You are effectively down-casting from  IDispatch to IHTMLElementCollection. Make it

    CComPtr<IDispatch> pTagsDisp;
    pHtmlDocElements->tags (CComVariant ("object"), &pTagsDisp);
    pHtmlObjElements = pTagsDisp;  // calls QueryInterface.


    Igor Tandetnik

    • Proposed as answer by Jesse Jiang Friday, March 2, 2012 2:43 AM
    • Marked as answer by Krushna Jhala Friday, March 2, 2012 10:12 AM
    Thursday, March 1, 2012 1:30 PM
  • Igor Tandetnik,

    Thanks for pointing out the issue... It worked.

    Thanks again for the help.

    Regards,

    Krushna

    Friday, March 2, 2012 10:14 AM