현재 MSAA를 사용하여 IE HWND에서 IHTMLDocument2 개체를 가져옵니다. 그러나 일부 복잡한 웹 응용 프로그램에서는이 IHTMLDocument2 개체가 여러 IHTMLDocument2 개체를 포함 할 수 있으며 그 중 일부는 현재 표시되는 페이지가 아니라 이전 페이지에 속합니다.IE DOM에서 가장 최신 IHTMLDocument2 개체를 얻는 방법
IE의 경우 DOM 개체를 다시 채우지 않지만 DOM에 더 많은 IHTMLDocument2 개체를 계속 추가하는 경우가 있습니다. 내 질문에 어떻게 DOM 개체에서 현재 표시 IHTMLDocument2 개체를 얻을 수 있습니다. 사전
업데이트
안녕하세요 레미의
감사합니다, 귀하의 답변에 대한
감사합니다.
네, 그렇습니다. 프레임을 사용하여 다른 IHTMLDocument2 개체를 가져옵니다. 내가 이해 한 것은 HWND에서 가져온 IHTMLDocument2 객체가 DOM의 최상위 객체라는 것이다. IE는 때로는 선행 IHTMLDocument2 객체를 프레임 중 하나에 넣습니다.
여기 내 코드의 일부입니다.
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;
}
이미 진행중인 경우 여기에서 MSAA를 사용하고 싶습니다. DOM을 직접 반복하면됩니다. – EricLaw