プレーンな Win32 (mfc、atl、wtl などなし) のみを使用して、C++ プログラムで IWebBrowser2 コントロールをホストしています。DISPID_NAVIGATECOMPLETE2 で、表示された Web ページで実行されている JavaScript からアクセスされるカスタム オブジェクトを追加します。
カスタム オブジェクトを追加するには、DISPATCH_PROPERTYPUT と、カスタム オブジェクトへのポインターを指定した DISPPARAMS 構造体を指定して InvokeEx を呼び出します。
InvokeEx の呼び出し中に、カスタム オブジェクトの AddRef 関数が呼び出され、その参照カウンターをインクリメントします。ただし、オブジェクトがその Release 関数を呼び出すことはないため、参照カウンターが再びゼロになることはありません。
InvokeEx で AddRef() が呼び出された後、Release() を呼び出すのは誰の責任ですか?
編集:(いくつかのコードを追加)
これは、カスタム オブジェクトを 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 . 可能であればフォークして改善してください:)