title: How to get the most current IHTMLDocument2 object from IE DOM
body: <p>Currently, I use MSAA to get an IHTMLDocument2 object from a IE HWND. However, with some complicated web applications, this IHTMLDocument2 object may contain several IHTMLDocument2 objects, some of them are not belong to the current displaying page, but the previous page. </p>
  
  <p>It seems to me, IE sometimes doesn't refesh its DOM object, but keep adding more IHTMLDocument2 object into its DOM. My question is how can I get the current displaying IHTMLDocument2 object from the DOM object.</p>
  
  <p>Thanks in advance</p>
  
  <p><strong>Update</strong></p>
  
  <p>Hi Remy,</p>
  
  <p>Thanks for your answer. </p>
  
  <p>Yes, you are right, I do use frames to get to other IHTMLDocument2 objects. My understanding is that the IHTMLDocument2 object that I get from a HWND is the top object in its DOM. IE sometimes puts the prevous IHTMLDocument2 objects inside one of the frames as well.</p>
  
  <p>Here is part of my code.</p>
  
  <pre><code>BOOL IESpy::GetHTMLText( CComPtr&lt;IHTMLDocument2&gt; spDoc, int tagNo, int schNo)
  {
      USES_CONVERSION;
  
      HRESULT hr = NULL;
      BOOL res = TRUE;
      BOOL doneSearch = FALSE;
  
      // Extract the source code of the document
      if (spDoc) {
          IHTMLFramesCollection2* pFrames = NULL;
          if (hr = (spDoc-&gt;get_frames(&amp;pFrames)) == S_OK){  
              LONG framesCount;
              pFrames-&gt;get_length(&amp;framesCount);
              if (framesCount &gt; 0) {
                  for( long i=0; i &lt; framesCount; i++) {
                      VARIANT varIdx; 
                      varIdx.vt=VT_I4;
                      VARIANT varResult;
                      varIdx.lVal=i;
                      VariantInit(&amp;varResult);
                      hr = pFrames-&gt;item(&amp;varIdx, &amp;varResult);
                      if (SUCCEEDED(hr) &amp;&amp; (varResult.vt == VT_DISPATCH)){
                          CComQIPtr&lt;IHTMLWindow2&gt; pFrameWnd;
                          CComQIPtr&lt;IHTMLDocument2&gt; pFrameDoc;
                          CComBSTR description=NULL;
                          pFrameWnd = varResult.pdispVal;
                          VariantClear(&amp;varResult);
                          if (pFrameWnd == 0) {
                              continue;
                          }
                          hr = pFrameWnd-&gt;get_document(&amp;pFrameDoc);
                          if (SUCCEEDED(hr) &amp;&amp; pFrameDoc){
                              GetHTMLText( pFrameDoc, tagNo, schNo );
                              if ( m_foundText ) {
                                  break;
                              }
                          } else if ( hr == E_ACCESSDENIED ) {
                              CComQIPtr&lt;IWebBrowser2&gt; spBrws = HtmlWindowToHtmlWebBrowser(pFrameWnd);
                              if ( spBrws != NULL) {
                                  // Get the document object from the IWebBrowser2 object.
                                  CComQIPtr&lt;IDispatch&gt; spDisp;
                                  hr = spBrws-&gt;get_Document(&amp;spDisp);
                                  if ( hr == S_OK ) {
                                      pFrameDoc = spDisp;
                                      if ( pFrameDoc ) {
                                          GetHTMLText( pFrameDoc, tagNo, schNo );
                                          if ( m_foundText ) {
                                              break;
                                          }
                                      }
                                  }
                              }
                          }
                      }
                  }
              }
  
              pFrames-&gt;Release();
  
              if ( !m_foundText ) {
                  res = ReadSearchText(spDoc, tagNo, schNo );
                  doneSearch = TRUE;
              }
          }
          if ( !m_foundText &amp;&amp; doneSearch == FALSE ) {
              res = ReadSearchText(spDoc, tagNo, schNo );
          }
      }
  
      return res;
  }
  
  BOOL IESpy::ReadSearchText(CComPtr&lt;IHTMLDocument2&gt; spDoc, int tagNo, int schNo )
  {
      USES_CONVERSION;
  
      HRESULT hr = NULL;
      BOOL found = FALSE;
  
      IHTMLElementCollection *pAll;
      hr = spDoc-&gt;get_all(&amp;pAll); 
      if (FAILED(hr))  {
          return FALSE;
      }
      long items;
      IDispatch *ppvDisp;
      IHTMLElement *ppvElement;
      pAll-&gt;get_length(&amp;items);
  
      std::wstring foundText = L"";
      for ( long j = 0; j &lt; items; j++ ) {
          VARIANT index;
          index.vt = VT_I4;
          index.lVal = j;
          hr = pAll-&gt;item( index, index, &amp;ppvDisp );
          if (FAILED(hr))  {
              return FALSE;
          }
  
          if ( ppvDisp ) {
              ppvDisp-&gt;QueryInterface(IID_IHTMLElement, (void **)&amp;ppvElement);
              if ( ppvElement ) { 
                  CComBSTR bstrTag;
                  ppvElement-&gt;get_tagName(&amp;bstrTag);
                  wchar_t *wtemp = OLE2W(bstrTag);    
                  if ( wtemp ) {
                      std::wstring text = ReadSearchText(ppvElement, wtemp, tagNo, schNo, found);
                      if ( !text.empty() ) {
                          if ( !foundText.empty() ) {
                              foundText += concat_string;
                          }
                          foundText += text;
                      }
                      ppvElement-&gt;Release();
                      if ( found ) {
                          BOOL stop = FALSE;
                          for ( size_t i = 0; i &lt; m_tagName[tagNo]-&gt;size(); i++ ) {
                              if ( wcscmp(m_tagName[tagNo]-&gt;at(i).c_str(), L"HTML") == 0 
                                  || wcscmp(m_tagName[tagNo]-&gt;at(i).c_str(), L"HEAD") == 0 
                                  || wcscmp(m_tagName[tagNo]-&gt;at(i).c_str(), L"BODY") == 0 ) {
                                  stop = TRUE;
                                  break;
                              }
                          }
                          if ( stop ) {
                              break;
                          }
                      }
                  } else {
                      ppvElement-&gt;Release();
                  }
              }
          }
      }
  
      if ( !foundText.empty() ) {
          if ( m_screenCompare ) {
          //  long timeStamp = GetHPTimeStamp(spDoc);
          //  m_temp_results[timeStamp] = foundText;
              m_temp_results.push_back(foundText);
          } else {
              m_result += foundText;
              m_result += L" ";
              m_foundText = TRUE;
          }
      }
  
      return TRUE;
  }
  </code></pre>