Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Javascript to Call C++ in Internet Explorer

I have seen this for BHO extensions, where the JavaScript can call functions in the C++ BHO. But lets say I am not using a BHO, instead I have a C++ console application that creates an IE COM object like so:

HRESULT hr = CoCreateInstance(
            CLSID_InternetExplorer,
            NULL,
            CLSCTX_LOCAL_SERVER,
            IID_IWebBrowser2,
            (void**)&_cBrowser);

I also have a class which "owns" the IWebBrowser2 object that comes back from this function.

class BrowserWrapper{
    public: 
        CComPtr<IWebBrowser2> pBrowser;

        void SomeFunction(...)
}

Is there a way to call a function like "SomeFunction" in the wrapper class from the JavaScript in the spawned IWebBrowser2 object?

like image 354
tt9 Avatar asked Apr 26 '16 00:04

tt9


1 Answers

You must implement the IDocHostUIHandler interface and set it to the web browser with a code similar to this (extracted from the doc):

ComPtr<IDispatch> spDocument;
hr = spWebBrowser2->get_Document(&spDocument);
if (SUCCEEDED(hr) && (spDocument != nullptr))
{
    // Request default handler from MSHTML client site
    ComPtr<IOleObject> spOleObject;
    if (SUCCEEDED(spDocument.As(&spOleObject)))
    {
        ComPtr<IOleClientSite> spClientSite;
        hr = spOleObject->GetClientSite(&spClientSite);
        if (SUCCEEDED(hr) && spClientSite)
        {
            // Save pointer for delegation to default 
            m_spDefaultDocHostUIHandler = spClientSite;
        }
    }

    // Set the new custom IDocHostUIHandler
    ComPtr<ICustomDoc> spCustomDoc;
    if (SUCCEEDED(spDocument.As(&spCustomDoc)))
    {
        // NOTE: spHandler is user-defined class
        spCustomDoc->SetUIHandler(spHandler.Get());
    }
} 

You must specifically implement the GetExternal method

Now, in IE's javascript (or vbscript for that matter), you can access your host with a call like this:

var ext = window.external; // this will call your host's IDocHostUIHandler.GetExternal method
ext.SomeFunction(...); // implemented by your object

What you return in GetExternal must be an IDispatch object that you can design the way you want.

like image 155
Simon Mourier Avatar answered Sep 19 '22 07:09

Simon Mourier