引用: http://www.cnblogs.com/kwliu/archive/2011/09/29/2195894.html
一直做IE相关的东西,但是发现对JS和VC之间如何调用不是很明白。虽然知道通过IDispatch接口可以在VC程序和JS之间进行交互,但是如何具体做一直有点模糊,所以就专门做了个实验,看看他们到底如何进行沟通。
脚本语言和编译型语言之间进行通信是通过IDispatch接口来行的,这里我对双接口的理论就不进行讨论,直接看看如何用WTL代码来实现。
首先定义如下的一个IDispatch实现:
class CExternalDisp: public CComObjectRoot, public IDispatch { public: CExternalDisp(void); ~CExternalDisp(void); BEGIN_COM_MAP(CExternalDisp) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() HRESULT STDMETHODCALLTYPE GetTypeInfoCount( /* [out] */ UINT *pctinfo) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE GetTypeInfo( /* [in] */ UINT iTInfo, /* [in] */ LCID lcid, /* [out] */ ITypeInfo **ppTInfo) { return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames( /* [in] */ REFIID riid, /* [size_is][in] */ LPOLESTR *rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID *rgDispId) { CComBSTR bsName(*rgszNames); if (bsName == L"abc") { *rgDispId = 2535; return S_OK; } return E_NOTIMPL; } virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( /* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS *pDispParams, /* [out] */ VARIANT *pVarResult, /* [out] */ EXCEPINFO *pExcepInfo, /* [out] */ UINT *puArgErr) { if (dispIdMember == 2535) { for (int i = 0; i < pDispParams->cArgs; ++i) { if( pDispParams->rgvarg[i].vt == VT_INT) i = i; else i = i; } MessageBox(NULL, L"sdjlkf", L"sdl", MB_OK); return S_OK; } return E_NOTIMPL; } };
以上代码中定义了一个CExternalDisp的组件,实现了IDispatch接口,当js脚本语言调用对象的某个方法时,会转成通过IDispatch的Invoke函数来调用,不同的函数对应不同的dispIdMember,而这个数字又是通过GetIDsOfNames来得到的。
有了CExternalDisp这个组件,还需要将其注册成为IE的exteranl对象。在IE控件的初始化部分进行设置,代码如下:
CComPtr<IWebBrowser2> spWeb; HRESULT hr = m_view.QueryControl(IID_IWebBrowser2, (void**)&spWeb ); CComObject<CExternalDisp> *obj; CComObject<CExternalDisp>::CreateInstance(&obj); CComPtr<IDispatch> spDisp; obj->QueryInterface(IID_IDispatch, (void**)&spDisp); m_view.SetExternalDispatch(spDisp);
<HTML> <HEAD> <META NAME="GENERATOR" Content="Microsoft Visual Studio 8.0"> <TITLE></TITLE> <script type="text/javascript"> window.external.abc(1, 'ljw', 2.3); </script> </HEAD> <BODY> </BODY> </HTML>