activex回调js
- 行业动态
- 2025-02-16
- 4
ActiveX 回调 JS 的实现方法有多种,以下为你详细介绍:
1、通过直接调用 JavaScript 函数的方式
原理:在 ActiveX 控件中创建一个方法,该方法接收一个 JavaScript 函数作为参数,然后调用该 JavaScript 函数。
具体步骤:
在 ActiveX 控件的开发环境中(如 C++ 等),为控件添加一个新方法,例如CallWebJs
,这个方法接收一个VARIANT
类型的参数,用于传递 JavaScript 函数。
在CallWebJs
方法的实现中,将传入的VARIANT
参数转换为IDispatch
接口指针,以便能够调用 JavaScript 函数。
使用IDispatch
接口的Invoke
方法来调用 JavaScript 函数,需要指定函数的标识符(一般为 0)、参数等信息。
在 HTML 页面中,创建 ActiveX 控件的实例,并通过 JavaScript 代码将需要回调的函数传递给 ActiveX 控件的CallWebJs
方法。
示例代码
ActiveX 控件端(C++):
STDMETHODIMP Ccalc::CallWebJs(VARIANT scriptCallback) { CComPtr<IDispatch> spCallback; if (scriptCallback.vt == VT_DISPATCH) spCallback = scriptCallback.pdispVal; CComVariant avarParams[1]; avarParams[0] = "hhheeee"; // 指定回调函数的参数 DISPPARAMS params = { avarParams, NULL, 1, 0 }; if (spCallback) spCallback->Invoke(0, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL); return S_OK; }
HTML 页面端:
<OBJECT id="calc" classid="CLSID:4A524B99-8CAF-44E9-B788-70536908F048"></OBJECT> <input type="button" value="Add" onclick="add();"/> <input type="button" value="CallWebJs" onclick="test()"/> <script type="text/javascript"> function add() { var calc = document.getElementById('calc'); var result = calc.Add(2, 3); alert(result); } function test() { var calc = document.getElementById('Calc'); var result = calc.CallWebJs(printMsg); } function printMsg(msg) { alert(msg); } </script>
2、通过事件触发的方式
原理:在 ActiveX 控件中定义事件,当特定的操作或条件满足时触发事件,然后在 JavaScript 中绑定事件处理函数,从而实现回调。
具体步骤:
在 ActiveX 控件的开发环境中,定义一个新的事件,这通常需要在控件的类工厂中添加事件的定义,并生成相应的事件接口和连接点。
在控件的方法中,当需要触发事件时,调用相关的函数来引发事件,在一个计算完成后触发事件。
在 HTML 页面中,获取 ActiveX 控件的实例后,使用attachEvent
或addEventListener
等方法将 JavaScript 函数绑定到控件的事件上。
示例代码
ActiveX 控件端(以 ATL 为例):
// 在 .h 文件中定义事件接口和连接点 class ICalcEvents : public IUnknown { public: virtual HRESULT AddCompleted([in] DOUBLE * bstrCmdInfo) = 0; }; class CCalc : public CComObjectRootEx<CComSingleThreadModel>, public ICalc, public IConnectionPointContainerImpl<CCalc> { public: DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CALC, InitControl) DECLARE_PROTECTED_CONNECTION_POINT_MAP() BEGIN_COM_MAP(CCalc) COM_INTERFACE_ENTRY(ICalc) COM_INTERFACE_ENTRY(IConnectionPointContainer) END_COM_MAP() ... }; // 在 .cpp 文件中实现事件引发 STDMETHODIMP CCalc::Add(DOUBLE a, DOUBLE b, DOUBLE * result) { *result = a + b; Fire_AddCompleted(*result); return S_OK; }
HTML 页面端:
<OBJECT id="Calc" classid="clsid:YourActiveXControl"></OBJECT> <script type="text/javascript"> var calc = document.getElementById('Calc'); calc.attachEvent("AddCompleted", OnAddCompleted); function OnAddCompleted(result) { alert(result); } </script>
3、通过线程同步和消息机制的方式
原理:在 ActiveX 控件中使用线程进行一些耗时的操作,当操作完成后,通过发送自定义消息通知主线程,主线程再调用 JavaScript 函数。
具体步骤:
在 ActiveX 控件中开启一个新线程进行运算或其他耗时操作,可以使用_beginthread
等函数创建线程。
在线程函数中完成操作后,使用PostMessage
函数向主线程发送自定义消息,例如WM_THREADFIREEVENT
。
在主线程的消息映射函数中,处理自定义消息,调用 JavaScript 函数,需要先获取浏览器的IWebBrowser2
接口,然后通过该接口获取文档对象和脚本对象,最后调用脚本对象的Invoke
方法执行 JavaScript 函数。
示例代码
ActiveX 控件端(MFC):
#define WM_THREADFIREEVENT WM_USER+101 void f(void * r) { CThirdCtrl* p = (CThirdCtrl*)r; Sleep(5000); p->m_param +=10; PostMessage(p->m_hWnd, WM_THREADFIREEVENT, (WPARAM)NULL, (LPARAM)NULL); return; } void CThirdCtrl::invoke(short param) { m_param = param; _beginthread(f, 0, (void*)(this)); } LRESULT CThirdCtrl::OnFireEventForThread(WPARAM wParam, LPARAM lParam) { InvokeScript(); return TRUE; }
HTML 页面端:与上述示例类似,需要在 HTML 页面中创建 ActiveX 控件实例并绑定相关事件或操作。
ActiveX 回调 JS 的这些方式各有优缺点,开发者可根据具体需求和应用场景选择合适的方法来实现 ActiveX 与 JavaScript 之间的交互,在实际开发中,还需要注意浏览器的安全设置、ActiveX 控件的注册等问题,以确保功能的正常运行。