ActiveX组件与JavaScript交互

简介: 1.在COM组件中调用JavaScript函数// 连接点方式页面javascript脚本        alert("State(" + s + ")");        return 123;        testCom.

1.在COM组件中调用JavaScript函数
// 连接点方式页面javascript脚本
<object classid="CLSID:B568F111-DFE4-4944-B67F-0728AB2AB30F" id="testCom" VIEWASTEXT></object>
<script language="JavaScript" for="testCom" event="staTe(s)">
        alert("State(" + s + ")");
        return 123;
</script>
<script language="JavaScript">
        testCom.FireStateEvent("Hello");
</script>

// 事件属性方式页面javascript脚本
function onState(s){
        alert("onState(" + s + ")");
        return 456;
}
var o = new ActiveXObject("TestATL.TestCom");
o.onstaTe=onState;
o.FireStateEvent("Hello");

// Com组件VC7.1 ATL代码
__interface _ITestComEvents{
        [id(1), helpstring("State事件")] HRESULT State([in] BSTR str);
};
__event __interface _ITestComEvents;
IDispatchPtr m_onState;        // 事件属性
STDMETHOD(get_onState)(IDispatch** pVal) {
        *pVal = m_onState;
        return S_OK;
};
STDMETHOD(put_onState)(IDispatch* newVal) {
        m_onState = newVal;
        return S_OK;
};
STDMETHOD(FireStateEvent)(BSTR str) {
        __raise State(str);        // 激发连接点事件
        CComVariant result;
        CComVariant avarParams[1] = {str};
        DISPPARAMS dispParams = {avarParams, NULL, 1, 0};
        EXCEPINFO excepInfo;
        memset(&excepInfo, 0, sizeof excepInfo);
        UINT nArgErr = (UINT)-1;      // initialize to invalid arg
        if (m_onState)        // 激发属性事件
            HRESULT hr = m_onState->Invoke(0, IID_NULL, LOCALE_USER_DEFAULT,
                DISPATCH_METHOD, &dispParams, &result, &excepInfo, &nArgErr);
        return S_OK;
}
参见:
How To Call a Script Function from a VC WebBrowser Application
如何在COM object中使用 Javascript function object?
在COM组件中调用JavaScript函数

2.从页面javascript向Com组件传递结构数组
// 页面脚本
var o = new ActiveXObject("TestATL.TestCom");
o.onstaTe=onState;
o.Put("array", {0: 123, 1: "abc"});
o.Put("array", [456, "def"]);
o.Put("array", [{name: "tom", age: 8}, {name: "jack", age: 10}]);
var a = new Array(789, "ghi"); // has "length" property
o.Put("array", a);

// Com组件VC7.1 ATL代码
STDMETHODIMP CTestCom::Put(BSTR key, VARIANT value)
{
WCHAR output[4096] = L"";
if(0 == wcsicmp(key, L"array") && VT_DISPATCH == value.vt)
{
     IDispatchPtr spDisp = value.pdispVal;
     DISPID dispID = 0;
     DISPPARAMS dispParams = {NULL, NULL, 0, 0};
     CComVariant result;
     EXCEPINFO excepInfo;
     memset(&excepInfo, 0, sizeof excepInfo);
     UINT nArgErr = (UINT)-1; // initialize to invalid arg
     unsigned int length = 0; // 数组长度 或 属性 个数

     LPOLESTR func = L"length";
     HRESULT hr = spDisp->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
     if(S_OK == hr){       // 如果有"length"属性
      hr = spDisp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
      if(S_OK == hr && VT_I4 == result.vt)
       length = result.intVal;       // 直接读取数组长度
     }else{
      unsigned int nTypeInfo = 0;
      hr = spDisp->GetTypeInfoCount(&nTypeInfo);
      ATLASSERT(1 == nTypeInfo);
      ITypeInfoPtr spTypeInfo;
      hr = spDisp->GetTypeInfo(0, 0, &spTypeInfo);
      TYPEATTR *pTypeAttr = NULL;
      hr = spTypeInfo->GetTypeAttr(&pTypeAttr);
      //ATLASSERT("{C59C6B12-F6C1-11CF-8835-00A0C911E8B2}" == pTypeAttr->guid);     // JScript:
      length = pTypeAttr->cVars;       // 从类型信息读取数组长度
      spTypeInfo->ReleaseTypeAttr(pTypeAttr);
     }
     for(unsigned int i=0; i<length; i++)
     {
      WCHAR buf[32];
      _itow(i, buf, 10);
      func = buf;
      hr = spDisp->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
      hr = spDisp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
      if(S_OK != hr)
       continue;
      if(VT_DISPATCH == result.vt){
       IDispatchPtr spItem = result.pdispVal;
       func = L"name";
       hr = spItem->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
       hr = spItem->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
       if(S_OK == hr && VT_BSTR == result.vt)
        swprintf(output + wcslen(output), L"name=%s", result.bstrVal);
       func = L"age";
       hr = spItem->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
       hr = spItem->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
       if(S_OK == hr && VT_I4 == result.vt)
        swprintf(output + wcslen(output), L" age=%d/n", result.intVal);
      }else if(VT_BSTR == result.vt)
       swprintf(output + wcslen(output), L"BSTR:%s/n", result.bstrVal);
      else if(VT_I4 == result.vt)
       swprintf(output + wcslen(output), L"I4:%d/n", result.intVal);
      else
       swprintf(output + wcslen(output), L"item.vt=%d/n", result.vt);
     }
}
FireStateEvent(output);
return S_OK;
}

