2009-07-13 2 views
1

Derzeit verwende ich MSAA, um ein IHTMLDocument2-Objekt von einem IE HWND zu erhalten. Bei einigen komplizierten Webanwendungen kann dieses IHTMLDocument2-Objekt jedoch mehrere IHTMLDocument2-Objekte enthalten, von denen einige nicht zur aktuellen Anzeigeseite, sondern zur vorherigen Seite gehören.So erhalten Sie das aktuellste IHTMLDocument2-Objekt aus dem IE-DOM

Es scheint mich, IE manchmal nicht sein DOM-Objekt refesh, aber halten mehr IHTMLDocument2 Objekt in seinen DOM hinzufügen. Meine Frage ist, wie kann ich das aktuelle IHTMLDocument2-Objekt aus dem DOM-Objekt abrufen.

Vielen Dank im Voraus

aktualisieren

Hallo Remy,

Vielen Dank für Ihre Antwort.

Ja, Sie haben Recht, ich verwende Frames, um zu anderen IHTMLDocument2-Objekten zu gelangen. Mein Verständnis ist, dass das IHTMLDocument2-Objekt, das ich von einem HWND bekomme, das oberste Objekt in seinem DOM ist. IE platziert manchmal die vorrausschauenden IHTMLDocument2 Objekte auch in einem der Frames.

Hier ist ein Teil meines Codes.

BOOL IESpy::GetHTMLText(CComPtr<IHTMLDocument2> 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->get_frames(&pFrames)) == S_OK){ 
      LONG framesCount; 
      pFrames->get_length(&framesCount); 
      if (framesCount > 0) { 
       for(long i=0; i < framesCount; i++) { 
        VARIANT varIdx; 
        varIdx.vt=VT_I4; 
        VARIANT varResult; 
        varIdx.lVal=i; 
        VariantInit(&varResult); 
        hr = pFrames->item(&varIdx, &varResult); 
        if (SUCCEEDED(hr) && (varResult.vt == VT_DISPATCH)){ 
         CComQIPtr<IHTMLWindow2> pFrameWnd; 
         CComQIPtr<IHTMLDocument2> pFrameDoc; 
         CComBSTR description=NULL; 
         pFrameWnd = varResult.pdispVal; 
         VariantClear(&varResult); 
         if (pFrameWnd == 0) { 
          continue; 
         } 
         hr = pFrameWnd->get_document(&pFrameDoc); 
         if (SUCCEEDED(hr) && pFrameDoc){ 
          GetHTMLText(pFrameDoc, tagNo, schNo); 
          if (m_foundText) { 
           break; 
          } 
         } else if (hr == E_ACCESSDENIED) { 
          CComQIPtr<IWebBrowser2> spBrws = HtmlWindowToHtmlWebBrowser(pFrameWnd); 
          if (spBrws != NULL) { 
           // Get the document object from the IWebBrowser2 object. 
           CComQIPtr<IDispatch> spDisp; 
           hr = spBrws->get_Document(&spDisp); 
           if (hr == S_OK) { 
            pFrameDoc = spDisp; 
            if (pFrameDoc) { 
             GetHTMLText(pFrameDoc, tagNo, schNo); 
             if (m_foundText) { 
              break; 
             } 
            } 
           } 
          } 
         } 
        } 
       } 
      } 

      pFrames->Release(); 

      if (!m_foundText) { 
       res = ReadSearchText(spDoc, tagNo, schNo); 
       doneSearch = TRUE; 
      } 
     } 
     if (!m_foundText && doneSearch == FALSE) { 
      res = ReadSearchText(spDoc, tagNo, schNo); 
     } 
    } 

    return res; 
} 

BOOL IESpy::ReadSearchText(CComPtr<IHTMLDocument2> spDoc, int tagNo, int schNo) 
{ 
    USES_CONVERSION; 

    HRESULT hr = NULL; 
    BOOL found = FALSE; 

    IHTMLElementCollection *pAll; 
    hr = spDoc->get_all(&pAll); 
    if (FAILED(hr)) { 
     return FALSE; 
    } 
    long items; 
    IDispatch *ppvDisp; 
    IHTMLElement *ppvElement; 
    pAll->get_length(&items); 

    std::wstring foundText = L""; 
    for (long j = 0; j < items; j++) { 
     VARIANT index; 
     index.vt = VT_I4; 
     index.lVal = j; 
     hr = pAll->item(index, index, &ppvDisp); 
     if (FAILED(hr)) { 
      return FALSE; 
     } 

     if (ppvDisp) { 
      ppvDisp->QueryInterface(IID_IHTMLElement, (void **)&ppvElement); 
      if (ppvElement) { 
       CComBSTR bstrTag; 
       ppvElement->get_tagName(&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->Release(); 
        if (found) { 
         BOOL stop = FALSE; 
         for (size_t i = 0; i < m_tagName[tagNo]->size(); i++) { 
          if (wcscmp(m_tagName[tagNo]->at(i).c_str(), L"HTML") == 0 
           || wcscmp(m_tagName[tagNo]->at(i).c_str(), L"HEAD") == 0 
           || wcscmp(m_tagName[tagNo]->at(i).c_str(), L"BODY") == 0) { 
           stop = TRUE; 
           break; 
          } 
         } 
         if (stop) { 
          break; 
         } 
        } 
       } else { 
        ppvElement->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; 
} 
+0

Wenn Sie bereits in Bearbeitung sind, warum sollten Sie MSAA hier verwenden? Iterieren Sie einfach die DOMs direkt. – EricLaw

Antwort

2

Ein IHTMLDocument2 kann nicht andere IHTMLDocument2 Objekte enthalten (es sei denn, sie auf der Seite Frames gehören), und schon gar nicht von den vorherigen Seiten. Wie bestimmen Sie das genau? Kannst du etwas Code zeigen?

Verwandte Themen