• 在COM组件中调用JavaScript函数 .


    在COM组件中调用JavaScript函数

    要求是很简单的,即有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,
                    &params, &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, 
                             &params, &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对象广泛使用这个方法。

  • 相关阅读:
    泛型的内部原理:类型擦除以及类型擦除带来的问题
    Redis的那些最常见面试问题
    线程池全面解析
    对线程调度中Thread.sleep(0)的深入理解
    集群环境下Redis分布式锁
    3.8
    3.7
    3.6任务
    3.5任务
    3.4
  • 原文地址:https://www.cnblogs.com/lidabo/p/3483107.html
Copyright © 2020-2023  润新知