3.枚举IE窗口的内容,并调用其中的脚本
#import <mshtml.tlb>       // Internet Explorer 5
#import <shdocvw.dll>
        SHDocVw::IShellWindowsPtr spSHWinds;
        spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows));
        long nCount = spSHWinds->GetCount();
        IDispatchPtr spDisp;
        for (long i = 0; i < nCount; i++)
        {
         _variant_t va(i, VT_I4);
         spDisp = spSHWinds->Item(va);
         SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);
         if (spBrowser != NULL)
         {
          _bstr_t location = spBrowser->GetLocationName();
          if(_bstr_t(L"Test DapCtrl") == location)       // 找指定IE窗口
          {
           IHTMLDocument2Ptr spDoc(spBrowser->GetDocument());
           if (spDoc != NULL)
           {
            _bstr_t exp = m_onState;
            IDispatch *pdis = NULL;
            hr = spDoc->get_Script(&pdis);
            if(pdis){
             DISPID tmpDispID = 0;
             LPOLESTR func = L"Test"; // javascript 函数名
             hr = pdis->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &tmpDispID);
             if(S_OK == hr)
              hr = pdis->Invoke(tmpDispID, IID_NULL, LOCALE_USER_DEFAULT,
               DISPATCH_METHOD, &dispParams, &result, &excepInfo, &nArgErr);
            }
           }
          }
         }
        }
参见:
HOWTO: Connect to a Running Instance of Internet Explorer
ActiveX组件与JavaScript交互
ActiveX组件控制其所在的IE窗口

4.在VC中执行脚本
#import <msscript.ocx>       // msscript.ocx
using namespace MSScriptControl;
        IScriptControlPtr pScriptControl(__uuidof(ScriptControl));
        LPSAFEARRAY psa;
        SAFEARRAYBOUND rgsabound[]       = { 1, 0 }; // 1 elements, 0-based
        int i;
        psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
        if (!psa)
        {
         return E_OUTOFMEMORY;
        }
        VARIANT vFlavors[1];
        for (i = 0; i < 1; i++)
        {
         VariantInit(&vFlavors[i]);
         V_VT(&vFlavors[i]) = VT_BSTR;
        }
        V_BSTR(&vFlavors[0]) = SysAllocString(bstr);
        long lZero = 0;
        hr = SafeArrayPutElement(psa, &lZero,&vFlavors[0]);
        for(i=0;i<1;i++)
        {
         SysFreeString(vFlavors[i].bstrVal);
        }
        pScriptControl->Language = "JScript";
        pScriptControl->AllowUI = TRUE;
        _bstr_t exp = L"1+2+3";
        _variant_t outpar = pScriptControl->Eval(exp);
        //_variant_t outpar = pScriptControl->ExecuteStatement(exp);
        //_variant_t outpar = pScriptControl->Run("MyStringFunction", &psa);
        _bstr_t bstrReturn = (_bstr_t)outpar;
        char *pResult = (char *)bstrReturn;
        SafeArrayDestroy(psa);
参见:

How To Call Run() Method of the Microsoft Script Control in C++

