Exposing methods to JS on a CAxWindow from a BHO (

2019-09-06 01:55发布

问题:

I have this BHO which I successfully exposed method to JS from it using this thread: Calling BHO method from Javascript?.

When I open a CAxWindow in order to host HTML docs, I'd like to use this exported method but it seems that it doesn't work for that window as well.

I tried to make a custom class like:

class Bubble: 
public CAxWindow, 
public IDispEventImpl<1, Bubble, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 0>
{
public:

    BEGIN_SINK_MAP(Bubble)
        SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE , OnDocumentComplete) 
        SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOWNLOADCOMPLETE , OnDownloadComplete)
        SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, BeforeNavigate2)
        SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_ONQUIT, OnQuit)
        SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_NAVIGATEERROR, NavigateError)           
        SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_NAVIGATECOMPLETE2 , OnNavigateComplete2)
    END_SINK_MAP()

To try repeat the process of exposing the methods on document complete but it seems that the event is not being fired.

So basically my question is: is there anyway to expose methods to js on my CAxWindow?

Many thanks!

回答1:

IDispEventImpl implements sink interface to handle event methods calls. You cannot extend it with your own additional methods directly. Additionally, JavaScript does not really see this interface from scripting code because it is connected to ActiveX control site, not the scripting engine. IDispEventImpl is at all a simplified implementation of IDispatch COM interface, reference counter free, suitable for event IDispatch::Invoke call on the connection point sink interface.

You need to either implement a type library enabled COM object with IDispatch interface (type library is used by scripting engine to discover actual methods), or custom IDispatch or IDispatchEx interface implementation (yes, this can be implemented directly on CAxWindow class as additional base class/interface) handling method name resolution without type library. Then you will pass this object to the scripting engine as external object or otherwise.