[WTL]调用JS有两种办法,一种是依赖于IWebBrowser接口的,就是可以操纵Web的。
我们先说另外一种,把JScript(VBS)当纯脚本调用的。
部分参考了这个BLOG:
http://www.cppblog.com/free2000fly/archive/2009/05/23/85549.html
保存下面的内容为 a.wsc:
<?xml version="1.0" encoding="UTF-8"?>
<?component error="true" debug="true"?>
<component id="XrhTest.LowerToUpper">
<registration
description = "UpperCase and lowCase convertion"
progid="XrhTest.LowerToUpper"
version="1.0"
classid="{9B88510F-9D5B-4dcd-9068-8AB0B4F7999C}" remotable="true">
</registration>
<public>
<!-- define method -->
<method name="toLower">
<parameter name="str"/>
</method>
<method name="toUpper">
<parameter name="str"/>
</method>
</public>
<script language="JavaScript">
<![CDATA[
function toLower(str)
{
var result=str.toLowerCase();
return result;
}
function toUpper(str)
{
var result=str.toUpperCase();
return result;
}
]]>
</script>
<?component error="true" debug="true"?>
<component id="XrhTest.LowerToUpper">
<registration
description = "UpperCase and lowCase convertion"
progid="XrhTest.LowerToUpper"
version="1.0"
classid="{9B88510F-9D5B-4dcd-9068-8AB0B4F7999C}" remotable="true">
</registration>
<public>
<!-- define method -->
<method name="toLower">
<parameter name="str"/>
</method>
<method name="toUpper">
<parameter name="str"/>
</method>
</public>
<script language="JavaScript">
<![CDATA[
function toLower(str)
{
var result=str.toLowerCase();
return result;
}
function toUpper(str)
{
var result=str.toUpperCase();
return result;
}
]]>
</script>
</component>
然后注册它[regsvr32 a.wsc, Win7需要管理员权限]。
注册完成后, 在注册表内有以下条目
[HKEY_CLASSES_ROOT\CLSID\{9B88510F-9D5B-4DCD-9068-8AB0B4F7999C}]
@="UpperCase and lowCase convertion"
"AppID"="{9B88510F-9D5B-4DCD-9068-8AB0B4F7999C}"
[HKEY_CLASSES_ROOT\CLSID\{9B88510F-9D5B-4DCD-9068-8AB0B4F7999C}\InprocServer32]
@="C:\\WINDOWS\\System32\\scrobj.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{9B88510F-9D5B-4DCD-9068-8AB0B4F7999C}\ProgID]
@="XrhTest.LowerToUpper.1.0"
[HKEY_CLASSES_ROOT\CLSID\{9B88510F-9D5B-4DCD-9068-8AB0B4F7999C}\ScriptletURL]
@="file:///D:/lower2upper.wsc "
[HKEY_CLASSES_ROOT\CLSID\{9B88510F-9D5B-4DCD-9068-8AB0B4F7999C}\VersionIndependentProgID]
@="XrhTest.LowerToUpper"
从以上注册表项目可以看出, 当我们要创建 wsc 组件时, COM 运行时将会加载 scrobj.dll 链接库, scrobj.dll 链接库将根据 scriptletURL 的键值 file:///D:/lower2upper.wsc 加载 wsc 脚本, 最后由 scrobj.dll 将脚本解释成一个 COM 组件实例, 将这个实例指针返回给调用者.@="UpperCase and lowCase convertion"
"AppID"="{9B88510F-9D5B-4DCD-9068-8AB0B4F7999C}"
[HKEY_CLASSES_ROOT\CLSID\{9B88510F-9D5B-4DCD-9068-8AB0B4F7999C}\InprocServer32]
@="C:\\WINDOWS\\System32\\scrobj.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{9B88510F-9D5B-4DCD-9068-8AB0B4F7999C}\ProgID]
@="XrhTest.LowerToUpper.1.0"
[HKEY_CLASSES_ROOT\CLSID\{9B88510F-9D5B-4DCD-9068-8AB0B4F7999C}\ScriptletURL]
@="file:///D:/lower2upper.wsc "
[HKEY_CLASSES_ROOT\CLSID\{9B88510F-9D5B-4DCD-9068-8AB0B4F7999C}\VersionIndependentProgID]
@="XrhTest.LowerToUpper"
然后就可以上代码了:
CComPtr<IBindCtx> pbc;
CComPtr<IMoniker> pMoniker;
CComPtr<IDispatch> pScript;
if (FAILED(CreateBindCtx(0, &pbc)))
break;
ULONG lEaten;
if (FAILED(MkParseDisplayName(pbc, CComBSTR(L"script:d:\\a.wsc"), &lEaten, &pMoniker)))
break;
HRESULT hr = S_OK;
if (FAILED(hr = BindMoniker(pMoniker, 0, __uuidof(IDispatch), (void**)&pScript)))
break;
if (FAILED(pScript.Invoke0(L"functionName")))
break;
CComPtr<IMoniker> pMoniker;
CComPtr<IDispatch> pScript;
if (FAILED(CreateBindCtx(0, &pbc)))
break;
ULONG lEaten;
if (FAILED(MkParseDisplayName(pbc, CComBSTR(L"script:d:\\a.wsc"), &lEaten, &pMoniker)))
break;
HRESULT hr = S_OK;
if (FAILED(hr = BindMoniker(pMoniker, 0, __uuidof(IDispatch), (void**)&pScript)))
break;
if (FAILED(pScript.Invoke0(L"functionName")))
break;
... ...
这种做法更简单。
CComQIPtr<IDispatch> spTmp;
hr = spTmp.CoCreateInstance(L"XrhTest.LowerToUpper");
if (SUCCEEDED(hr))
{
CComDispatchDriver spDisp(spTmp);
CComVariant varParam(L"The quick brown fox jumps over the lazy dog");
CComVariant varResult;
hr = spDisp.Invoke1(L"toUpper", &varParam, &varResult);
if (SUCCEEDED(hr))
{
MessageBoxW(NULL, (LPCWSTR) varResult.bstrVal, L"MB_OK", MB_OK);
}
}
hr = spTmp.CoCreateInstance(L"XrhTest.LowerToUpper");
if (SUCCEEDED(hr))
{
CComDispatchDriver spDisp(spTmp);
CComVariant varParam(L"The quick brown fox jumps over the lazy dog");
CComVariant varResult;
hr = spDisp.Invoke1(L"toUpper", &varParam, &varResult);
if (SUCCEEDED(hr))
{
MessageBoxW(NULL, (LPCWSTR) varResult.bstrVal, L"MB_OK", MB_OK);
}
}