BHO 在每个页面上执行 JavaScript

BHO Execute JavaScript on every page

本文关键字:执行 JavaScript BHO      更新时间:2023-10-16

我是Internet Explorer(BHO)的写入扩展。我读了很多问题,答案,但找不到和理解,如何使从每个页面上的资源执行Javascript文件?不附加网页,需要在每个页面上执行必要的JS。

我知道,我需要在 OnDocumentComplete 之后执行,但我不知道,如何在C++中做到这一点......我找到了这个扩展,但它是用 C# 编写的,我无法将其转换为 C++。

https://github.com/dvdotsenko/livereload_ie_extension

我在C++中举了 BHO 示例:http://www.codeproject.com/Articles/37044/Writing-a-BHO-in-Plain-C

你能帮我在每个页面上从资源中添加执行 JavaScript 吗?

您正在寻找 IHTMLWindow2::execScript。

您可以通过执行以下操作来获取IHTMLDocument2指针:

  1. 呼叫IWebBrowser2::get_Document() .
  2. QueryInterface() 生成的 IDispatch IID_IHTMLDocument2 指针。

您应该能够通过在IHTMLDocument2对象上调用get_parentWindow并执行类似的舞蹈来获取 IHTMLWindow2 指针。

下面是一些示例函数。 您必须实现IObjectWithSite并缓存站点指针。 您可以将其传递给这些函数。

HRESULT Web2FromSite(IUnknown *punkSite, IWebBrowser2 **pWeb2) {
    IServiceProvider* psp;
    HRESULT hr = punkSite->QueryInterface(IID_IServiceProvider, (void **)&psp);
    if (SUCCEEDED(hr))
    {
        hr = psp->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, (void **)pWeb2);
        psp->Release();
    }
    return hr;
}
HRESULT Doc2FromWeb2(IWebBrowser2 *pWeb2, IHTMLDocument2 **ppDoc2) {
    CComPtr<IDispatch> spDisp;
    HRESULT hr = pWeb2->get_Document(&spDisp);
    if (SUCCEEDED(hr) && spDisp)
    {
        hr = spDisp->QueryInterface(IID_IHTMLDocument2, (void**)ppDoc2);
    } else {
        hr = E_FAIL;
    }
    return hr;
}
HRESULT Doc2FromSite(IUnknown *punkSite, IHTMLDocument2 **ppDoc2) {
    CComPtr<IWebBrowser2> spWeb2;
    HRESULT hr = Web2FromSite(punkSite, &spWeb2);
    if (SUCCEEDED(hr)) {
        hr = Doc2FromWeb2(spWeb2, ppDoc2);
    }
    return hr;
}
我想

你已经有一个正在运行的BHO,并且它处理OnDocumentComplete。我还假设您对 OnDocumentComplete 的处理会为您提供一个 IWebBrowser2 接口指针。如果不是这种情况,请告诉我。

警告:错误检查"完美"。

HRESULT ExecScriptOnDocComplete(  CComPtr<IWebBrowser2> & spIWebBrowser2, BSTR bstrScriptToExec ) {
    // get the IHTMLDocument2
    CComPtr<IDispatch> spIDispatchDocument;
    HRESULT hr = spIWebBrowser2->get_Document( &spIDispatchDocument );
    if ( FAILED( hr ) ) return hr;
    CComPtr<IHTMLDocument2> spIHTMLDocument2;
    hr = spIDispatchDocument.QueryInterface<IHTMLDocument2>( &spIHTMLDocument2 );
    if ( FAILED( hr ) ) return hr;
    // get the IHTMLWindow2
    CComPtr<IHTMLWindow2> spIHTMLWindow2;
    hr = spIHTMLDocument2->get_parentWindow( &spIHTMLWindow2 );
    if ( FAILED( hr ) ) return hr;
    // Execute the script
    CComVariant ccomvariantRetVal;
    hr = spIHTMLWindow2->execScript( bstrScriptToExec, CComBSTR( L"JavaScript" ), &ccomvariantRetVal );
    return hr;
}