[转]在COM组件中调用JavaScript函数
要求是很简单的,即有COM组件A在IE中运行,使用JavaScript(JS)调用A的方法longCalc(),该方法是一个耗时的操作,要求通知IE当前的进度。这就要求使用回调函数,设其名称为scriptCallbackFunc。实现这个技术很简单:
在COM组件中调用JavaScript函数
要求是很简单的,即有COM组件A在IE中运行,使用JavaScript(JS)调用A的方法longCalc(),该方法是一个耗时的操作,要求通知IE当前的进度。这就要求使用回调函数,设其名称为scriptCallbackFunc。实现这个技术很简单:
Code
1 1 组件方(C++)
2
3 组件A 的方法在IDL中定义:
4 [id(2)] HRESULT longCalc([in] DOUBLE v1, [in] DOUBLE v2, [in, optional] VARIANT scriptCallback);
5
6 组件A的方法实现:
7 // 假设回调原型为:
8 // scriptCallbackFunc(LONG nCurrentProgress, LONG nTotalProgress, BSTR bstrProgressName);
9 // 此方法由JS脚本来实现
10 STDMETHODIMP CA:: longCalc (DOUBLE v1, DOUBLE v2, VARIANT scriptCallback)
11 {
12 CComPtr<IDispatch> spCallback;
13 if (scriptCallback.vt == VT_DISPATCH)
14 spCallback = scriptCallback.pdispVal;
15
16
17 // 参数准备
18 CComVariant varResult;
19 CComVariant avarParams[3];
20 avarParams[0] = “开始计算股票”; // bstrProgressName
21 avarParams[0].vt = VT_BSTR;
22 avarParams[1] = 100; // nTotalProgress
23 avarParams[1].vt = VT_I4;
24 avarParams[2] = 0; // nCurrentProgress
25 avarParams[2].vt = VT_I4;
26 DISPPARAMS params = { avarParams, NULL, 3, 0 };
27
28
29 if(spCallback)
30 spCallback->Invoke(0,
31 IID_NULL,
32 LOCALE_USER_DEFAULT,
33 DISPATCH_METHOD,
34 ¶ms, &varResult, NULL, NULL);
35
36 BOOL bFinished = false;
37
38
39 while(!bFinished)
40 {
41 // 计算工作…
42 Sleep(1000);
43 v1 = v1+v2;
44
45 // 回调客户
46 if(spCallback)
47 {
48 avarParams[0] = “正在计算股票…”;
49 avarParams[2] = 0;
50 spCallback->Invoke(0,
51 IID_NULL,
52 LOCALE_USER_DEFAULT,
53 DISPATCH_METHOD,
54 ¶ms, &varResult, NULL, NULL);
55 }
56
57 if(…)
58 bFinished = TRUE;
59 } // while OK!
60
61 return S_OK;
62 }
63
64
65 2 客户方(JS)
66
67 <script language="javascript">
68 <!--
69 // 符合回调原型:scriptCallbackFunc
70 function scfDisplayProgress(nCurrentProgress, nTotalProgress, bstrProgressName)
71 {
72 window.status = bstrProgressName + “:”+(nCurrentProgress *100/TotalProgress);
73 }
74
75 // 创建组件并执行longCalc
76 var objA = new ActiveXObject(“MyCom.A”);
77
78 // 使用回调: 执行时在IE状态栏显示进度
79 objA. longCalc (100, 200, scfDisplayProgress);
80
81 // 不使用回调
82 objA. longCalc (100, 200);
83 //-->
84 </script>
85
86 3 说明
87
88 该技术仅适用于脚本。不适合于VB、C++客户。
89 该技术和连接点、事件无关。
90 微软的XML DOM对象广泛使用这个方法。
91
1 1 组件方(C++)
2
3 组件A 的方法在IDL中定义:
4 [id(2)] HRESULT longCalc([in] DOUBLE v1, [in] DOUBLE v2, [in, optional] VARIANT scriptCallback);
5
6 组件A的方法实现:
7 // 假设回调原型为:
8 // scriptCallbackFunc(LONG nCurrentProgress, LONG nTotalProgress, BSTR bstrProgressName);
9 // 此方法由JS脚本来实现
10 STDMETHODIMP CA:: longCalc (DOUBLE v1, DOUBLE v2, VARIANT scriptCallback)
11 {
12 CComPtr<IDispatch> spCallback;
13 if (scriptCallback.vt == VT_DISPATCH)
14 spCallback = scriptCallback.pdispVal;
15
16
17 // 参数准备
18 CComVariant varResult;
19 CComVariant avarParams[3];
20 avarParams[0] = “开始计算股票”; // bstrProgressName
21 avarParams[0].vt = VT_BSTR;
22 avarParams[1] = 100; // nTotalProgress
23 avarParams[1].vt = VT_I4;
24 avarParams[2] = 0; // nCurrentProgress
25 avarParams[2].vt = VT_I4;
26 DISPPARAMS params = { avarParams, NULL, 3, 0 };
27
28
29 if(spCallback)
30 spCallback->Invoke(0,
31 IID_NULL,
32 LOCALE_USER_DEFAULT,
33 DISPATCH_METHOD,
34 ¶ms, &varResult, NULL, NULL);
35
36 BOOL bFinished = false;
37
38
39 while(!bFinished)
40 {
41 // 计算工作…
42 Sleep(1000);
43 v1 = v1+v2;
44
45 // 回调客户
46 if(spCallback)
47 {
48 avarParams[0] = “正在计算股票…”;
49 avarParams[2] = 0;
50 spCallback->Invoke(0,
51 IID_NULL,
52 LOCALE_USER_DEFAULT,
53 DISPATCH_METHOD,
54 ¶ms, &varResult, NULL, NULL);
55 }
56
57 if(…)
58 bFinished = TRUE;
59 } // while OK!
60
61 return S_OK;
62 }
63
64
65 2 客户方(JS)
66
67 <script language="javascript">
68 <!--
69 // 符合回调原型:scriptCallbackFunc
70 function scfDisplayProgress(nCurrentProgress, nTotalProgress, bstrProgressName)
71 {
72 window.status = bstrProgressName + “:”+(nCurrentProgress *100/TotalProgress);
73 }
74
75 // 创建组件并执行longCalc
76 var objA = new ActiveXObject(“MyCom.A”);
77
78 // 使用回调: 执行时在IE状态栏显示进度
79 objA. longCalc (100, 200, scfDisplayProgress);
80
81 // 不使用回调
82 objA. longCalc (100, 200);
83 //-->
84 </script>
85
86 3 说明
87
88 该技术仅适用于脚本。不适合于VB、C++客户。
89 该技术和连接点、事件无关。
90 微软的XML DOM对象广泛使用这个方法。
91