J'héberge un contrôle IWebBrowser2 dans mon programme C++ en utilisant simplement Win32 (pas de mfc, atl, wtl etc.). Sur DISPID_NAVIGATECOMPLETE2, j'ajoute un objet personnalisé accessible à partir de javascript exécuté sur la page Web affichée.Pourquoi toutes les références à mon objet IDispatch ne sont-elles pas publiées?
Pour ajouter l'objet personnalisé, j'appelle InvokeEx avec DISPATCH_PROPERTYPUT et une structure DISPPARAMS avec un pointeur vers mon objet personnalisé.
Pendant l'appel à InvokeEx, la fonction AddRef de mon objet personnalisé est appelée et j'incrémente son compteur de référence. Mais l'objet ne reçoit jamais d'appel à sa fonction Release, de sorte que le compteur de référence ne redescend jamais à zéro.
Qui est responsable de l'appel de Release() après l'appel de AddRef() dans InvokeEx?
EDIT: (Ajout d'un code)
Ceci est le code qui ajoute mon objet personnalisé à la IHTMLWindow2. custObj
des points à mon objet personnalisé
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);
Ceci est l'objet que j'ajoute (certains députés ont été omis par souci de concision)
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:
maintenant qu'il semble fonctionner comme si je devais décider de le mettre sur github.
https://github.com/Tobbe/CppIEEmbed. S'il vous plaît fourchez et améliorez si vous pouvez :)
Indiquez exactement la propriété que vous affectez. Cela devrait être DISPATCH_PROPERTYPUTREF btw puisque vous assignez un objet. –
Si j'utilise DISPATCH_PROPERTYPUTREF InvokeEx échoue avec DISP_E_MEMBERNOTFOUND – Tobbe
@Hans Passant: Je ne suis pas tout à fait sûr de ce que vous demandez lorsque vous dites "Document exactement quelle propriété vous affectez". Est-ce que le code que j'ai ajouté à ma question vous donne ce que vous avez demandé? – Tobbe