在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