当前位置:首页 > 行业动态 > 正文

activex回调js

ActiveX 回调 JS 是指在网页中使用 ActiveX 控件时,通过 JavaScript 调用该控件的方法或属性。

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, &params, 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 控件的实例后,使用attachEventaddEventListener 等方法将 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 控件的注册等问题,以确保功能的正常运行。

0