来自CSDN网站ssli博客

目录
相关文章
|
4月前
|
JavaScript 前端开发 开发者
哇塞!Vue.js 与 Web Components 携手,掀起前端组件复用风暴,震撼你的开发世界!
【8月更文挑战第30天】这段内容介绍了Vue.js和Web Components在前端开发中的优势及二者结合的可能性。Vue.js提供高效简洁的组件化开发,单个组件包含模板、脚本和样式,方便构建复杂用户界面。Web Components作为新兴技术标准,利用自定义元素、Shadow DOM等技术创建封装性强的自定义HTML元素,实现跨框架复用。结合二者,不仅增强了Web Components的逻辑和交互功能,还实现了Vue.js组件在不同框架中的复用,提高了开发效率和可维护性。未来前端开发中,这种结合将大有可为。
172 0
|
1月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
45 5
|
1月前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
38 4
|
1月前
|
设计模式 前端开发 JavaScript
揭秘!前端大牛们如何巧妙利用JavaScript,打造智能交互体验!
【10月更文挑战第30天】前端开发领域充满了无限可能与创意,JavaScript作为核心语言,凭借强大的功能和灵活性,成为打造智能交互体验的重要工具。本文介绍前端大牛如何利用JavaScript实现平滑滚动、复杂动画、实时数据更新和智能表单验证等效果,展示了JavaScript的多样性和强大能力。
54 4
|
2月前
|
存储 JavaScript 前端开发
【JavaScript】网页交互的灵魂舞者
本文介绍了 JavaScript 的三种引入方式(行内、内部、外部)和基础语法,包括变量、数据类型、运算符、数组、函数和对象等内容。同时,文章还详细讲解了 jQuery 的基本语法和常用方法,如 `text()`、`html()`、`val()`、`attr()` 和 `css()` 等,以及如何插入和删除元素。通过示例代码和图解,帮助读者更好地理解和应用这些知识。
35 1
【JavaScript】网页交互的灵魂舞者
|
2月前
|
JavaScript 前端开发 API
探索Vue.js 3的组合式API:一种更灵活的组件状态管理方式
【10月更文挑战第5天】探索Vue.js 3的组合式API:一种更灵活的组件状态管理方式
|
3月前
|
Web App开发 JavaScript 前端开发
用 JavaScript 创建 XPCOM 组件
用 JavaScript 创建 XPCOM 组件
|
3月前
|
JavaScript 前端开发
JavaScript 与 DOM 交互
【9月更文挑战第01天】
39 2
|
4月前
|
JavaScript 前端开发 UED
Vue.js动画魔法:解锁流畅过渡,让每一次交互都成为用户心中的小确幸!
【8月更文挑战第30天】在Vue.js中,动画与过渡效果不仅是视觉点缀,更是提升用户体验的关键。通过流畅的动态效果,应用的互动性和吸引力得以增强,从而提高用户满意度和参与度。`&lt;transition&gt;`和`&lt;transition-group&gt;`组件结合CSS过渡,可轻松实现元素的进入、离开及列表变化动画。合理的性能优化,如使用硬件加速,能避免页面卡顿,确保动画既美观又高效。下面是一个简单的淡入淡出效果示例,展示了如何利用Vue.js实现平滑的动画过渡。总之,恰当的动画设计能显著提升应用的用户体验。
64 0
Vue.js动画魔法:解锁流畅过渡,让每一次交互都成为用户心中的小确幸!
|
4月前
|
Android开发 iOS开发 C#
Xamarin:用C#打造跨平台移动应用的终极利器——从零开始构建你的第一个iOS与Android通用App,体验前所未有的高效与便捷开发之旅
【8月更文挑战第31天】Xamarin 是一个强大的框架,允许开发者使用单一的 C# 代码库构建高性能的原生移动应用,支持 iOS、Android 和 Windows 平台。作为微软的一部分,Xamarin 充分利用了 .NET 框架的强大功能,提供了丰富的 API 和工具集,简化了跨平台移动应用开发。本文通过一个简单的示例应用介绍了如何使用 Xamarin.Forms 快速创建跨平台应用,包括设置开发环境、定义用户界面和实现按钮点击事件处理逻辑。这个示例展示了 Xamarin.Forms 的基本功能,帮助开发者提高开发效率并实现一致的用户体验。
178 0