首页 > 代码库 > 在COM组件中调用JS函数

在COM组件中调用JS函数

要求是很简单的,即有COM组件A在IE中运行,使用JavaScript(JS)调用A的方法longCalc(),该方法是一个耗时的操作,要求通知IE当前的进度。这就要求使用回调函数,设其名称为scriptCallbackFunc。实现这个技术很简单:

1 、组件方(C++)

组件A 的方法在IDL中定义:

[id(2)] HRESULT longCalc([in] DOUBLE v1, [in] DOUBLE v2, [in, optional] VARIANT scriptCallback);

组件A的方法实现:

// 假设回调原型为: // scriptCallbackFunc(LONG nCurrentProgress, LONG nTotalProgress, BSTR bstrProgressName);// 此方法由JS脚本来实现STDMETHODIMP CA:: longCalc (DOUBLE v1, DOUBLE v2, VARIANT scriptCallback){    CComPtr<IDispatch> spCallback;    if (scriptCallback.vt == VT_DISPATCH)         spCallback = scriptCallback.pdispVal;        // 参数准备    CComVariant varResult;    CComVariant avarParams[3];    avarParams[0] = “开始计算股票”;        // bstrProgressName    avarParams[0].vt = VT_BSTR;    avarParams[1] = 100;                              // nTotalProgress    avarParams[1].vt = VT_I4;    avarParams[2] = 0;                                 // nCurrentProgress    avarParams[2].vt = VT_I4;    DISPPARAMS params = { avarParams, NULL, 3, 0 };    if(spCallback)          spCallback->Invoke(0,                 IID_NULL,                 LOCALE_USER_DEFAULT,                 DISPATCH_METHOD,                 ¶ms, &varResult, NULL, NULL);    BOOL  bFinished = false;        while(!bFinished)    {         // 计算工作…         Sleep(1000);         v1 = v1+v2;          // 回调客户        if(spCallback)        {            avarParams[0] = “正在计算股票…”;            avarParams[2] = 0;            spCallback->Invoke(0,                          IID_NULL,                          LOCALE_USER_DEFAULT,                          DISPATCH_METHOD,                          ¶ms, &varResult, NULL, NULL);          }          if(…)                 bFinished = TRUE;     }  // while OK!      return S_OK;}

2、 客户方(JS)

<script language="javascript"><!--      // 符合回调原型:scriptCallbackFunc      function scfDisplayProgress(nCurrentProgress, nTotalProgress, bstrProgressName)      {             window.status = bstrProgressName + “:”+(nCurrentProgress *100/TotalProgress);      }       // 创建组件并执行longCalc      var objA = new ActiveXObject(“MyCom.A”);       // 使用回调: 执行时在IE状态栏显示进度       objA. longCalc (100, 200, scfDisplayProgress);        // 不使用回调       objA. longCalc (100, 200); //--></script>

3 说明

该技术仅适用于脚本。不适合于VB、C++客户。
该技术和连接点、事件无关。
微软的XML DOM对象广泛使用这个方法。