Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
309 views
in Technique[技术] by (71.8m points)

c# - Accessing data in a Frame or Iframe with IE plugin Browser Helper Object (BHO)

I am writing an IE plugin that wrap phone numbers in a link that connects to a phone system and dials that number when clicked. I am accomplishing this by using DocumentComplete event.

//using SHDocVw.WebBrowser
webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);

The problem is I cannot seem to access elements inside of frame and iframe elements.

Question: How do you manipulate data inside frame and iframe elements in IE using a Browser Helper Object?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First, some caveats. Generally speaking, add-ons of this nature (e.g. those that run on all pages and scan all content) have a major performance impact and are likely to result in users removing or disabling the add-on when they see the performance impact it entails. It further appears that you're writing your code in .NET, which is also strongly discouraged due to the performance impact.

Getting the contents of a cross-domain subframe is non-trivial because you will get an Access Denied by default. The reason is that the cross-domain security restriction that exists for JavaScript is also applied when your add-on attempts to get the cross-domain content.

To get the cross-domain content from the top-level page, you must jump through some hoops which are non-trivial, particularly in .NET. Your best bet is to just run your code on each frame's DocumentComplete event, as Jeff observed.

If you must run your code only once, from the top-level page, then you can do so with a technique like this one:

http://support.microsoft.com/default.aspx?scid=kb;en-us;196340

// &lpDocDisp is the dispatch pointer for the document
IHTMLDocument2* pDocument;
HRESULT hr = lpDocDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDocument);
if (FAILED(hr))
    return hr;

long iCount = 0;

// Now, check for subframes
// http://support.microsoft.com/default.aspx?scid=kb;en-us;196340
IOleContainer* pContainer;

// Get the container
hr = lpDocDisp->QueryInterface(IID_IOleContainer, (void**)&pContainer);
if (FAILED(hr) || (NULL == pContainer)){
    OutputDebugString("[AXHUNTER] Failed to get container
");
    return hr;
}

LPENUMUNKNOWN  pEnumerator;

// Get an enumerator for the frames
hr = pContainer->EnumObjects(OLECONTF_EMBEDDINGS, &pEnumerator);
pContainer->Release();

if (FAILED(hr) || (NULL == pEnumerator)){
    OutputDebugString("[AXHUNTER] Failed to get enumerator
");                 
    return hr;
}

IUnknown* pUnk;
ULONG uFetched;

// Enumerate all the frames
for (UINT i = 0; S_OK == pEnumerator->Next(1, &pUnk, &uFetched); i++)
{
    assert(NULL != pUnk);
    IWebBrowser2* pBrowser;
    hr = pUnk->QueryInterface(IID_IWebBrowser2, (void**)&pBrowser);
    pUnk->Release();

    if (SUCCEEDED(hr))
    {
        LPDISPATCH pSubDoc = NULL;
        hr = pBrowser->get_Document(&pSubDoc);
        if (SUCCEEDED(hr) && (NULL != pSubDoc)){
            CrawlPage(pSubDoc, ++iNested);
            pSubDoc->Release();
        }

        pBrowser->Release();
    }
    else
    {
        OutputDebugString("[AXHUNTER] Cannot get IWebBrowser2 interface
");
    }
}


pEnumerator->Release();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...