Я размещаю элемент управления IWebBrowser2 в моей программе на C ++, используя только обычный Win32 (без mfc, atl, wtl и т. Д.). На DISPID_NAVIGATECOMPLETE2 я добавляю пользовательский объект для доступа из javascript, запущенного на отображаемой веб-странице.
Чтобы добавить пользовательский объект, я вызываю InvokeEx с DISPATCH_PROPERTYPUT и структуру DISPPARAMS с указателем на мой пользовательский объект.
Во время вызова InvokeEx вызывается функция AddRef моего пользовательского объекта, и я увеличиваю его счетчик ссылок. Но объект никогда не получает вызов своей функции Release, поэтому счетчик ссылок никогда не уменьшается до нуля.
Кто отвечает за вызов Release () после вызова AddRef () в InvokeEx?
РЕДАКТИРОВАТЬ: (добавить код)
Это код, который добавляет мой пользовательский объект в IHTMLWindow2. custObj
указывает на мой пользовательский объект
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, ¶ms, NULL, NULL, NULL);
Это объект, который я добавляю (некоторые частные члены были опущены для краткости)
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);
};
РЕДАКТИРОВАТЬ 2:
Теперь, когда кажется, что он работает так, как будто я решил поставить его на github.
https://github.com/Tobbe/CppIEEmbed. Пожалуйста, раскошелиться и улучшить, если вы можете:)