Question

I'm hosting an IWebBrowser2 control in my C++ program using nothing but plain Win32 (no mfc, atl, wtl etc). On DISPID_NAVIGATECOMPLETE2 I add a custom object to be accessed from javascript running on the displayed webpage.

To add the custom object I call InvokeEx with DISPATCH_PROPERTYPUT and a DISPPARAMS structure with a pointer to my custom object.

During the call to InvokeEx the AddRef function of my custom object is called and I increment its reference counter. But the object never gets a call to its Release function, so the reference counter never decreases down to zero again.

Who is responsible for calling Release() after AddRef() has been called in InvokeEx?

EDIT: (Adding some code)

This is the code that adds my custom object to the IHTMLWindow2. custObj points to my custom object

IHTMLWindow2 *win = NULL;
GetDoc()->get_parentWindow(&win);
IDispatchEx *winEx = NULL;
win->QueryInterface(&winEx);

DISPID dispid;
HRESULT hr = winEx->GetDispID(objName, fdexNameEnsure, &dispid); //objName is "JSObject"

DISPID namedArgs[] = {DISPID_PROPERTYPUT};
DISPPARAMS params;
params.rgvarg = new VARIANT[1];
params.rgvarg[0].pdispVal = custObj;
params.rgvarg[0].vt = VT_DISPATCH;
params.rgdispidNamedArgs = namedArgs;
params.cArgs = 1;
params.cNamedArgs = 1;

hr = winEx->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL); 

This is the object that I'm adding (some private members have been left out for brevity)

class JSObject : public IDispatch {
private:
    long ref;
public:
    JSObject();

    // IUnknown
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv);
    virtual ULONG STDMETHODCALLTYPE AddRef();
    virtual ULONG STDMETHODCALLTYPE Release();

    // IDispatch
    virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo);
    virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid,
        ITypeInfo **ppTInfo);
    virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid,
        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId);
    virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid,
        LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
        EXCEPINFO *pExcepInfo, UINT *puArgErr);
};

EDIT 2:

Now that it seems to be working like it should I decided to put it on github.

https://github.com/Tobbe/CppIEEmbed. Please fork and improve if you can :)

Was it helpful?

Solution

Well, you are assigning a property, aren't you? As long as this property exists and refers to your object, it will have a reference added.

If you want the remote object to release your reference you should assign NULL to the property, or some other object.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top